diff --git a/control_tools.cpp b/control_tools.cpp index 4113afd..1a2290a 100644 --- a/control_tools.cpp +++ b/control_tools.cpp @@ -43,6 +43,7 @@ #include "pclsync/pshm.h" #include "pclsync/pfoldersync.h" #include "pclsync/rpcclient.h" +#include "pclsync/pcommands.h" #include "CLI11.hpp" @@ -52,15 +53,6 @@ namespace control_tools { static const int STOP = 0; -enum command_ids_ { - STARTCRYPTO = 20, - STOPCRYPTO, - FINALIZE, - LISTSYNC, - ADDSYNC, - STOPSYNC -}; - int list_sync_folders() { int ret; char *errm; diff --git a/pclsync/pcommands.h b/pclsync/pcommands.h new file mode 100644 index 0000000..9fca4c1 --- /dev/null +++ b/pclsync/pcommands.h @@ -0,0 +1,8 @@ +enum command_ids_ { + STARTCRYPTO = 20, + STOPCRYPTO, + FINALIZE, + LISTSYNC, + ADDSYNC, + STOPSYNC +}; diff --git a/pclsync/pcryptofolder.c b/pclsync/pcryptofolder.c index efaaeda..ec8b3db 100644 --- a/pclsync/pcryptofolder.c +++ b/pclsync/pcryptofolder.c @@ -548,7 +548,6 @@ int pcryptofolder_unlock(const char *password) { * to have some thread to hold sql_lock and wait for read lock. This will * normally deadlock with us holding writelock and waiting for sql_lock. * Therefore we use sql_trylock here. - * */ retry: pthread_rwlock_wrlock(&crypto_lock); @@ -604,6 +603,8 @@ retry: debug(D_NOTICE, "got keys from the database"); assert(rowcnt == 4); } + + debug(D_NOTICE, "trying to load public key"); crypto_pubkey = psync_ssl_rsa_load_public(rsapub, rsapublen); if (crypto_pubkey == PSYNC_INVALID_RSA) { pthread_rwlock_unlock(&crypto_lock); @@ -613,6 +614,10 @@ retry: psync_free(salt); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT); } + debug(D_NOTICE, "successfully loaded public key"); + + + debug(D_NOTICE, "generating symmetric key"); aeskey = psync_ssl_gen_symmetric_key_from_pass( password, PSYNC_AES256_KEY_SIZE + PSYNC_AES256_BLOCK_SIZE, salt, saltlen, iterations); @@ -622,19 +627,26 @@ retry: memcpy(rsaprivdec, rsapriv, rsaprivlen); pcrypto_ctr_encdec_decode(enc, rsaprivdec, rsaprivlen, 0); pcrypto_ctr_encdec_free(enc); + debug(D_NOTICE, "successfully generated symmetric key"); + + + debug(D_NOTICE, "trying to load private key"); crypto_privkey = psync_ssl_rsa_load_private(rsaprivdec, rsaprivlen); psync_ssl_memclean(rsaprivdec, rsaprivlen); pmemlock_free(rsaprivdec); if (crypto_privkey == PSYNC_INVALID_RSA) { + debug(D_NOTICE, "failed to load private key"); psync_ssl_rsa_free_public(crypto_pubkey); crypto_pubkey = PSYNC_INVALID_RSA; pthread_rwlock_unlock(&crypto_lock); - debug(D_NOTICE, "bad password"); psync_free(rsapriv); psync_free(rsapub); psync_free(salt); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_BAD_PASSWORD); } + debug(D_NOTICE, "successfully loaded private key"); + + debug(D_NOTICE, "verify matching public and private key"); if (!crypto_keys_match()) { psync_ssl_rsa_free_public(crypto_pubkey); crypto_pubkey = PSYNC_INVALID_RSA; @@ -647,13 +659,17 @@ retry: psync_free(salt); return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_KEYS_DONT_MATCH); } + debug(D_NOTICE, "public and private keys match, setting crypto started"); + crypto_started_l = 1; crypto_started_un = 1; pthread_rwlock_unlock(&crypto_lock); - if (rowcnt < 4) + if (rowcnt < 4) { + debug(D_NOTICE, "saving crypto setup to database"); psync_cloud_crypto_setup_save_to_db(rsapriv, rsaprivlen, rsapub, rsapublen, salt, saltlen, iterations, 0, publicsha1, privatesha1, flags); + } psync_free(rsapriv); psync_free(rsapub); psync_free(salt); diff --git a/pclsync/pcryptofolder.h b/pclsync/pcryptofolder.h index 80e1c9c..488985d 100644 --- a/pclsync/pcryptofolder.h +++ b/pclsync/pcryptofolder.h @@ -32,10 +32,14 @@ #ifndef __PCRYPTOFOLDER_H #define __PCRYPTOFOLDER_H +#ifdef __cplusplus +extern "C" { +#endif + #include "papi.h" #include "pcrypto.h" +#include "pfoldersync.h" #include "pfsfolder.h" -#include "psynclib.h" #define PSYNC_CRYPTO_SYM_FLAG_ISDIR 1 @@ -74,4 +78,8 @@ int pcryptofolder_reset(); int pcryptofolder_setup(const char *password, const char *hint); int pcryptofolder_unlock(const char *password); +#ifdef __cplusplus +} +#endif + #endif diff --git a/pclsync/pstatus.h b/pclsync/pstatus.h index ddee192..7246dc9 100644 --- a/pclsync/pstatus.h +++ b/pclsync/pstatus.h @@ -31,6 +31,10 @@ #ifndef _PSYNC_STATUS_H #define _PSYNC_STATUS_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include "plist.h" @@ -155,4 +159,8 @@ void pstatus_get_cb(pstatus_t *status); void pstatus_set_cb(pstatus_change_callback_t callback); void pstatus_send_status_update(); +#ifdef __cplusplus +} +#endif + #endif diff --git a/pclsync_lib.cpp b/pclsync_lib.cpp index 25f79c4..6285602 100644 --- a/pclsync_lib.cpp +++ b/pclsync_lib.cpp @@ -37,10 +37,12 @@ #include #include +#include "pcryptofolder.h" #include "prpc.h" #include "psynclib.h" #include "pshm.h" #include "pdevice.h" +#include "pcommands.h" #include "pclsync_lib.h" @@ -199,28 +201,35 @@ void event_handler(psync_eventtype_t event, psync_eventdata_t eventdata) { } static int lib_setup_cripto() { - int ret = 0; - ret = psync_crypto_issetup(); - if (ret) { - ret = psync_crypto_start( - clib::pclsync_lib::get_lib().get_crypto_pass().c_str()); - std::cout << "crypto is setup, login result=" << ret << std::endl; - } else { - std::cout << "crypto is not setup" << std::endl; - ret = psync_crypto_setup( - clib::pclsync_lib::get_lib().get_crypto_pass().c_str(), "no hint"); - if (ret) { - std::cout << "crypto setup failed" << std::endl; - } else { - ret = psync_crypto_start( - clib::pclsync_lib::get_lib().get_crypto_pass().c_str()); - std::cout << "crypto setup successful, start=" << ret << std::endl; - ret = psync_crypto_mkdir(0, "Crypto", NULL, NULL); - std::cout << "creating folder=" << ret << std::endl; - } + const char *pwd = clib::pclsync_lib::get_lib().get_crypto_pass().c_str(); + + if(pstatus_get(PSTATUS_TYPE_ONLINE) == PSTATUS_ONLINE_OFFLINE) { + std::cout << "Cannot unlock crypto folder, pcloudcc is offline" << std::endl; + return PSYNC_CRYPTO_CANT_CONNECT; } + + if(!psync_crypto_issetup()) { + std::cout << "crypto is not setup, setting it up now..." << std::endl; + if(int ret = pcryptofolder_setup(pwd, "no hint") != PSYNC_CRYPTO_SETUP_SUCCESS) { + std::cout << "crypto setup failed, error code was " << ret << std::endl; + return ret; + } + if(int ret = pcryptofolder_mkdir(0, "Crypto", NULL, NULL) != PSYNC_CRYPTO_SUCCESS) { + std::cout << "failed to create crypto directory, error code was" << ret << std::endl; + return ret; + } + std::cout << "crypto folder was setup using the provided password, " + << "you may want to change your password hint on the " + << "pcloud website." << std::endl; + } + + if(int ret = pcryptofolder_unlock(pwd) != PSYNC_CRYPTO_START_SUCCESS) { + std::cout << "Failed to unlock crypto folder: error code was " << ret << std::endl; + return ret; + } + clib::pclsync_lib::get_lib().crypto_on_ = true; - return ret; + return 0; } static const char *status2string(uint32_t status) { @@ -450,12 +459,12 @@ int clib::pclsync_lib::init() { psync_free(username_old); } - psync_overlay_register_callback(20, &clib::pclsync_lib::start_crypto); - psync_overlay_register_callback(21, &clib::pclsync_lib::stop_crypto); - psync_overlay_register_callback(22, &clib::pclsync_lib::finalize); - psync_overlay_register_callback(23, &clib::pclsync_lib::list_sync_folders); - psync_overlay_register_callback(24, &clib::pclsync_lib::add_sync_folder); - psync_overlay_register_callback(25, &clib::pclsync_lib::remove_sync_folder); + psync_overlay_register_callback(STARTCRYPTO, &clib::pclsync_lib::start_crypto); + psync_overlay_register_callback(STOPCRYPTO, &clib::pclsync_lib::stop_crypto); + psync_overlay_register_callback(FINALIZE, &clib::pclsync_lib::finalize); + psync_overlay_register_callback(LISTSYNC, &clib::pclsync_lib::list_sync_folders); + psync_overlay_register_callback(ADDSYNC, &clib::pclsync_lib::add_sync_folder); + psync_overlay_register_callback(STOPSYNC, &clib::pclsync_lib::remove_sync_folder); return 0; }