From d6415277d003d2dbb5d4f3b580019f13d9d95b27 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Fri, 4 Aug 2017 09:36:03 -0400 Subject: [PATCH] Wrap up error handling overhaul. --- core/c/mpw-algorithm.c | 6 +-- core/c/mpw-algorithm_v0.c | 10 ++--- core/c/mpw-algorithm_v1.c | 10 ++--- core/c/mpw-algorithm_v2.c | 10 ++--- core/c/mpw-algorithm_v3.c | 10 ++--- core/c/mpw-marshall.c | 21 +++++++--- core/c/mpw-types.c | 36 ++++++++--------- core/c/mpw-util.c | 4 +- core/c/mpw-util.h | 9 +++++ platform-independent/cli-c/cli/mpw-cli.c | 39 ++++++++++++------- .../cli-c/cli/mpw-tests-util.c | 2 +- platform-independent/cli-c/cli/mpw-tests.c | 4 +- 12 files changed, 96 insertions(+), 65 deletions(-) diff --git a/core/c/mpw-algorithm.c b/core/c/mpw-algorithm.c index 678eba57..284fe703 100644 --- a/core/c/mpw-algorithm.c +++ b/core/c/mpw-algorithm.c @@ -37,7 +37,7 @@ MPMasterKey mpw_masterKey(const char *fullName, const char *masterPassword, cons case MPAlgorithmVersion3: return mpw_masterKeyForUser_v3( fullName, masterPassword ); default: - ftl( "Unsupported version: %d", algorithmVersion ); + err( "Unsupported version: %d\n", algorithmVersion ); return NULL; } } @@ -59,7 +59,7 @@ MPSiteKey mpw_siteKey( case MPAlgorithmVersion3: return mpw_siteKey_v3( masterKey, siteName, siteCounter, keyPurpose, keyContext ); default: - ftl( "Unsupported version: %d", algorithmVersion ); + err( "Unsupported version: %d\n", algorithmVersion ); return NULL; } } @@ -80,7 +80,7 @@ const char *mpw_sitePassword( case MPAlgorithmVersion3: return mpw_sitePassword_v3( siteKey, passwordType ); default: - ftl( "Unsupported version: %d", algorithmVersion ); + err( "Unsupported version: %d\n", algorithmVersion ); return NULL; } } diff --git a/core/c/mpw-algorithm_v0.c b/core/c/mpw-algorithm_v0.c index 7c6e78cf..ab6263f2 100644 --- a/core/c/mpw-algorithm_v0.c +++ b/core/c/mpw-algorithm_v0.c @@ -61,7 +61,7 @@ static MPMasterKey mpw_masterKeyForUser_v0(const char *fullName, const char *mas mpw_push_int( &masterKeySalt, &masterKeySaltSize, htonl( mpw_utf8_strlen( fullName ) ) ); mpw_push_string( &masterKeySalt, &masterKeySaltSize, fullName ); if (!masterKeySalt) { - ftl( "Could not allocate master key salt: %s\n", strerror( errno ) ); + err( "Could not allocate master key salt: %s\n", strerror( errno ) ); return NULL; } trc( "masterKeySalt ID: %s\n", mpw_id_buf( masterKeySalt, masterKeySaltSize ) ); @@ -71,7 +71,7 @@ static MPMasterKey mpw_masterKeyForUser_v0(const char *fullName, const char *mas const uint8_t *masterKey = mpw_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); mpw_free( masterKeySalt, masterKeySaltSize ); if (!masterKey) { - ftl( "Could not allocate master key: %s\n", strerror( errno ) ); + err( "Could not allocate master key: %s\n", strerror( errno ) ); return NULL; } trc( "masterKey ID: %s\n", mpw_id_buf( masterKey, MPMasterKeySize ) ); @@ -107,7 +107,7 @@ static MPSiteKey mpw_siteKey_v0( mpw_push_string( &siteSalt, &siteSaltSize, keyContext ); } if (!siteSalt || !siteSaltSize) { - ftl( "Could not allocate site salt: %s\n", strerror( errno ) ); + err( "Could not allocate site salt: %s\n", strerror( errno ) ); mpw_free( siteSalt, siteSaltSize ); return NULL; } @@ -116,7 +116,7 @@ static MPSiteKey mpw_siteKey_v0( MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); mpw_free( siteSalt, siteSaltSize ); if (!siteKey) { - ftl( "Could not allocate site key: %s\n", strerror( errno ) ); + err( "Could not allocate site key: %s\n", strerror( errno ) ); return NULL; } trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) ); @@ -137,7 +137,7 @@ static const char *mpw_sitePassword_v0( if (!template) return NULL; if (strlen( template ) > MPSiteKeySize) { - ftl( "Template too long for password seed: %lu", strlen( template ) ); + err( "Template too long for password seed: %lu\n", strlen( template ) ); return NULL; } diff --git a/core/c/mpw-algorithm_v1.c b/core/c/mpw-algorithm_v1.c index cad3cc3b..34f9a713 100644 --- a/core/c/mpw-algorithm_v1.c +++ b/core/c/mpw-algorithm_v1.c @@ -43,7 +43,7 @@ static MPMasterKey mpw_masterKeyForUser_v1(const char *fullName, const char *mas mpw_push_int( &masterKeySalt, &masterKeySaltSize, htonl( mpw_utf8_strlen( fullName ) ) ); mpw_push_string( &masterKeySalt, &masterKeySaltSize, fullName ); if (!masterKeySalt) { - ftl( "Could not allocate master key salt: %s\n", strerror( errno ) ); + err( "Could not allocate master key salt: %s\n", strerror( errno ) ); return NULL; } trc( "masterKeySalt ID: %s\n", mpw_id_buf( masterKeySalt, masterKeySaltSize ) ); @@ -53,7 +53,7 @@ static MPMasterKey mpw_masterKeyForUser_v1(const char *fullName, const char *mas MPMasterKey masterKey = mpw_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); mpw_free( masterKeySalt, masterKeySaltSize ); if (!masterKey) { - ftl( "Could not allocate master key: %s\n", strerror( errno ) ); + err( "Could not allocate master key: %s\n", strerror( errno ) ); return NULL; } trc( "masterKey ID: %s\n", mpw_id_buf( masterKey, MPMasterKeySize ) ); @@ -89,7 +89,7 @@ static MPSiteKey mpw_siteKey_v1( mpw_push_string( &siteSalt, &siteSaltSize, keyContext ); } if (!siteSalt || !siteSaltSize) { - ftl( "Could not allocate site salt: %s\n", strerror( errno ) ); + err( "Could not allocate site salt: %s\n", strerror( errno ) ); mpw_free( siteSalt, siteSaltSize ); return NULL; } @@ -98,7 +98,7 @@ static MPSiteKey mpw_siteKey_v1( MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); mpw_free( siteSalt, siteSaltSize ); if (!siteKey) { - ftl( "Could not allocate site key: %s\n", strerror( errno ) ); + err( "Could not allocate site key: %s\n", strerror( errno ) ); return NULL; } trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) ); @@ -118,7 +118,7 @@ static const char *mpw_sitePassword_v1( if (!template) return NULL; if (strlen( template ) > MPSiteKeySize) { - ftl( "Template too long for password seed: %lu", strlen( template ) ); + err( "Template too long for password seed: %lu\n", strlen( template ) ); return NULL; } diff --git a/core/c/mpw-algorithm_v2.c b/core/c/mpw-algorithm_v2.c index 9acedc0b..23de9419 100644 --- a/core/c/mpw-algorithm_v2.c +++ b/core/c/mpw-algorithm_v2.c @@ -43,7 +43,7 @@ static MPMasterKey mpw_masterKeyForUser_v2(const char *fullName, const char *mas mpw_push_int( &masterKeySalt, &masterKeySaltSize, htonl( mpw_utf8_strlen( fullName ) ) ); mpw_push_string( &masterKeySalt, &masterKeySaltSize, fullName ); if (!masterKeySalt) { - ftl( "Could not allocate master key salt: %s\n", strerror( errno ) ); + err( "Could not allocate master key salt: %s\n", strerror( errno ) ); return NULL; } trc( "masterKeySalt ID: %s\n", mpw_id_buf( masterKeySalt, masterKeySaltSize ) ); @@ -53,7 +53,7 @@ static MPMasterKey mpw_masterKeyForUser_v2(const char *fullName, const char *mas const uint8_t *masterKey = mpw_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); mpw_free( masterKeySalt, masterKeySaltSize ); if (!masterKey) { - ftl( "Could not allocate master key: %s\n", strerror( errno ) ); + err( "Could not allocate master key: %s\n", strerror( errno ) ); return NULL; } trc( "masterKey ID: %s\n", mpw_id_buf( masterKey, MPMasterKeySize ) ); @@ -89,7 +89,7 @@ static MPSiteKey mpw_siteKey_v2( mpw_push_string( &siteSalt, &siteSaltSize, keyContext ); } if (!siteSalt || !siteSaltSize) { - ftl( "Could not allocate site salt: %s\n", strerror( errno ) ); + err( "Could not allocate site salt: %s\n", strerror( errno ) ); mpw_free( siteSalt, siteSaltSize ); return NULL; } @@ -98,7 +98,7 @@ static MPSiteKey mpw_siteKey_v2( const uint8_t *siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); mpw_free( siteSalt, siteSaltSize ); if (!siteKey) { - ftl( "Could not allocate site key: %s\n", strerror( errno ) ); + err( "Could not allocate site key: %s\n", strerror( errno ) ); return NULL; } trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) ); @@ -118,7 +118,7 @@ static const char *mpw_sitePassword_v2( if (!template) return NULL; if (strlen( template ) > MPSiteKeySize) { - ftl( "Template too long for password seed: %lu", strlen( template ) ); + err( "Template too long for password seed: %lu\n", strlen( template ) ); return NULL; } diff --git a/core/c/mpw-algorithm_v3.c b/core/c/mpw-algorithm_v3.c index cc8578b5..ae5722e0 100644 --- a/core/c/mpw-algorithm_v3.c +++ b/core/c/mpw-algorithm_v3.c @@ -43,7 +43,7 @@ static MPMasterKey mpw_masterKeyForUser_v3(const char *fullName, const char *mas mpw_push_int( &masterKeySalt, &masterKeySaltSize, htonl( strlen( fullName ) ) ); mpw_push_string( &masterKeySalt, &masterKeySaltSize, fullName ); if (!masterKeySalt) { - ftl( "Could not allocate master key salt: %s\n", strerror( errno ) ); + err( "Could not allocate master key salt: %s\n", strerror( errno ) ); return NULL; } trc( "masterKeySalt ID: %s\n", mpw_id_buf( masterKeySalt, masterKeySaltSize ) ); @@ -53,7 +53,7 @@ static MPMasterKey mpw_masterKeyForUser_v3(const char *fullName, const char *mas const uint8_t *masterKey = mpw_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); mpw_free( masterKeySalt, masterKeySaltSize ); if (!masterKey) { - ftl( "Could not allocate master key: %s\n", strerror( errno ) ); + err( "Could not allocate master key: %s\n", strerror( errno ) ); return NULL; } trc( "masterKey ID: %s\n", mpw_id_buf( masterKey, MPMasterKeySize ) ); @@ -89,7 +89,7 @@ static MPSiteKey mpw_siteKey_v3( mpw_push_string( &siteSalt, &siteSaltSize, keyContext ); } if (!siteSalt) { - ftl( "Could not allocate site salt: %s\n", strerror( errno ) ); + err( "Could not allocate site salt: %s\n", strerror( errno ) ); return NULL; } trc( "siteSalt ID: %s\n", mpw_id_buf( siteSalt, siteSaltSize ) ); @@ -97,7 +97,7 @@ static MPSiteKey mpw_siteKey_v3( MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); mpw_free( siteSalt, siteSaltSize ); if (!siteKey || !siteSaltSize) { - ftl( "Could not allocate site key: %s\n", strerror( errno ) ); + err( "Could not allocate site key: %s\n", strerror( errno ) ); mpw_free( siteSalt, siteSaltSize ); return NULL; } @@ -118,7 +118,7 @@ static const char *mpw_sitePassword_v3( if (!template) return NULL; if (strlen( template ) > MPSiteKeySize) { - ftl( "Template too long for password seed: %lu", strlen( template ) ); + err( "Template too long for password seed: %lu\n", strlen( template ) ); return NULL; } diff --git a/core/c/mpw-marshall.c b/core/c/mpw-marshall.c index dbb2bc6e..a9d62a2a 100644 --- a/core/c/mpw-marshall.c +++ b/core/c/mpw-marshall.c @@ -469,7 +469,13 @@ static MPMarshalledUser *mpw_marshall_read_flat( *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %s", siteName, str_type ) }; return NULL; } - int value = atoi( str_algorithm ); + long long int value = atoll( str_counter ); + if (value < 0 || value > UINT32_MAX) { + *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site counter: %s: %s", siteName, str_counter ) }; + return NULL; + } + uint32_t siteCounter = (uint32_t)value; + value = atoll( str_algorithm ); if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast) { *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site algorithm: %s: %s", siteName, str_algorithm ) }; return NULL; @@ -482,7 +488,7 @@ static MPMarshalledUser *mpw_marshall_read_flat( } MPMarshalledSite *site = mpw_marshall_site( - user, siteName, siteType, (uint32_t)atoi( str_counter ), siteAlgorithm ); + user, siteName, siteType, siteCounter, siteAlgorithm ); if (!site) { *error = (MPMarshallError){ MPMarshallErrorInternal, "Couldn't allocate a new site." }; return NULL; @@ -561,7 +567,7 @@ static MPMarshalledUser *mpw_marshall_read_json( const char *fullName = mpw_get_json_string( json_file, "user.full_name", NULL ); const char *str_lastUsed = mpw_get_json_string( json_file, "user.last_used", NULL ); const char *keyID = mpw_get_json_string( json_file, "user.key_id", NULL ); - int value = mpw_get_json_int( json_file, "user.algorithm", MPAlgorithmVersionCurrent ); + int32_t value = mpw_get_json_int( json_file, "user.algorithm", MPAlgorithmVersionCurrent ); if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast) { *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid user algorithm version: %u", value ) }; return NULL; @@ -605,7 +611,7 @@ static MPMarshalledUser *mpw_marshall_read_json( const char *siteName = json_site.key; value = mpw_get_json_int( json_site.val, "algorithm", (int)user->algorithm ); if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast) { - *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site algorithm version: %s: %u", siteName, value ) }; + *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site algorithm version: %s: %d", siteName, value ) }; return NULL; } MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)value; @@ -614,7 +620,12 @@ static MPMarshalledUser *mpw_marshall_read_json( *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %u", siteName, siteType ) }; return NULL; } - uint32_t siteCounter = (uint32_t)mpw_get_json_int( json_site.val, "counter", 1 ); + value = mpw_get_json_int( json_site.val, "counter", 1 ); + if (value < 0 || value > UINT32_MAX) { + *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site counter: %s: %d", siteName, value ) }; + return NULL; + } + uint32_t siteCounter = (uint32_t)value; const char *siteContent = mpw_get_json_string( json_site.val, "password", NULL ); const char *siteLoginName = mpw_get_json_string( json_site.val, "login_name", NULL ); bool siteLoginGenerated = mpw_get_json_boolean( json_site.val, "login_generated", false ); diff --git a/core/c/mpw-types.c b/core/c/mpw-types.c index 87c422b9..67251dc8 100644 --- a/core/c/mpw-types.c +++ b/core/c/mpw-types.c @@ -42,33 +42,33 @@ const MPPasswordType mpw_typeWithName(const char *typeName) { stdTypeName[stdTypeNameSize] = '\0'; // Find what password type is represented by the type name. - if (0 == strncmp( "x", stdTypeName, 1 ) + if (0 == strcmp( "x", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedMaximum ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedMaximum; - if (0 == strncmp( "l", stdTypeName, 1 ) + if (0 == strcmp( "l", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedLong ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedLong; - if (0 == strncmp( "m", stdTypeName, 1 ) + if (0 == strcmp( "m", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedMedium ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedMedium; - if (0 == strncmp( "b", stdTypeName, 1 ) + if (0 == strcmp( "b", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedBasic ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedBasic; - if (0 == strncmp( "s", stdTypeName, 1 ) + if (0 == strcmp( "s", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedShort ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedShort; - if (0 == strncmp( "i", stdTypeName, 1 ) + if (0 == strcmp( "i", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedPIN ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedPIN; - if (0 == strncmp( "n", stdTypeName, 1 ) + if (0 == strcmp( "n", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedName ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedName; - if (0 == strncmp( "p", stdTypeName, 1 ) + if (0 == strcmp( "p", stdTypeName ) || strncmp( mpw_nameForType( MPPasswordTypeGeneratedPhrase ), stdTypeName, strlen( stdTypeName ) ) == 0) return MPPasswordTypeGeneratedPhrase; - ftl( "Not a generated type name: %s", stdTypeName ); - return MPPasswordTypeDefault; + dbg( "Not a generated type name: %s\n", stdTypeName ); + return (MPPasswordType)ERR; } const char *mpw_nameForType(MPPasswordType passwordType) { @@ -95,7 +95,7 @@ const char *mpw_nameForType(MPPasswordType passwordType) { case MPPasswordTypeStoredDevice: return "device"; default: { - ftl( "Unknown password type: %d", passwordType ); + dbg( "Unknown password type: %d\n", passwordType ); return NULL; } } @@ -104,7 +104,7 @@ const char *mpw_nameForType(MPPasswordType passwordType) { const char **mpw_templatesForType(MPPasswordType type, size_t *count) { if (!(type & MPPasswordTypeClassGenerated)) { - ftl( "Not a generated type: %d", type ); + dbg( "Not a generated type: %d\n", type ); return NULL; } @@ -140,7 +140,7 @@ const char **mpw_templatesForType(MPPasswordType type, size_t *count) { return mpw_alloc_array( count, const char *, "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" ); default: { - ftl( "Unknown generated type: %d", type ); + dbg( "Unknown generated type: %d\n", type ); return NULL; } } @@ -172,8 +172,8 @@ const MPKeyPurpose mpw_purposeWithName(const char *purposeName) { if (strncmp( mpw_nameForPurpose( MPKeyPurposeRecovery ), stdPurposeName, strlen( stdPurposeName ) ) == 0) return MPKeyPurposeRecovery; - ftl( "Not a purpose name: %s", stdPurposeName ); - return MPKeyPurposeAuthentication; + dbg( "Not a purpose name: %s\n", stdPurposeName ); + return (MPKeyPurpose)ERR; } const char *mpw_nameForPurpose(MPKeyPurpose purpose) { @@ -186,7 +186,7 @@ const char *mpw_nameForPurpose(MPKeyPurpose purpose) { case MPKeyPurposeRecovery: return "recovery"; default: { - ftl( "Unknown purpose: %d", purpose ); + dbg( "Unknown purpose: %d\n", purpose ); return NULL; } } @@ -202,7 +202,7 @@ const char *mpw_scopeForPurpose(MPKeyPurpose purpose) { case MPKeyPurposeRecovery: return "com.lyndir.masterpassword.answer"; default: { - ftl( "Unknown purpose: %d", purpose ); + dbg( "Unknown purpose: %d\n", purpose ); return NULL; } } @@ -232,7 +232,7 @@ const char *mpw_charactersInClass(char characterClass) { case ' ': return " "; default: { - ftl( "Unknown character class: %c", characterClass ); + dbg( "Unknown character class: %c\n", characterClass ); return NULL; } } diff --git a/core/c/mpw-util.c b/core/c/mpw-util.c index 2c4eb974..f9d4729e 100644 --- a/core/c/mpw-util.c +++ b/core/c/mpw-util.c @@ -40,7 +40,7 @@ bool mpw_push_buf(uint8_t **const buffer, size_t *const bufferSize, const void * if (!buffer || !bufferSize || !pushBuffer || !pushSize) return false; - if (*bufferSize == (size_t)-1) + if (*bufferSize == ERR) // The buffer was marked as broken, it is missing a previous push. Abort to avoid corrupt content. return false; @@ -49,7 +49,7 @@ bool mpw_push_buf(uint8_t **const buffer, size_t *const bufferSize, const void * if (!resizedBuffer) { // realloc failed, we can't push. Mark the buffer as broken. mpw_free( *buffer, *bufferSize - pushSize ); - *bufferSize = (size_t)-1; + *bufferSize = (size_t)ERR; *buffer = NULL; return false; } diff --git a/core/c/mpw-util.h b/core/c/mpw-util.h index 1353df9a..3f68d42b 100644 --- a/core/c/mpw-util.h +++ b/core/c/mpw-util.h @@ -29,36 +29,42 @@ #ifndef trc extern int mpw_verbosity; #define trc_level 3 +/** Logging internal state. */ #define trc(...) ({ \ if (mpw_verbosity >= 3) \ fprintf( stderr, __VA_ARGS__ ); }) #endif #ifndef dbg #define dbg_level 2 +/** Logging state and events interesting when investigating issues. */ #define dbg(...) ({ \ if (mpw_verbosity >= 2) \ fprintf( stderr, __VA_ARGS__ ); }) #endif #ifndef inf #define inf_level 1 +/** User messages. */ #define inf(...) ({ \ if (mpw_verbosity >= 1) \ fprintf( stderr, __VA_ARGS__ ); }) #endif #ifndef wrn #define wrn_level 0 +/** Recoverable issues and user suggestions. */ #define wrn(...) ({ \ if (mpw_verbosity >= 0) \ fprintf( stderr, __VA_ARGS__ ); }) #endif #ifndef err #define err_level -1 +/** Unrecoverable issues. */ #define err(...) ({ \ if (mpw_verbosity >= -1) \ fprintf( stderr, __VA_ARGS__ ); }) #endif #ifndef ftl #define ftl_level -2 +/** Issues that lead to abortion. */ #define ftl(...) ({ \ if (mpw_verbosity >= -2) \ fprintf( stderr, __VA_ARGS__ ); }) @@ -76,6 +82,9 @@ extern int mpw_verbosity; __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) #endif +#ifndef ERR +#define ERR -1 +#endif //// Buffers and memory. diff --git a/platform-independent/cli-c/cli/mpw-cli.c b/platform-independent/cli-c/cli/mpw-cli.c index 8c6ca074..426520ac 100644 --- a/platform-independent/cli-c/cli/mpw-cli.c +++ b/platform-independent/cli-c/cli/mpw-cli.c @@ -119,7 +119,7 @@ int main(int argc, char *const argv[]) { const char *algorithmVersionArg = getenv( MP_env_algorithm ); // Read the command-line options. - for (int opt; (opt = getopt( argc, argv, "u:P:t:c:V:a:C:vqh" )) != -1;) + for (int opt; (opt = getopt( argc, argv, "u:P:t:c:V:a:C:vqh" )) != EOF;) switch (opt) { case 'u': fullNameArg = optarg; @@ -168,7 +168,7 @@ int main(int argc, char *const argv[]) { return EX_USAGE; } default: - ftl( "Unexpected option: %c", opt ); + ftl( "Unexpected option: %c\n", opt ); return EX_USAGE; } if (optind < argc) @@ -221,7 +221,7 @@ int main(int argc, char *const argv[]) { (bufPointer += (readSize = fread( buf + bufPointer, 1, readAmount, mpwSites ))) && (readSize == readAmount)); if (ferror( mpwSites )) - wrn( "Error while reading configuration file:\n %s: %d", mpwSitesPath, ferror( mpwSites ) ); + wrn( "Error while reading configuration file:\n %s: %d\n", mpwSitesPath, ferror( mpwSites ) ); fclose( mpwSites ); // Parse file. @@ -232,7 +232,8 @@ int main(int argc, char *const argv[]) { if (marshallError.type == MPMarshallErrorMasterPassword) { ftl( "Incorrect master password according to configuration:\n %s: %s\n", mpwSitesPath, marshallError.description ); return EX_DATAERR; - } else + } + else err( "Couldn't parse configuration file:\n %s: %s\n", mpwSitesPath, marshallError.description ); } @@ -263,7 +264,7 @@ int main(int argc, char *const argv[]) { else { buf = NULL; if (!mpw_marshall_write( &buf, MPMarshallFormatJSON, user, &marshallError ) || marshallError.type != MPMarshallSuccess) - wrn( "Couldn't encode updated configuration file:\n %s: %s", mpwSitesPath, marshallError.description ); + wrn( "Couldn't encode updated configuration file:\n %s: %s\n", mpwSitesPath, marshallError.description ); else if (fwrite( buf, sizeof( char ), strlen( buf ), mpwSites ) != strlen( buf )) wrn( "Error while writing updated configuration file:\n %s: %d\n", mpwSitesPath, ferror( mpwSites ) ); @@ -278,7 +279,7 @@ int main(int argc, char *const argv[]) { free( mpwSitesPath ); // Parse default/config-overriding command-line parameters. - if (algorithmVersionArg) { + if (algorithmVersionArg && strlen( algorithmVersionArg )) { int algorithmVersionInt = atoi( algorithmVersionArg ); if (algorithmVersionInt < MPAlgorithmVersionFirst || algorithmVersionInt > MPAlgorithmVersionLast) { ftl( "Invalid algorithm version: %s\n", algorithmVersionArg ); @@ -286,7 +287,7 @@ int main(int argc, char *const argv[]) { } algorithmVersion = (MPAlgorithmVersion)algorithmVersionInt; } - if (siteCounterArg) { + if (siteCounterArg && strlen( siteCounterArg )) { long long int siteCounterInt = atoll( siteCounterArg ); if (siteCounterInt < 0 || siteCounterInt > UINT32_MAX) { ftl( "Invalid site counter: %s\n", siteCounterArg ); @@ -294,15 +295,25 @@ int main(int argc, char *const argv[]) { } siteCounter = (uint32_t)siteCounterInt; } - if (keyPurposeArg) - keyPurpose = mpw_purposeWithName( keyPurposeArg ); // TODO: error check + if (keyPurposeArg && strlen( keyPurposeArg )) { + keyPurpose = mpw_purposeWithName( keyPurposeArg ); + if (ERR == keyPurpose) { + ftl( "Invalid purpose: %s\n", keyPurposeArg ); + return EX_USAGE; + } + } if (keyPurpose == MPKeyPurposeIdentification) passwordType = MPPasswordTypeGeneratedName; if (keyPurpose == MPKeyPurposeRecovery) passwordType = MPPasswordTypeGeneratedPhrase; - if (passwordTypeArg) - passwordType = mpw_typeWithName( passwordTypeArg ); // TODO: error check - if (keyContextArg) + if (passwordTypeArg && strlen( passwordTypeArg )) { + passwordType = mpw_typeWithName( passwordTypeArg ); + if (ERR == passwordType) { + ftl( "Invalid type: %s\n", passwordTypeArg ); + return EX_USAGE; + } + } + if (keyContextArg && strlen( keyContextArg )) keyContext = strdup( keyContextArg ); // Summarize operation. @@ -329,7 +340,7 @@ int main(int argc, char *const argv[]) { mpw_free_string( masterPassword ); mpw_free_string( fullName ); if (!masterKey) { - ftl( "Couldn't derive master key." ); + ftl( "Couldn't derive master key.\n" ); return EX_SOFTWARE; } @@ -340,7 +351,7 @@ int main(int argc, char *const argv[]) { mpw_free_string( siteName ); mpw_free_string( keyContext ); if (!sitePassword) { - ftl( "Couldn't derive site password." ); + ftl( "Couldn't derive site password.\n" ); return EX_SOFTWARE; } diff --git a/platform-independent/cli-c/cli/mpw-tests-util.c b/platform-independent/cli-c/cli/mpw-tests-util.c index 9304e604..79828b83 100644 --- a/platform-independent/cli-c/cli/mpw-tests-util.c +++ b/platform-independent/cli-c/cli/mpw-tests-util.c @@ -57,7 +57,7 @@ xmlNodePtr mpw_xmlTestCaseNode(xmlNodePtr testCaseNode, const char *nodeName) { } } - ftl( "Missing parent: %s, for case: %s\n", parentId, mpw_xmlTestCaseString( testCaseNode, "id" ) ); + err( "Missing parent: %s, for case: %s\n", parentId, mpw_xmlTestCaseString( testCaseNode, "id" ) ); return NULL; } diff --git a/platform-independent/cli-c/cli/mpw-tests.c b/platform-independent/cli-c/cli/mpw-tests.c index 9367e8a6..616a5a9d 100644 --- a/platform-independent/cli-c/cli/mpw-tests.c +++ b/platform-independent/cli-c/cli/mpw-tests.c @@ -49,7 +49,7 @@ int main(int argc, char *const argv[]) { MPMasterKey masterKey = mpw_masterKey( (char *)fullName, (char *)masterPassword, algorithm ); if (!masterKey) { - ftl( "Couldn't derive master key." ); + ftl( "Couldn't derive master key.\n" ); continue; } @@ -61,7 +61,7 @@ int main(int argc, char *const argv[]) { mpw_free( masterKey, MPMasterKeySize ); mpw_free( siteKey, MPSiteKeySize ); if (!sitePassword) { - ftl( "Couldn't derive site password." ); + ftl( "Couldn't derive site password.\n" ); continue; }