84 security enhancements (#133)
- DoD 5220.22-M compliant memory wipe replaces single-pass zero wipe - Wipe in-memory request and response messages before freeing - Wipe in-memory private keys and salt data before freeing - Wipe all passwords on unlink / logout - Wipe crypto password on all pcryptofolder_unlock return paths
This commit is contained in:
parent
3c713d6437
commit
79141898c3
4
main.cpp
4
main.cpp
|
|
@ -117,7 +117,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
cc::clibrary::pclsync_lib::get_lib().set_username(username);
|
cc::clibrary::pclsync_lib::get_lib().set_username(username);
|
||||||
if (passwordsw) {
|
if (passwordsw) {
|
||||||
cc::clibrary::pclsync_lib::get_lib().get_pass_from_console();
|
cc::clibrary::pclsync_lib::get_lib().read_password();
|
||||||
}
|
}
|
||||||
cc::clibrary::pclsync_lib::get_lib().set_tfa_code(tfa_code);
|
cc::clibrary::pclsync_lib::get_lib().set_tfa_code(tfa_code);
|
||||||
cc::clibrary::pclsync_lib::get_lib().set_trusted_device(trusted_device);
|
cc::clibrary::pclsync_lib::get_lib().set_trusted_device(trusted_device);
|
||||||
|
|
@ -127,7 +127,7 @@ int main(int argc, char **argv) {
|
||||||
cc::clibrary::pclsync_lib::get_lib().set_crypto_pass(password);
|
cc::clibrary::pclsync_lib::get_lib().set_crypto_pass(password);
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Enter crypto password." << std::endl;
|
std::cout << "Enter crypto password." << std::endl;
|
||||||
cc::clibrary::pclsync_lib::get_lib().get_cryptopass_from_console();
|
cc::clibrary::pclsync_lib::get_lib().read_cryptopass();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
cc::clibrary::pclsync_lib::get_lib().setup_crypto_ = false;
|
cc::clibrary::pclsync_lib::get_lib().setup_crypto_ = false;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@
|
||||||
#include <mbedtls/ssl.h>
|
#include <mbedtls/ssl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "pfile.h"
|
|
||||||
#include "pcompiler.h"
|
#include "pcompiler.h"
|
||||||
|
|
||||||
#include "pssl.h"
|
#include "pssl.h"
|
||||||
|
|
@ -68,7 +67,7 @@ static void psync_hmac_sha512_init(psync_hmac_sha512_ctx *ctx,
|
||||||
}
|
}
|
||||||
psync_sha512_init(&ctx->sha1ctx);
|
psync_sha512_init(&ctx->sha1ctx);
|
||||||
psync_sha512_update(&ctx->sha1ctx, keyxor, PSYNC_SHA512_BLOCK_LEN);
|
psync_sha512_update(&ctx->sha1ctx, keyxor, PSYNC_SHA512_BLOCK_LEN);
|
||||||
pssl_memclean(keyxor, PSYNC_SHA512_BLOCK_LEN);
|
putil_wipe(keyxor, PSYNC_SHA512_BLOCK_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void psync_hmac_sha512_update(psync_hmac_sha512_ctx *ctx,
|
static void psync_hmac_sha512_update(psync_hmac_sha512_ctx *ctx,
|
||||||
|
|
@ -81,7 +80,7 @@ static void psync_hmac_sha512_final(unsigned char *result,
|
||||||
psync_sha512_final(ctx->final + PSYNC_SHA512_BLOCK_LEN, &ctx->sha1ctx);
|
psync_sha512_final(ctx->final + PSYNC_SHA512_BLOCK_LEN, &ctx->sha1ctx);
|
||||||
psync_sha512(ctx->final, PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN,
|
psync_sha512(ctx->final, PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN,
|
||||||
result);
|
result);
|
||||||
pssl_memclean(ctx->final,
|
putil_wipe(ctx->final,
|
||||||
PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN);
|
PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,8 +106,8 @@ static void psync_hmac_sha512(const unsigned char *msg, size_t msglen,
|
||||||
psync_sha512_update(&sha1ctx, msg, msglen);
|
psync_sha512_update(&sha1ctx, msg, msglen);
|
||||||
psync_sha512_final(final + PSYNC_SHA512_BLOCK_LEN, &sha1ctx);
|
psync_sha512_final(final + PSYNC_SHA512_BLOCK_LEN, &sha1ctx);
|
||||||
psync_sha512(final, PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN, result);
|
psync_sha512(final, PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN, result);
|
||||||
pssl_memclean(keyxor, PSYNC_SHA512_BLOCK_LEN);
|
putil_wipe(keyxor, PSYNC_SHA512_BLOCK_LEN);
|
||||||
pssl_memclean(final, PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN);
|
putil_wipe(final, PSYNC_SHA512_BLOCK_LEN + PSYNC_SHA512_DIGEST_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ALIGN_A256_BS(n) \
|
#define ALIGN_A256_BS(n) \
|
||||||
|
|
@ -193,7 +192,7 @@ pcrypto_ctr_encdec_t pcrypto_ctr_encdec_create(psync_symmetric_key_t key) {
|
||||||
void pcrypto_ctr_encdec_free(
|
void pcrypto_ctr_encdec_free(
|
||||||
pcrypto_ctr_encdec_t enc) {
|
pcrypto_ctr_encdec_t enc) {
|
||||||
paes_free_encoder(enc->encoder);
|
paes_free_encoder(enc->encoder);
|
||||||
pssl_memclean(enc->iv, PSYNC_AES256_BLOCK_SIZE);
|
putil_wipe(enc->iv, PSYNC_AES256_BLOCK_SIZE);
|
||||||
psync_free(enc);
|
psync_free(enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -419,7 +418,7 @@ pcrypto_textenc_create(psync_symmetric_key_t key) {
|
||||||
void pcrypto_textenc_free(
|
void pcrypto_textenc_free(
|
||||||
pcrypto_textenc_t enc) {
|
pcrypto_textenc_t enc) {
|
||||||
paes_free_encoder(enc->encoder);
|
paes_free_encoder(enc->encoder);
|
||||||
pssl_memclean(enc->iv, enc->ivlen);
|
putil_wipe(enc->iv, enc->ivlen);
|
||||||
pmemlock_free(enc);
|
pmemlock_free(enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -445,7 +444,7 @@ pcrypto_textdec_create(psync_symmetric_key_t key) {
|
||||||
void pcrypto_textdec_free(
|
void pcrypto_textdec_free(
|
||||||
pcrypto_textdec_t enc) {
|
pcrypto_textdec_t enc) {
|
||||||
paes_free_encoder(enc->encoder);
|
paes_free_encoder(enc->encoder);
|
||||||
pssl_memclean(enc->iv, enc->ivlen);
|
putil_wipe(enc->iv, enc->ivlen);
|
||||||
pmemlock_free(enc);
|
pmemlock_free(enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,7 +477,7 @@ void pcrypto_sec_encdec_free(
|
||||||
pcrypto_sector_encdec_t enc) {
|
pcrypto_sector_encdec_t enc) {
|
||||||
paes_free_encoder(enc->encoder);
|
paes_free_encoder(enc->encoder);
|
||||||
paes_free_decoder(enc->decoder);
|
paes_free_decoder(enc->decoder);
|
||||||
pssl_memclean(enc->iv, enc->ivlen);
|
putil_wipe(enc->iv, enc->ivlen);
|
||||||
pmemlock_free(enc);
|
pmemlock_free(enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@ static int download_keys(unsigned char **rsapriv, size_t *rsaprivlen, unsigned c
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
def1:
|
def1:
|
||||||
|
putil_wipe(rsaprivstruct, rsaprivstructlen);
|
||||||
psync_free(rsaprivstruct);
|
psync_free(rsaprivstruct);
|
||||||
psync_free(rsapubstruct);
|
psync_free(rsapubstruct);
|
||||||
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
|
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
|
||||||
|
|
@ -292,10 +293,12 @@ static int download_keys(unsigned char **rsapriv, size_t *rsaprivlen, unsigned c
|
||||||
default:
|
default:
|
||||||
def2:
|
def2:
|
||||||
psync_free(*rsapub);
|
psync_free(*rsapub);
|
||||||
|
putil_wipe(rsaprivstruct, rsaprivstructlen);
|
||||||
psync_free(rsaprivstruct);
|
psync_free(rsaprivstruct);
|
||||||
psync_free(rsapubstruct);
|
psync_free(rsapubstruct);
|
||||||
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
|
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
|
||||||
}
|
}
|
||||||
|
putil_wipe(rsaprivstruct, rsaprivstructlen);
|
||||||
psync_free(rsaprivstruct);
|
psync_free(rsaprivstruct);
|
||||||
psync_free(rsapubstruct);
|
psync_free(rsapubstruct);
|
||||||
return PSYNC_CRYPTO_START_SUCCESS;
|
return PSYNC_CRYPTO_START_SUCCESS;
|
||||||
|
|
@ -591,6 +594,7 @@ int pcryptofolder_unlock(const char *password) {
|
||||||
if (unlikely(rowcnt != 0)) {
|
if (unlikely(rowcnt != 0)) {
|
||||||
debug(D_BUG,
|
debug(D_BUG,
|
||||||
"only some of records found in the database, should not happen");
|
"only some of records found in the database, should not happen");
|
||||||
|
putil_wipe(rsapriv, rsaprivlen);
|
||||||
psync_free(rsapriv);
|
psync_free(rsapriv);
|
||||||
psync_free(rsapub);
|
psync_free(rsapub);
|
||||||
psync_free(salt);
|
psync_free(salt);
|
||||||
|
|
@ -614,8 +618,10 @@ int pcryptofolder_unlock(const char *password) {
|
||||||
if (crypto_pubkey == PSYNC_INVALID_RSA) {
|
if (crypto_pubkey == PSYNC_INVALID_RSA) {
|
||||||
pthread_rwlock_unlock(&crypto_lock);
|
pthread_rwlock_unlock(&crypto_lock);
|
||||||
debug(D_WARNING, "could not load public key");
|
debug(D_WARNING, "could not load public key");
|
||||||
|
putil_wipe(rsapriv, rsaprivlen);
|
||||||
psync_free(rsapriv);
|
psync_free(rsapriv);
|
||||||
psync_free(rsapub);
|
psync_free(rsapub);
|
||||||
|
putil_wipe(salt, saltlen);
|
||||||
psync_free(salt);
|
psync_free(salt);
|
||||||
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
|
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_UNKNOWN_KEY_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
@ -634,15 +640,17 @@ int pcryptofolder_unlock(const char *password) {
|
||||||
|
|
||||||
debug(D_NOTICE, "trying to load private key");
|
debug(D_NOTICE, "trying to load private key");
|
||||||
crypto_privkey = prsa_load_private(rsaprivdec, rsaprivlen);
|
crypto_privkey = prsa_load_private(rsaprivdec, rsaprivlen);
|
||||||
pssl_memclean(rsaprivdec, rsaprivlen);
|
putil_wipe(rsaprivdec, rsaprivlen);
|
||||||
pmemlock_free(rsaprivdec);
|
pmemlock_free(rsaprivdec);
|
||||||
if (crypto_privkey == PSYNC_INVALID_RSA) {
|
if (crypto_privkey == PSYNC_INVALID_RSA) {
|
||||||
debug(D_NOTICE, "failed to load private key");
|
debug(D_NOTICE, "failed to load private key");
|
||||||
prsa_free_public(crypto_pubkey);
|
prsa_free_public(crypto_pubkey);
|
||||||
crypto_pubkey = PSYNC_INVALID_RSA;
|
crypto_pubkey = PSYNC_INVALID_RSA;
|
||||||
pthread_rwlock_unlock(&crypto_lock);
|
pthread_rwlock_unlock(&crypto_lock);
|
||||||
|
putil_wipe(rsapriv, rsaprivlen);
|
||||||
psync_free(rsapriv);
|
psync_free(rsapriv);
|
||||||
psync_free(rsapub);
|
psync_free(rsapub);
|
||||||
|
putil_wipe(salt, saltlen);
|
||||||
psync_free(salt);
|
psync_free(salt);
|
||||||
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_BAD_PASSWORD);
|
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_BAD_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
@ -656,8 +664,10 @@ int pcryptofolder_unlock(const char *password) {
|
||||||
crypto_privkey = PSYNC_INVALID_RSA;
|
crypto_privkey = PSYNC_INVALID_RSA;
|
||||||
pthread_rwlock_unlock(&crypto_lock);
|
pthread_rwlock_unlock(&crypto_lock);
|
||||||
debug(D_ERROR, "keys don't match");
|
debug(D_ERROR, "keys don't match");
|
||||||
|
putil_wipe(rsapriv, rsaprivlen);
|
||||||
psync_free(rsapriv);
|
psync_free(rsapriv);
|
||||||
psync_free(rsapub);
|
psync_free(rsapub);
|
||||||
|
putil_wipe(salt, saltlen);
|
||||||
psync_free(salt);
|
psync_free(salt);
|
||||||
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_KEYS_DONT_MATCH);
|
return PRINT_RETURN_CONST(PSYNC_CRYPTO_START_KEYS_DONT_MATCH);
|
||||||
}
|
}
|
||||||
|
|
@ -672,8 +682,10 @@ int pcryptofolder_unlock(const char *password) {
|
||||||
salt, saltlen, iterations, 0,
|
salt, saltlen, iterations, 0,
|
||||||
publicsha1, privatesha1, flags);
|
publicsha1, privatesha1, flags);
|
||||||
}
|
}
|
||||||
|
putil_wipe(rsapriv, rsaprivlen);
|
||||||
psync_free(rsapriv);
|
psync_free(rsapriv);
|
||||||
psync_free(rsapub);
|
psync_free(rsapub);
|
||||||
|
putil_wipe(salt, saltlen);
|
||||||
psync_free(salt);
|
psync_free(salt);
|
||||||
debug(D_NOTICE, "crypto successfully started");
|
debug(D_NOTICE, "crypto successfully started");
|
||||||
return PSYNC_CRYPTO_START_SUCCESS;
|
return PSYNC_CRYPTO_START_SUCCESS;
|
||||||
|
|
@ -1704,7 +1716,7 @@ char *pcryptofolder_filencoder_key_new(uint32_t flags, size_t *keylen) {
|
||||||
debug(D_ERROR, "RSA encryption failed");
|
debug(D_ERROR, "RSA encryption failed");
|
||||||
return (char *)errptr(PRINT_RETURN_CONST(PSYNC_CRYPTO_RSA_ERROR));
|
return (char *)errptr(PRINT_RETURN_CONST(PSYNC_CRYPTO_RSA_ERROR));
|
||||||
}
|
}
|
||||||
pssl_memclean(&sym, sizeof(sym));
|
putil_wipe(&sym, sizeof(sym));
|
||||||
ret = (char *)psync_base64_encode(encsym->data, encsym->datalen, keylen);
|
ret = (char *)psync_base64_encode(encsym->data, encsym->datalen, keylen);
|
||||||
psync_free(encsym);
|
psync_free(encsym);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -1734,7 +1746,7 @@ char *pcryptofolder_filencoder_key_newplain(
|
||||||
return (char *)errptr(PRINT_RETURN_CONST(PSYNC_CRYPTO_RSA_ERROR));
|
return (char *)errptr(PRINT_RETURN_CONST(PSYNC_CRYPTO_RSA_ERROR));
|
||||||
}
|
}
|
||||||
*deckey = symkeyv1_to_symkey(&sym);
|
*deckey = symkeyv1_to_symkey(&sym);
|
||||||
pssl_memclean(&sym, sizeof(sym));
|
putil_wipe(&sym, sizeof(sym));
|
||||||
ret = (char *)psync_base64_encode(encsym->data, encsym->datalen, keylen);
|
ret = (char *)psync_base64_encode(encsym->data, encsym->datalen, keylen);
|
||||||
psync_free(encsym);
|
psync_free(encsym);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -1762,7 +1774,7 @@ int pcryptofolder_mkdir(psync_folderid_t folderid, const char *name,
|
||||||
}
|
}
|
||||||
encsym = prsa_encrypt_data(crypto_pubkey, (unsigned char *)&sym,
|
encsym = prsa_encrypt_data(crypto_pubkey, (unsigned char *)&sym,
|
||||||
sizeof(sym));
|
sizeof(sym));
|
||||||
pssl_memclean(&sym, sizeof(sym));
|
putil_wipe(&sym, sizeof(sym));
|
||||||
ret = get_fldr_name(folderid, name, &ename, err);
|
ret = get_fldr_name(folderid, name, &ename, err);
|
||||||
pthread_rwlock_unlock(&crypto_lock);
|
pthread_rwlock_unlock(&crypto_lock);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
@ -1864,7 +1876,7 @@ int psync_pcloud_crypto_reencode_key(
|
||||||
pcrypto_ctr_encdec_free(enc);
|
pcrypto_ctr_encdec_free(enc);
|
||||||
newprivlen = offsetof(priv_key_ver1, key) + rsaprivlen;
|
newprivlen = offsetof(priv_key_ver1, key) + rsaprivlen;
|
||||||
priv = prsa_load_private(rsaprivdec, rsaprivlen);
|
priv = prsa_load_private(rsaprivdec, rsaprivlen);
|
||||||
pssl_memclean(rsaprivdec, rsaprivlen);
|
putil_wipe(rsaprivdec, rsaprivlen);
|
||||||
psync_free(rsaprivdec);
|
psync_free(rsaprivdec);
|
||||||
if (unlikely(priv == PSYNC_INVALID_RSA))
|
if (unlikely(priv == PSYNC_INVALID_RSA))
|
||||||
goto err_ph_1;
|
goto err_ph_1;
|
||||||
|
|
@ -1954,6 +1966,7 @@ int psync_pcloud_crypto_encode_key(const char *newpassphrase, uint32_t flags,
|
||||||
psync_sha256(newpriv, rsaprivlen, newprivsha);
|
psync_sha256(newpriv, rsaprivlen, newprivsha);
|
||||||
rsasign = prsa_sign_sha256_hash(crypto_privkey, newprivsha);
|
rsasign = prsa_sign_sha256_hash(crypto_privkey, newprivsha);
|
||||||
if (is_err(rsasign)) {
|
if (is_err(rsasign)) {
|
||||||
|
putil_wipe(newpriv, rsaprivlen);
|
||||||
psync_free(newpriv);
|
psync_free(newpriv);
|
||||||
prsa_free_binary(rsapriv);
|
prsa_free_binary(rsapriv);
|
||||||
return to_err(rsasign);
|
return to_err(rsasign);
|
||||||
|
|
@ -1961,6 +1974,7 @@ int psync_pcloud_crypto_encode_key(const char *newpassphrase, uint32_t flags,
|
||||||
*privenc = (char *)psync_base64_encode(newpriv, rsaprivlen, &dummy);
|
*privenc = (char *)psync_base64_encode(newpriv, rsaprivlen, &dummy);
|
||||||
*sign = (char *)psync_base64_encode(rsasign->data, rsasign->datalen, &dummy);
|
*sign = (char *)psync_base64_encode(rsasign->data, rsasign->datalen, &dummy);
|
||||||
psync_free(rsasign);
|
psync_free(rsasign);
|
||||||
|
putil_wipe(newpriv, rsaprivlen);
|
||||||
psync_free(newpriv);
|
psync_free(newpriv);
|
||||||
prsa_free_binary(rsapriv);
|
prsa_free_binary(rsapriv);
|
||||||
|
|
||||||
|
|
@ -2017,6 +2031,7 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
|
||||||
memset(privatekey_struct, 0, offsetof(priv_key_ver1, key) + privkeylen);
|
memset(privatekey_struct, 0, offsetof(priv_key_ver1, key) + privkeylen);
|
||||||
memcpy(privatekey_struct->key, privkey, privkeylen);
|
memcpy(privatekey_struct->key, privkey, privkeylen);
|
||||||
privatekey_struct->type = PSYNC_CRYPTO_TYPE_RSA4096_64BYTESALT_20000IT;
|
privatekey_struct->type = PSYNC_CRYPTO_TYPE_RSA4096_64BYTESALT_20000IT;
|
||||||
|
putil_wipe(privkey, privkeylen);
|
||||||
psync_free(privkey);
|
psync_free(privkey);
|
||||||
} else if (!strcmp(id, "crypto_public_key")) {
|
} else if (!strcmp(id, "crypto_public_key")) {
|
||||||
load_str_to(&row[1], &pubkey, &pubkeylen);
|
load_str_to(&row[1], &pubkey, &pubkeylen);
|
||||||
|
|
@ -2034,6 +2049,7 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
memcpy(privatekey_struct->salt, salt, saltlen);
|
memcpy(privatekey_struct->salt, salt, saltlen);
|
||||||
|
putil_wipe(salt, saltlen);
|
||||||
psync_free(salt);
|
psync_free(salt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2081,7 +2097,9 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
|
||||||
pubkey, pubkeylen, privkey, privkeylen, oldpassphrase, newpassphrase,
|
pubkey, pubkeylen, privkey, privkeylen, oldpassphrase, newpassphrase,
|
||||||
flags, privenc, sign);
|
flags, privenc, sign);
|
||||||
psync_free(pubkey);
|
psync_free(pubkey);
|
||||||
|
putil_wipe(privkey, privkeylen);
|
||||||
psync_free(privkey);
|
psync_free(privkey);
|
||||||
|
putil_wipe(salt, saltlen);
|
||||||
psync_free(salt);
|
psync_free(salt);
|
||||||
if (cres)
|
if (cres)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
@ -2092,6 +2110,7 @@ int pcryptofolder_change_pass(const char *oldpassphrase,
|
||||||
(unsigned char *)privatekey_struct,
|
(unsigned char *)privatekey_struct,
|
||||||
privkeylen + offsetof(priv_key_ver1, key), oldpassphrase, newpassphrase,
|
privkeylen + offsetof(priv_key_ver1, key), oldpassphrase, newpassphrase,
|
||||||
flags, privenc, sign);
|
flags, privenc, sign);
|
||||||
|
putil_wipe(privatekey_struct, privkeylen + offsetof(priv_key_ver1, key));
|
||||||
psync_free(privatekey_struct);
|
psync_free(privatekey_struct);
|
||||||
psync_free(pubkey_struct);
|
psync_free(pubkey_struct);
|
||||||
if (cres)
|
if (cres)
|
||||||
|
|
|
||||||
|
|
@ -2583,14 +2583,14 @@ int psync_get_upload_checksum(psync_uploadid_t uploadid, unsigned char *uhash,
|
||||||
return PSYNC_NET_OK;
|
return PSYNC_NET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void psync_logout2(uint32_t auth_status, int doinvauth);
|
static void proc_logout() {
|
||||||
|
psync_logout(PSTATUS_AUTH_BADTOKEN, 0);
|
||||||
static void logout2_thread() { psync_logout2(PSTATUS_AUTH_BADTOKEN, 0); }
|
}
|
||||||
|
|
||||||
// this is called when ANY api call returns non zero result
|
// this is called when ANY api call returns non zero result
|
||||||
void psync_process_api_error(uint64_t result) {
|
void psync_process_api_error(uint64_t result) {
|
||||||
if (result == 2000)
|
if (result == 2000)
|
||||||
prun_thread("logout from process_api_error", logout2_thread);
|
prun_thread("logout from process_api_error", proc_logout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void psync_netlibs_timer(psync_timer_t timer, void *ptr) {
|
static void psync_netlibs_timer(psync_timer_t timer, void *ptr) {
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include "ppassword.h"
|
#include "ppassword.h"
|
||||||
#include "ppassworddict.h"
|
#include "ppassworddict.h"
|
||||||
#include "pssl.h"
|
#include "pssl.h"
|
||||||
|
#include "putil.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -351,8 +352,8 @@ uint64_t ppassword_score(const char *cpassword) {
|
||||||
ldpwd[nlen] = lpwd[nlen];
|
ldpwd[nlen] = lpwd[nlen];
|
||||||
}
|
}
|
||||||
num = score_variants(password, lpwd, ldpwd, plen);
|
num = score_variants(password, lpwd, ldpwd, plen);
|
||||||
pssl_memclean(lpwd, plen);
|
putil_wipe(lpwd, plen);
|
||||||
pssl_memclean(ldpwd, plen);
|
putil_wipe(ldpwd, plen);
|
||||||
psync_free(lpwd);
|
psync_free(lpwd);
|
||||||
psync_free(ldpwd);
|
psync_free(ldpwd);
|
||||||
mul_score(num);
|
mul_score(num);
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@
|
||||||
#include "pssl.h"
|
#include "pssl.h"
|
||||||
#include "psslcerts.h"
|
#include "psslcerts.h"
|
||||||
#include "psynclib.h"
|
#include "psynclib.h"
|
||||||
|
#include "putil.h"
|
||||||
|
|
||||||
|
|
||||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
@ -69,7 +70,7 @@ static void ssl_debug(int loglevel, int errnum, const char *msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_encrypted(psync_encrypted_data_t e) {
|
static void free_encrypted(psync_encrypted_data_t e) {
|
||||||
pssl_memclean(e->data, e->datalen);
|
putil_wipe(e->data, e->datalen);
|
||||||
pmemlock_free(e);
|
pmemlock_free(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +79,7 @@ void prsa_free_binary(psync_binary_rsa_key_t bin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void psymkey_free(psync_symmetric_key_t key) {
|
void psymkey_free(psync_symmetric_key_t key) {
|
||||||
pssl_memclean(key->key, key->keylen);
|
putil_wipe(key->key, key->keylen);
|
||||||
pmemlock_free(key);
|
pmemlock_free(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,12 +208,6 @@ int pssl_init() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pssl_memclean(void *ptr, size_t len) {
|
|
||||||
volatile unsigned char *p = ptr;
|
|
||||||
while (len--)
|
|
||||||
*p++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssl_connection_t *conn_alloc(const char *hostname) {
|
static ssl_connection_t *conn_alloc(const char *hostname) {
|
||||||
ssl_connection_t *conn;
|
ssl_connection_t *conn;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
@ -574,7 +569,7 @@ prsa_private_to_binary(psync_rsa_privatekey_t rsa) {
|
||||||
pmemlock_malloc(offsetof(psync_encrypted_data_struct_t, data) + len);
|
pmemlock_malloc(offsetof(psync_encrypted_data_struct_t, data) + len);
|
||||||
ret->datalen = len;
|
ret->datalen = len;
|
||||||
memcpy(ret->data, buff + sizeof(buff) - len, len);
|
memcpy(ret->data, buff + sizeof(buff) - len, len);
|
||||||
pssl_memclean(buff + sizeof(buff) - len, len);
|
putil_wipe(buff + sizeof(buff) - len, len);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -754,7 +749,7 @@ psync_symmetric_key_t prsa_decrypt_data(psync_rsa_privatekey_t rsa,
|
||||||
offsetof(psync_symmetric_key_struct_t, key) + len);
|
offsetof(psync_symmetric_key_struct_t, key) + len);
|
||||||
ret->keylen = len;
|
ret->keylen = len;
|
||||||
memcpy(ret->key, buff, len);
|
memcpy(ret->key, buff, len);
|
||||||
pssl_memclean(buff, len);
|
putil_wipe(buff, len);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -779,7 +774,7 @@ paes_create_encoder(psync_symmetric_key_t key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void paes_free_encoder(psync_aes256_encoder aes) {
|
void paes_free_encoder(psync_aes256_encoder aes) {
|
||||||
pssl_memclean(aes, sizeof(mbedtls_aes_context));
|
putil_wipe(aes, sizeof(mbedtls_aes_context));
|
||||||
psync_free(aes);
|
psync_free(aes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -793,7 +788,7 @@ paes_create_decoder(psync_symmetric_key_t key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void paes_free_decoder(psync_aes256_encoder aes) {
|
void paes_free_decoder(psync_aes256_encoder aes) {
|
||||||
pssl_memclean(aes, sizeof(mbedtls_aes_context));
|
putil_wipe(aes, sizeof(mbedtls_aes_context));
|
||||||
psync_free(aes);
|
psync_free(aes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,6 @@ typedef psync_encrypted_data_t psync_rsa_signature_t;
|
||||||
// Lock used to serialize access to RSA decrypt key function
|
// Lock used to serialize access to RSA decrypt key function
|
||||||
|
|
||||||
int pssl_init();
|
int pssl_init();
|
||||||
void pssl_memclean(void *ptr, size_t len);
|
|
||||||
int pssl_connect(int sock, void **sslconn, const char *hostname);
|
int pssl_connect(int sock, void **sslconn, const char *hostname);
|
||||||
int pssl_connect_finish(void *sslconn, const char *hostname);
|
int pssl_connect_finish(void *sslconn, const char *hostname);
|
||||||
void pssl_free(void *sslconn);
|
void pssl_free(void *sslconn);
|
||||||
|
|
|
||||||
|
|
@ -428,21 +428,25 @@ static void psync_invalidate_auth(const char *auth) {
|
||||||
psync_run_command("logout", params, NULL);
|
psync_run_command("logout", params, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void psync_logout2(uint32_t auth_status, int doinvauth) {
|
void psync_logout(uint32_t auth_status, int doinvauth) {
|
||||||
tfa = 0;
|
tfa = 0;
|
||||||
debug(D_NOTICE, "logout");
|
debug(D_NOTICE, "logout");
|
||||||
psync_sql_statement(
|
|
||||||
"DELETE FROM setting WHERE id IN ('pass', 'auth', 'saveauth')");
|
psync_sql_statement("DELETE FROM setting WHERE id IN ('pass', 'auth', 'saveauth')");
|
||||||
if (doinvauth)
|
if (doinvauth) {
|
||||||
psync_invalidate_auth(psync_my_auth);
|
psync_invalidate_auth(psync_my_auth);
|
||||||
memset(psync_my_auth, 0, sizeof(psync_my_auth));
|
}
|
||||||
|
putil_wipe(psync_my_auth, sizeof(psync_my_auth));
|
||||||
pcryptofolder_lock();
|
pcryptofolder_lock();
|
||||||
|
|
||||||
pthread_mutex_lock(&psync_my_auth_mutex);
|
pthread_mutex_lock(&psync_my_auth_mutex);
|
||||||
|
putil_wipe(psync_my_pass, sizeof(psync_my_pass));
|
||||||
psync_free(psync_my_pass);
|
psync_free(psync_my_pass);
|
||||||
psync_my_pass = NULL;
|
|
||||||
pthread_mutex_unlock(&psync_my_auth_mutex);
|
pthread_mutex_unlock(&psync_my_auth_mutex);
|
||||||
|
|
||||||
pstatus_set(PSTATUS_TYPE_ONLINE, PSTATUS_ONLINE_CONNECTING);
|
pstatus_set(PSTATUS_TYPE_ONLINE, PSTATUS_ONLINE_CONNECTING);
|
||||||
pstatus_set(PSTATUS_TYPE_AUTH, auth_status);
|
pstatus_set(PSTATUS_TYPE_AUTH, auth_status);
|
||||||
|
|
||||||
psync_fs_pause_until_login();
|
psync_fs_pause_until_login();
|
||||||
pdownload_stop_all();
|
pdownload_stop_all();
|
||||||
pupload_stop_all();
|
pupload_stop_all();
|
||||||
|
|
@ -451,12 +455,11 @@ void psync_logout2(uint32_t auth_status, int doinvauth) {
|
||||||
psync_set_apiserver(PSYNC_API_HOST, PSYNC_LOCATIONID_DEFAULT);
|
psync_set_apiserver(PSYNC_API_HOST, PSYNC_LOCATIONID_DEFAULT);
|
||||||
psync_restart_localscan();
|
psync_restart_localscan();
|
||||||
ptimer_notify_exception();
|
ptimer_notify_exception();
|
||||||
if (psync_fs_need_per_folder_refresh())
|
if (psync_fs_need_per_folder_refresh()) {
|
||||||
psync_fs_refresh_folder(0);
|
psync_fs_refresh_folder(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void psync_logout() { psync_logout2(PSTATUS_AUTH_REQUIRED, 1); }
|
|
||||||
|
|
||||||
apiservers_list_t *psync_get_apiservers(char **err) {
|
apiservers_list_t *psync_get_apiservers(char **err) {
|
||||||
psock_t *api;
|
psock_t *api;
|
||||||
binresult *bres;
|
binresult *bres;
|
||||||
|
|
@ -573,19 +576,19 @@ void psync_unlink() {
|
||||||
ppagecache_clean();
|
ppagecache_clean();
|
||||||
psync_sql_connect(psync_database);
|
psync_sql_connect(psync_database);
|
||||||
if (deviceid) {
|
if (deviceid) {
|
||||||
res = psync_sql_prep_statement(
|
res = psync_sql_prep_statement("REPLACE INTO setting (id, value) VALUES ('deviceid', ?)");
|
||||||
"REPLACE INTO setting (id, value) VALUES ('deviceid', ?)");
|
|
||||||
psync_sql_bind_string(res, 1, deviceid);
|
psync_sql_bind_string(res, 1, deviceid);
|
||||||
psync_sql_run_free(res);
|
psync_sql_run_free(res);
|
||||||
psync_free(deviceid);
|
psync_free(deviceid);
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&psync_my_auth_mutex);
|
pthread_mutex_lock(&psync_my_auth_mutex);
|
||||||
memset(psync_my_auth, 0, sizeof(psync_my_auth));
|
putil_wipe(psync_my_auth, sizeof(psync_my_auth));
|
||||||
psync_my_user = NULL;
|
psync_my_user = NULL;
|
||||||
psync_my_pass = NULL;
|
putil_wipe(psync_my_pass, sizeof(psync_my_pass));
|
||||||
psync_my_userid = 0;
|
psync_my_userid = 0;
|
||||||
pthread_mutex_unlock(&psync_my_auth_mutex);
|
pthread_mutex_unlock(&psync_my_auth_mutex);
|
||||||
debug(D_NOTICE, "clearing database, finished");
|
debug(D_NOTICE, "clearing database, finished");
|
||||||
|
|
||||||
psync_fs_pause_until_login();
|
psync_fs_pause_until_login();
|
||||||
psync_fs_clean_tasks();
|
psync_fs_clean_tasks();
|
||||||
ppathstatus_init();
|
ppathstatus_init();
|
||||||
|
|
@ -602,8 +605,9 @@ void psync_unlink() {
|
||||||
pstatus_set(PSTATUS_TYPE_AUTH, PSTATUS_AUTH_REQUIRED);
|
pstatus_set(PSTATUS_TYPE_AUTH, PSTATUS_AUTH_REQUIRED);
|
||||||
pstatus_set(PSTATUS_TYPE_RUN, PSTATUS_RUN_RUN);
|
pstatus_set(PSTATUS_TYPE_RUN, PSTATUS_RUN_RUN);
|
||||||
psync_resume_localscan();
|
psync_resume_localscan();
|
||||||
if (psync_fs_need_per_folder_refresh())
|
if (psync_fs_need_per_folder_refresh()) {
|
||||||
psync_fs_refresh_folder(0);
|
psync_fs_refresh_folder(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int psync_tfa_has_devices() { return psync_my_2fa_has_devices; }
|
int psync_tfa_has_devices() { return psync_my_2fa_has_devices; }
|
||||||
|
|
|
||||||
|
|
@ -638,7 +638,7 @@ char *psync_get_username();
|
||||||
void psync_set_user_pass(const char *username, const char *password, int save);
|
void psync_set_user_pass(const char *username, const char *password, int save);
|
||||||
void psync_set_pass(const char *password, int save);
|
void psync_set_pass(const char *password, int save);
|
||||||
void psync_set_auth(const char *auth, int save);
|
void psync_set_auth(const char *auth, int save);
|
||||||
void psync_logout();
|
void psync_logout(uint32_t auth_status, int doinvauth);
|
||||||
void psync_unlink();
|
void psync_unlink();
|
||||||
|
|
||||||
/* Upon seein a status of PSTATUS_TFA_REQUIRED the application is supposed to
|
/* Upon seein a status of PSTATUS_TFA_REQUIRED the application is supposed to
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
|
||||||
|
#include "plibs.h"
|
||||||
|
|
||||||
|
// wipe a segment of memory mem of size sz using a DoD 5220.22-M compliant
|
||||||
|
// 3-pass wipe. the first pass overwrites the memory with zeroes, the second
|
||||||
|
// with ones, and the third with random data using the urandom entropy
|
||||||
|
// source. if the urandom source fails, it falls back to a simple
|
||||||
|
// (non-cryptographically-secure) RNG.
|
||||||
|
void putil_wipe(void *mem, size_t sz) {
|
||||||
|
if (!mem || sz == 0) { return; }
|
||||||
|
|
||||||
|
volatile unsigned char *p = (volatile unsigned char *)mem;
|
||||||
|
|
||||||
|
memset((void*)p, 0x00, sz);
|
||||||
|
memset((void*)p, 0xFF, sz);
|
||||||
|
|
||||||
|
ssize_t result = getrandom((void*)p, sz, 0);
|
||||||
|
if (result != (ssize_t)sz) {
|
||||||
|
if (result == -1) {
|
||||||
|
debug(D_WARNING, "getrandom() failed: %s.", strerror(errno));
|
||||||
|
} else {
|
||||||
|
debug(D_WARNING, "getrandom() returned partial data.");
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(D_WARNING, "falling back to less secure third pass. This may occur due to insufficient entropy, early boot state, or kernel incompatibility.");
|
||||||
|
srand((unsigned int)(time(NULL) ^ (uintptr_t)&srand));
|
||||||
|
for (size_t i = 0; i < sz; i++) {
|
||||||
|
p[i] = (unsigned char)rand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,20 @@
|
||||||
|
#ifndef __PUTIL_H
|
||||||
|
#define __PUTIL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#define NTO_STR(s) TO_STR(s)
|
#define NTO_STR(s) TO_STR(s)
|
||||||
#define TO_STR(s) #s
|
#define TO_STR(s) #s
|
||||||
#define VAR_ARRAY(name, type, size) type name[size]
|
#define VAR_ARRAY(name, type, size) type name[size]
|
||||||
|
|
||||||
|
void putil_wipe(void *mem, size_t sz);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include "pshm.h"
|
#include "pshm.h"
|
||||||
#include "pdevice.h"
|
#include "pdevice.h"
|
||||||
#include "pcommands.h"
|
#include "pcommands.h"
|
||||||
|
#include "putil.h"
|
||||||
|
|
||||||
#include "pclsync_lib.h"
|
#include "pclsync_lib.h"
|
||||||
|
|
||||||
|
|
@ -70,6 +71,18 @@ const std::string &clib::pclsync_lib::get_crypto_pass() {
|
||||||
return 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_; }
|
const std::string &clib::pclsync_lib::get_mount() { return mount_; }
|
||||||
|
|
||||||
void clib::pclsync_lib::set_trusted_device(bool arg) {
|
void clib::pclsync_lib::set_trusted_device(bool arg) {
|
||||||
|
|
@ -81,9 +94,6 @@ void clib::pclsync_lib::set_tfa_code(const std::string &arg) {
|
||||||
void clib::pclsync_lib::set_username(const std::string &arg) {
|
void clib::pclsync_lib::set_username(const std::string &arg) {
|
||||||
username_ = arg;
|
username_ = arg;
|
||||||
}
|
}
|
||||||
void clib::pclsync_lib::set_password(const std::string &arg) {
|
|
||||||
password_ = arg;
|
|
||||||
}
|
|
||||||
void clib::pclsync_lib::set_crypto_pass(const std::string &arg) {
|
void clib::pclsync_lib::set_crypto_pass(const std::string &arg) {
|
||||||
crypto_pass_ = arg;
|
crypto_pass_ = arg;
|
||||||
};
|
};
|
||||||
|
|
@ -103,30 +113,27 @@ clib::pclsync_lib &clib::pclsync_lib::get_lib() {
|
||||||
|
|
||||||
char *clib::pclsync_lib::get_token() { return psync_get_token(); }
|
char *clib::pclsync_lib::get_token() { return psync_get_token(); }
|
||||||
|
|
||||||
void clib::pclsync_lib::get_pass_from_console() {
|
void clib::pclsync_lib::read_password() {
|
||||||
do_get_pass_from_console(password_);
|
read_from_stdin(password_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clib::pclsync_lib::get_tfa_code_from_console()
|
void clib::pclsync_lib::read_tfa_code()
|
||||||
{
|
{
|
||||||
if (daemon_) {
|
if (daemon_) {
|
||||||
std::cout << "Not able to read 2fa code when started as daemon."
|
std::cout << "Not able to read 2fa code when started as daemon." << std::endl;
|
||||||
<< std::endl;
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
std::cout << "Please enter 2fa code"
|
std::cout << "Please enter 2fa code" << std::endl;
|
||||||
<< std::endl;
|
|
||||||
getline(std::cin, tfa_code_);
|
getline(std::cin, tfa_code_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clib::pclsync_lib::get_cryptopass_from_console() {
|
void clib::pclsync_lib::read_cryptopass() {
|
||||||
do_get_pass_from_console(crypto_pass_);
|
read_from_stdin(crypto_pass_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clib::pclsync_lib::do_get_pass_from_console(std::string &password) {
|
void clib::pclsync_lib::read_from_stdin(std::string &s) {
|
||||||
if (daemon_) {
|
if (daemon_) {
|
||||||
std::cout << "Not able to read password when started as daemon."
|
std::cout << "Not able to read password when started as daemon." << std::endl;
|
||||||
<< std::endl;
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
termios oldt;
|
termios oldt;
|
||||||
|
|
@ -135,7 +142,7 @@ void clib::pclsync_lib::do_get_pass_from_console(std::string &password) {
|
||||||
newt.c_lflag &= ~ECHO;
|
newt.c_lflag &= ~ECHO;
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||||
std::cout << "Please, enter password" << std::endl;
|
std::cout << "Please, enter password" << std::endl;
|
||||||
getline(std::cin, password);
|
getline(std::cin, s);
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,21 +208,22 @@ void event_handler(psync_eventtype_t event, psync_eventdata_t eventdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lib_setup_cripto() {
|
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) {
|
if(pstatus_get(PSTATUS_TYPE_ONLINE) == PSTATUS_ONLINE_OFFLINE) {
|
||||||
std::cout << "Cannot unlock crypto folder, pcloudcc is offline" << std::endl;
|
std::cout << "Cannot unlock crypto folder, pcloudcc is offline" << std::endl;
|
||||||
return PSYNC_CRYPTO_CANT_CONNECT;
|
return PSYNC_CRYPTO_CANT_CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *pwd = clib::pclsync_lib::get_lib().get_crypto_pass().c_str();
|
||||||
if(!pcryptofolder_issetup()) {
|
if(!pcryptofolder_issetup()) {
|
||||||
std::cout << "crypto is not setup, setting it up now..." << std::endl;
|
std::cout << "crypto is not setup, setting it up now..." << std::endl;
|
||||||
if(int ret = pcryptofolder_setup(pwd, "no hint") != PSYNC_CRYPTO_SETUP_SUCCESS) {
|
if(int ret = pcryptofolder_setup(pwd, "no hint") != PSYNC_CRYPTO_SETUP_SUCCESS) {
|
||||||
std::cout << "crypto setup failed, error code was " << ret << std::endl;
|
std::cout << "crypto setup failed, error code was " << ret << std::endl;
|
||||||
|
clib::pclsync_lib::get_lib().wipe_crypto_pass();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if(int ret = pcryptofolder_mkdir(0, "Crypto", NULL, NULL) != PSYNC_CRYPTO_SUCCESS) {
|
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;
|
std::cout << "failed to create crypto directory, error code was" << ret << std::endl;
|
||||||
|
clib::pclsync_lib::get_lib().wipe_crypto_pass();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
std::cout << "crypto folder was setup using the provided password, "
|
std::cout << "crypto folder was setup using the provided password, "
|
||||||
|
|
@ -225,9 +233,11 @@ static int lib_setup_cripto() {
|
||||||
|
|
||||||
if(int ret = pcryptofolder_unlock(pwd) != PSYNC_CRYPTO_START_SUCCESS) {
|
if(int ret = pcryptofolder_unlock(pwd) != PSYNC_CRYPTO_START_SUCCESS) {
|
||||||
std::cout << "Failed to unlock crypto folder: error code was " << ret << std::endl;
|
std::cout << "Failed to unlock crypto folder: error code was " << ret << std::endl;
|
||||||
|
clib::pclsync_lib::get_lib().wipe_crypto_pass();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clib::pclsync_lib::get_lib().wipe_crypto_pass();
|
||||||
clib::pclsync_lib::get_lib().crypto_on_ = true;
|
clib::pclsync_lib::get_lib().crypto_on_ = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -286,7 +296,7 @@ static void status_change(pstatus_t *status) {
|
||||||
*clib::pclsync_lib::get_lib().status_ = *status;
|
*clib::pclsync_lib::get_lib().status_ = *status;
|
||||||
if (status->status == PSTATUS_LOGIN_REQUIRED) {
|
if (status->status == PSTATUS_LOGIN_REQUIRED) {
|
||||||
if (clib::pclsync_lib::get_lib().get_password().empty()) {
|
if (clib::pclsync_lib::get_lib().get_password().empty()) {
|
||||||
clib::pclsync_lib::get_lib().get_pass_from_console();
|
clib::pclsync_lib::get_lib().read_password();
|
||||||
}
|
}
|
||||||
|
|
||||||
psync_set_user_pass(clib::pclsync_lib::get_lib().get_username().c_str(),
|
psync_set_user_pass(clib::pclsync_lib::get_lib().get_username().c_str(),
|
||||||
|
|
@ -295,7 +305,7 @@ static void status_change(pstatus_t *status) {
|
||||||
std::cout << "logging in" << std::endl;
|
std::cout << "logging in" << std::endl;
|
||||||
} else if (status->status == PSTATUS_TFA_REQUIRED) {
|
} else if (status->status == PSTATUS_TFA_REQUIRED) {
|
||||||
if (clib::pclsync_lib::get_lib().get_tfa_code().empty()) {
|
if (clib::pclsync_lib::get_lib().get_tfa_code().empty()) {
|
||||||
clib::pclsync_lib::get_lib().get_tfa_code_from_console();
|
clib::pclsync_lib::get_lib().read_tfa_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
psync_tfa_set_code(clib::pclsync_lib::get_lib().get_tfa_code().c_str(),
|
psync_tfa_set_code(clib::pclsync_lib::get_lib().get_tfa_code().c_str(),
|
||||||
|
|
@ -303,7 +313,7 @@ static void status_change(pstatus_t *status) {
|
||||||
0);
|
0);
|
||||||
} else if (status->status == PSTATUS_BAD_LOGIN_DATA) {
|
} else if (status->status == PSTATUS_BAD_LOGIN_DATA) {
|
||||||
if (!clib::pclsync_lib::get_lib().newuser_) {
|
if (!clib::pclsync_lib::get_lib().newuser_) {
|
||||||
clib::pclsync_lib::get_lib().get_pass_from_console();
|
clib::pclsync_lib::get_lib().read_password();
|
||||||
psync_set_user_pass(clib::pclsync_lib::get_lib().get_username().c_str(),
|
psync_set_user_pass(clib::pclsync_lib::get_lib().get_username().c_str(),
|
||||||
clib::pclsync_lib::get_lib().get_password().c_str(),
|
clib::pclsync_lib::get_lib().get_password().c_str(),
|
||||||
(int)clib::pclsync_lib::get_lib().save_pass_);
|
(int)clib::pclsync_lib::get_lib().save_pass_);
|
||||||
|
|
@ -470,22 +480,33 @@ int clib::pclsync_lib::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::login(const char *user, const char *pass, int save) {
|
int clib::pclsync_lib::login(const char *user, const char *pass, int save) {
|
||||||
set_username(user);
|
username_ = user;
|
||||||
set_password(pass);
|
password_ = pass;
|
||||||
set_savepass(bool(save));
|
save_pass_ = save;
|
||||||
psync_set_user_pass(user, pass, save);
|
psync_set_user_pass(user, pass, save);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::logout() {
|
int clib::pclsync_lib::logout() {
|
||||||
set_password("");
|
wipe_password();
|
||||||
psync_logout();
|
psync_logout(PSTATUS_AUTH_REQUIRED, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::unlink() {
|
int clib::pclsync_lib::unlink() {
|
||||||
set_username("");
|
set_username("");
|
||||||
set_password("");
|
wipe_password();
|
||||||
psync_unlink();
|
psync_unlink();
|
||||||
return 0;
|
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();
|
||||||
|
}
|
||||||
|
|
@ -68,7 +68,6 @@ public:
|
||||||
void set_trusted_device(bool arg);
|
void set_trusted_device(bool arg);
|
||||||
void set_tfa_code(const std::string& arg);
|
void set_tfa_code(const std::string& arg);
|
||||||
void set_username(const std::string &arg);
|
void set_username(const std::string &arg);
|
||||||
void set_password(const std::string &arg);
|
|
||||||
void set_crypto_pass(const std::string &arg);
|
void set_crypto_pass(const std::string &arg);
|
||||||
void set_mount(const std::string &arg);
|
void set_mount(const std::string &arg);
|
||||||
void set_savepass(bool s);
|
void set_savepass(bool s);
|
||||||
|
|
@ -77,13 +76,19 @@ public:
|
||||||
void set_daemon(bool p);
|
void set_daemon(bool p);
|
||||||
void set_status_callback(status_callback_t 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
|
// Singleton
|
||||||
static pclsync_lib &get_lib();
|
static pclsync_lib &get_lib();
|
||||||
|
|
||||||
// Console
|
// Console
|
||||||
void get_tfa_code_from_console();
|
void read_tfa_code();
|
||||||
void get_pass_from_console();
|
void read_password();
|
||||||
void get_cryptopass_from_console();
|
void read_cryptopass();
|
||||||
|
|
||||||
// API calls
|
// API calls
|
||||||
int init();
|
int init();
|
||||||
|
|
@ -103,16 +108,17 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string username_;
|
std::string username_;
|
||||||
std::string password_;
|
std::string password_; // SENSITIVE, use wipe function
|
||||||
std::string tfa_code_;
|
std::string tfa_code_; // SENSITIVE, use wipe function
|
||||||
std::string crypto_pass_;
|
std::string crypto_pass_; // SENSITIVE, use wipe function
|
||||||
std::string mount_;
|
std::string mount_;
|
||||||
|
|
||||||
|
|
||||||
bool to_set_mount_;
|
bool to_set_mount_;
|
||||||
bool daemon_;
|
bool daemon_;
|
||||||
|
|
||||||
void do_get_pass_from_console(std::string &password);
|
void read_from_stdin(std::string &s);
|
||||||
|
void wipe(std::string& s);
|
||||||
};
|
};
|
||||||
} // namespace clibrary
|
} // namespace clibrary
|
||||||
} // namespace console_client
|
} // namespace console_client
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "rpcclient.h"
|
#include "rpcclient.h"
|
||||||
#include "plibs.h"
|
#include "plibs.h"
|
||||||
#include "prpc.h"
|
#include "prpc.h"
|
||||||
|
#include "putil.h"
|
||||||
|
|
||||||
|
|
||||||
#define POVERLAY_BUFSIZE 512
|
#define POVERLAY_BUFSIZE 512
|
||||||
|
|
@ -97,12 +98,12 @@ int RpcClient::writeRequest(int fd, int msgtype, const char *value, char **out,
|
||||||
writeerr = POVERLAY_WRITE_COMM_ERR;
|
writeerr = POVERLAY_WRITE_COMM_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
putil_wipe(buf, size);
|
||||||
free(buf);
|
free(buf);
|
||||||
return writeerr;
|
return writeerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RpcClient::readResponse(int fd, char **out, size_t *out_size) {
|
int RpcClient::readResponse(int fd, char **out, size_t *out_size) {
|
||||||
|
|
||||||
rpc_message_t *msg = (rpc_message_t *)malloc(POVERLAY_BUFSIZE);
|
rpc_message_t *msg = (rpc_message_t *)malloc(POVERLAY_BUFSIZE);
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
const char *error_msg = "Memory allocation failed";
|
const char *error_msg = "Memory allocation failed";
|
||||||
|
|
@ -116,6 +117,7 @@ int RpcClient::readResponse(int fd, char **out, size_t *out_size) {
|
||||||
const char *error_msg = (bytes_read == 0) ? "Connection closed" : "Read error";
|
const char *error_msg = (bytes_read == 0) ? "Connection closed" : "Read error";
|
||||||
*out = strdup(error_msg);
|
*out = strdup(error_msg);
|
||||||
*out_size = strlen(error_msg) + 1;
|
*out_size = strlen(error_msg) + 1;
|
||||||
|
putil_wipe(msg, POVERLAY_BUFSIZE);
|
||||||
free(msg);
|
free(msg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -124,6 +126,7 @@ int RpcClient::readResponse(int fd, char **out, size_t *out_size) {
|
||||||
memcpy(*out, msg->value, msg->length);
|
memcpy(*out, msg->value, msg->length);
|
||||||
*out_size = msg->length;
|
*out_size = msg->length;
|
||||||
|
|
||||||
|
putil_wipe(msg, POVERLAY_BUFSIZE);
|
||||||
free(msg);
|
free(msg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue