security enhancements and small formatting changes

- wipe crypto password on all crypto folder unlock return paths
- wipe passwords on logout/unlink
- *pwd reference setup only after online check succeeds
This commit is contained in:
Levi Neely 2025-03-11 13:31:06 +01:00
parent b1e9e98a1e
commit 9236ad2b2d
3 changed files with 52 additions and 10 deletions

View File

@ -1,6 +1,10 @@
#ifndef __PUTIL_H
#define __PUTIL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#define NTO_STR(s) TO_STR(s)
@ -9,4 +13,8 @@
void putil_wipe(void *mem, size_t sz);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -43,6 +43,7 @@
#include "pshm.h"
#include "pdevice.h"
#include "pcommands.h"
#include "putil.h"
#include "pclsync_lib.h"
@ -70,6 +71,18 @@ const std::string &clib::pclsync_lib::get_crypto_pass() {
return crypto_pass_;
};
void clib::pclsync_lib::wipe_crypto_pass() {
this->wipe(crypto_pass_);
}
void clib::pclsync_lib::wipe_password() {
this->wipe(password_);
}
void clib::pclsync_lib::wipe_tfa_code() {
this->wipe(tfa_code_);
}
const std::string &clib::pclsync_lib::get_mount() { return mount_; }
void clib::pclsync_lib::set_trusted_device(bool arg) {
@ -201,21 +214,22 @@ void event_handler(psync_eventtype_t event, psync_eventdata_t eventdata) {
}
static int lib_setup_cripto() {
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;
}
const char *pwd = clib::pclsync_lib::get_lib().get_crypto_pass().c_str();
if(!pcryptofolder_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;
clib::pclsync_lib::get_lib().wipe_crypto_pass();
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;
clib::pclsync_lib::get_lib().wipe_crypto_pass();
return ret;
}
std::cout << "crypto folder was setup using the provided password, "
@ -225,9 +239,11 @@ static int lib_setup_cripto() {
if(int ret = pcryptofolder_unlock(pwd) != PSYNC_CRYPTO_START_SUCCESS) {
std::cout << "Failed to unlock crypto folder: error code was " << ret << std::endl;
clib::pclsync_lib::get_lib().wipe_crypto_pass();
return ret;
}
clib::pclsync_lib::get_lib().wipe_crypto_pass();
clib::pclsync_lib::get_lib().crypto_on_ = true;
return 0;
}
@ -470,22 +486,33 @@ int clib::pclsync_lib::init() {
}
int clib::pclsync_lib::login(const char *user, const char *pass, int save) {
set_username(user);
set_password(pass);
set_savepass(bool(save));
username_ = user;
password_ = pass;
save_pass_ = save;
psync_set_user_pass(user, pass, save);
return 0;
}
int clib::pclsync_lib::logout() {
set_password("");
wipe_password();
psync_logout();
return 0;
}
int clib::pclsync_lib::unlink() {
set_username("");
set_password("");
wipe_password();
psync_unlink();
return 0;
}
void clib::pclsync_lib::wipe(std::string& s) {
if (s.empty()) {
return;
}
void* mem = &s[0];
size_t sz = s.size();
putil_wipe(mem, sz);
s.clear();
}

View File

@ -77,6 +77,12 @@ public:
void set_daemon(bool p);
void set_status_callback(status_callback_t p);
// FIXME: not ideal, better if programmer does not have to remember to do
// this, but good enough for now...
void wipe_password();
void wipe_crypto_pass();
void wipe_tfa_code();
// Singleton
static pclsync_lib &get_lib();
@ -103,9 +109,9 @@ public:
private:
std::string username_;
std::string password_;
std::string tfa_code_;
std::string crypto_pass_;
std::string password_; // SENSITIVE, use wipe function
std::string tfa_code_; // SENSITIVE, use wipe function
std::string crypto_pass_; // SENSITIVE, use wipe function
std::string mount_;
@ -113,6 +119,7 @@ private:
bool daemon_;
void do_get_pass_from_console(std::string &password);
void wipe(std::string& str);
};
} // namespace clibrary
} // namespace console_client