2
0

Make marshal error messages owned by the file.

Error message lifecycle was limited to the static mpw_str buffer, which
is far too limited and also dangerous.  Own the message by the
MPMarshalFile object, freed in mpw_marshal_file_free.
This commit is contained in:
Maarten Billemont 2020-04-20 17:07:35 -04:00
parent 66dd78797b
commit 694b5ea227
2 changed files with 66 additions and 58 deletions

View File

@ -176,6 +176,21 @@ MPMarshalledFile *mpw_marshal_file(
return file; return file;
} }
MPMarshalledFile *mpw_marshal_error(
MPMarshalledFile *file, MPMarshalErrorType type, const char *format, ...) {
file = mpw_marshal_file( file, NULL, NULL );
if (!file)
return NULL;
va_list args;
va_start( args, format );
file->error = (MPMarshalError){ type, mpw_strdup( mpw_vstr( format, args ) ) };
va_end( args );
return file;
}
void mpw_marshal_info_free( void mpw_marshal_info_free(
MPMarshalledInfo **info) { MPMarshalledInfo **info) {
@ -228,6 +243,7 @@ void mpw_marshal_file_free(
mpw_marshal_info_free( &(*file)->info ); mpw_marshal_info_free( &(*file)->info );
mpw_marshal_data_free( &(*file)->data ); mpw_marshal_data_free( &(*file)->data );
mpw_free_string( &(*file)->error.message );
mpw_free( file, sizeof( MPMarshalledFile ) ); mpw_free( file, sizeof( MPMarshalledFile ) );
} }
@ -539,7 +555,7 @@ static const char *mpw_marshal_write_flat(
const MPMarshalledData *data = file->data; const MPMarshalledData *data = file->data;
if (!data) { if (!data) {
file->error = (MPMarshalError){ MPMarshalErrorMissing, "Missing data." }; mpw_marshal_error( file, MPMarshalErrorMissing, "Missing data." );
return NULL; return NULL;
} }
@ -583,9 +599,9 @@ static const char *mpw_marshal_write_flat(
} }
if (!out) if (!out)
file->error = (MPMarshalError){ MPMarshalErrorFormat, "Couldn't encode JSON." }; mpw_marshal_error( file, MPMarshalErrorFormat, "Couldn't encode JSON." );
else else
file->error = (MPMarshalError){ MPMarshalSuccess, NULL }; mpw_marshal_error( file, MPMarshalSuccess, NULL );
return out; return out;
} }
@ -637,7 +653,7 @@ static const char *mpw_marshal_write_json(
// Section: "export" // Section: "export"
json_object *json_file = mpw_get_json_data( file->data ); json_object *json_file = mpw_get_json_data( file->data );
if (!json_file) { if (!json_file) {
file->error = (MPMarshalError){ MPMarshalErrorFormat, "Couldn't serialize export data." }; mpw_marshal_error( file, MPMarshalErrorFormat, "Couldn't serialize export data." );
return NULL; return NULL;
} }
@ -650,9 +666,9 @@ static const char *mpw_marshal_write_json(
json_object_put( json_file ); json_object_put( json_file );
if (!out) if (!out)
file->error = (MPMarshalError){ MPMarshalErrorFormat, "Couldn't encode JSON." }; mpw_marshal_error( file, MPMarshalErrorFormat, "Couldn't encode JSON." );
else else
file->error = (MPMarshalError){ MPMarshalSuccess, NULL }; mpw_marshal_error( file, MPMarshalSuccess, NULL );
return out; return out;
} }
@ -698,17 +714,17 @@ const char *mpw_marshal_write(
if (!file_) if (!file_)
mpw_marshal_file_free( &file ); mpw_marshal_file_free( &file );
else else
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate data." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't allocate data." );
return NULL; return NULL;
} }
if (!user->fullName || !strlen( user->fullName )) { if (!user->fullName || !strlen( user->fullName )) {
if (!file_) if (!file_)
mpw_marshal_file_free( &file ); mpw_marshal_file_free( &file );
else else
file->error = (MPMarshalError){ MPMarshalErrorMissing, "Missing full name." }; mpw_marshal_error( file, MPMarshalErrorMissing, "Missing full name." );
return NULL; return NULL;
} }
file->error = (MPMarshalError){ MPMarshalSuccess, NULL }; mpw_marshal_error( file, MPMarshalSuccess, NULL );
MPMasterKey masterKey = NULL; MPMasterKey masterKey = NULL;
if (user->masterKeyProvider) if (user->masterKeyProvider)
@ -749,7 +765,7 @@ const char *mpw_marshal_write(
if (!file_) if (!file_)
mpw_marshal_file_free( &file ); mpw_marshal_file_free( &file );
else else
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't derive master key." );
return NULL; return NULL;
} }
@ -807,7 +823,7 @@ const char *mpw_marshal_write(
const char *out = NULL; const char *out = NULL;
switch (outFormat) { switch (outFormat) {
case MPMarshalFormatNone: case MPMarshalFormatNone:
file->error = (MPMarshalError){ MPMarshalSuccess, NULL }; mpw_marshal_error( file, MPMarshalSuccess, NULL );
break; break;
case MPMarshalFormatFlat: case MPMarshalFormatFlat:
out = mpw_marshal_write_flat( file ); out = mpw_marshal_write_flat( file );
@ -818,7 +834,7 @@ const char *mpw_marshal_write(
break; break;
#endif #endif
default: default:
file->error = (MPMarshalError){ MPMarshalErrorFormat, mpw_str( "Unsupported output format: %u", outFormat ) }; mpw_marshal_error( file, MPMarshalErrorFormat, "Unsupported output format: %u", outFormat );
break; break;
} }
if (out && file->error.type == MPMarshalSuccess) if (out && file->error.type == MPMarshalSuccess)
@ -839,7 +855,7 @@ static void mpw_marshal_read_flat(
mpw_marshal_file( file, NULL, mpw_marshal_data_new() ); mpw_marshal_file( file, NULL, mpw_marshal_data_new() );
if (!file->data) { if (!file->data) {
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate data." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't allocate data." );
return; return;
} }
@ -891,10 +907,7 @@ static void mpw_marshal_read_flat(
const char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" ); const char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" );
const char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" ); const char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" );
if (!headerName || !headerValue) { if (!headerName || !headerValue) {
file->error = (MPMarshalError){ mpw_marshal_error( file, MPMarshalErrorStructure, "Invalid header: %s", mpw_strndup( line, (size_t)(endOfLine - line) ) );
MPMarshalErrorStructure,
mpw_str( "Invalid header: %s", mpw_strndup( line, (size_t)(endOfLine - line) ) )
};
mpw_free_strings( &headerName, &headerValue, NULL ); mpw_free_strings( &headerName, &headerValue, NULL );
continue; continue;
} }
@ -908,7 +921,7 @@ static void mpw_marshal_read_flat(
if (mpw_strcasecmp( headerName, "Algorithm" ) == OK) { if (mpw_strcasecmp( headerName, "Algorithm" ) == OK) {
unsigned long value = strtoul( headerValue, NULL, 10 ); unsigned long value = strtoul( headerValue, NULL, 10 );
if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast) if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast)
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user algorithm version: %s", headerValue ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid user algorithm version: %s", headerValue );
else else
algorithm = (MPAlgorithmVersion)value; algorithm = (MPAlgorithmVersion)value;
} }
@ -923,7 +936,7 @@ static void mpw_marshal_read_flat(
if (mpw_strcasecmp( headerName, "Default Type" ) == OK) { if (mpw_strcasecmp( headerName, "Default Type" ) == OK) {
unsigned long value = strtoul( headerValue, NULL, 10 ); unsigned long value = strtoul( headerValue, NULL, 10 );
if (!mpw_type_short_name( (MPResultType)value )) if (!mpw_type_short_name( (MPResultType)value ))
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user default type: %s", headerValue ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid user default type: %s", headerValue );
else else
defaultType = (MPResultType)value; defaultType = (MPResultType)value;
} }
@ -934,7 +947,7 @@ static void mpw_marshal_read_flat(
if (!headerEnded) if (!headerEnded)
continue; continue;
if (!fullName) if (!fullName)
file->error = (MPMarshalError){ MPMarshalErrorMissing, "Missing header: Full Name" }; mpw_marshal_error( file, MPMarshalErrorMissing, "Missing header: Full Name" );
if (positionInLine >= endOfLine) if (positionInLine >= endOfLine)
continue; continue;
@ -973,7 +986,7 @@ static void mpw_marshal_read_flat(
break; break;
} }
default: { default: {
file->error = (MPMarshalError){ MPMarshalErrorFormat, mpw_str( "Unexpected import format: %u", format ) }; mpw_marshal_error( file, MPMarshalErrorFormat, "Unexpected import format: %u", format );
continue; continue;
} }
} }
@ -981,28 +994,24 @@ static void mpw_marshal_read_flat(
if (siteName && str_type && str_counter && str_algorithm && str_uses && str_lastUsed) { if (siteName && str_type && str_counter && str_algorithm && str_uses && str_lastUsed) {
MPResultType siteType = (MPResultType)strtoul( str_type, NULL, 10 ); MPResultType siteType = (MPResultType)strtoul( str_type, NULL, 10 );
if (!mpw_type_short_name( siteType )) { if (!mpw_type_short_name( siteType )) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site type: %s: %s", siteName, str_type ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site type: %s: %s", siteName, str_type );
continue; continue;
} }
long long int value = strtoll( str_counter, NULL, 10 ); long long int value = strtoll( str_counter, NULL, 10 );
if (value < MPCounterValueFirst || value > MPCounterValueLast) { if (value < MPCounterValueFirst || value > MPCounterValueLast) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site counter: %s: %s", siteName, str_counter ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site counter: %s: %s", siteName, str_counter );
continue; continue;
} }
MPCounterValue siteCounter = (MPCounterValue)value; MPCounterValue siteCounter = (MPCounterValue)value;
value = strtoll( str_algorithm, NULL, 0 ); value = strtoll( str_algorithm, NULL, 0 );
if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast) { if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast) {
file->error = (MPMarshalError){ mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site algorithm: %s: %s", siteName, str_algorithm );
MPMarshalErrorIllegal, mpw_str( "Invalid site algorithm: %s: %s", siteName, str_algorithm )
};
continue; continue;
} }
MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)value; MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)value;
time_t siteLastUsed = mpw_timegm( str_lastUsed ); time_t siteLastUsed = mpw_timegm( str_lastUsed );
if (!siteLastUsed) { if (!siteLastUsed) {
file->error = (MPMarshalError){ mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site last used: %s: %s", siteName, str_lastUsed );
MPMarshalErrorIllegal, mpw_str( "Invalid site last used: %s: %s", siteName, str_lastUsed )
};
continue; continue;
} }
@ -1020,11 +1029,9 @@ static void mpw_marshal_read_flat(
mpw_marshal_data_set_str( dateString, file->data, "sites", siteName, "last_used", NULL ); mpw_marshal_data_set_str( dateString, file->data, "sites", siteName, "last_used", NULL );
} }
else { else {
file->error = (MPMarshalError){ mpw_marshal_error( file, MPMarshalErrorMissing,
MPMarshalErrorMissing, "Missing one of: lastUsed=%s, uses=%s, type=%s, version=%s, counter=%s, loginName=%s, siteName=%s",
mpw_str( "Missing one of: lastUsed=%s, uses=%s, type=%s, version=%s, counter=%s, loginName=%s, siteName=%s", str_lastUsed, str_uses, str_type, str_algorithm, str_counter, siteLoginState, siteName );
str_lastUsed, str_uses, str_type, str_algorithm, str_counter, siteLoginState, siteName )
};
continue; continue;
} }
@ -1044,7 +1051,7 @@ static void mpw_marshal_read_json(
mpw_marshal_file( file, NULL, mpw_marshal_data_new() ); mpw_marshal_file( file, NULL, mpw_marshal_data_new() );
if (!file->data) { if (!file->data) {
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate data." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't allocate data." );
return; return;
} }
@ -1052,7 +1059,7 @@ static void mpw_marshal_read_json(
enum json_tokener_error json_error = json_tokener_success; enum json_tokener_error json_error = json_tokener_success;
json_object *json_file = json_tokener_parse_verbose( in, &json_error ); json_object *json_file = json_tokener_parse_verbose( in, &json_error );
if (!json_file || json_error != json_tokener_success) { if (!json_file || json_error != json_tokener_success) {
file->error = (MPMarshalError){ MPMarshalErrorFormat, mpw_str( "Couldn't parse JSON: %s", json_tokener_error_desc( json_error ) ) }; mpw_marshal_error( file, MPMarshalErrorFormat, "Couldn't parse JSON: %s", json_tokener_error_desc( json_error ) );
return; return;
} }
@ -1074,9 +1081,9 @@ MPMarshalledFile *mpw_marshal_read(
if (!file) if (!file)
return NULL; return NULL;
file->error = (MPMarshalError){ MPMarshalSuccess, NULL }; mpw_marshal_error( file, MPMarshalSuccess, NULL );
if (!info) { if (!info) {
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate info." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't allocate info." );
return file; return file;
} }
@ -1116,13 +1123,13 @@ MPMarshalledUser *mpw_marshal_auth(
if (!file) if (!file)
return NULL; return NULL;
file->error = (MPMarshalError){ MPMarshalSuccess, NULL }; mpw_marshal_error( file, MPMarshalSuccess, NULL );
if (!file->info) { if (!file->info) {
file->error = (MPMarshalError){ MPMarshalErrorMissing, "File wasn't parsed yet." }; mpw_marshal_error( file, MPMarshalErrorMissing, "File wasn't parsed yet." );
return NULL; return NULL;
} }
if (!file->data) { if (!file->data) {
file->error = (MPMarshalError){ MPMarshalErrorMissing, "No input data." }; mpw_marshal_error( file, MPMarshalErrorMissing, "No input data." );
return NULL; return NULL;
} }
@ -1132,43 +1139,43 @@ MPMarshalledUser *mpw_marshal_auth(
MPAlgorithmVersion algorithm = MPAlgorithmVersion algorithm =
mpw_default_n( MPAlgorithmVersionCurrent, mpw_marshal_data_get_num( file->data, "user", "algorithm", NULL ) ); mpw_default_n( MPAlgorithmVersionCurrent, mpw_marshal_data_get_num( file->data, "user", "algorithm", NULL ) );
if (algorithm < MPAlgorithmVersionFirst || algorithm > MPAlgorithmVersionLast) { if (algorithm < MPAlgorithmVersionFirst || algorithm > MPAlgorithmVersionLast) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user algorithm: %u", algorithm ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid user algorithm: %u", algorithm );
return NULL; return NULL;
} }
unsigned int avatar = mpw_default_n( 0U, mpw_marshal_data_get_num( file->data, "user", "avatar", NULL ) ); unsigned int avatar = mpw_default_n( 0U, mpw_marshal_data_get_num( file->data, "user", "avatar", NULL ) );
const char *fullName = mpw_marshal_data_get_str( file->data, "user", "full_name", NULL ); const char *fullName = mpw_marshal_data_get_str( file->data, "user", "full_name", NULL );
if (!fullName || !strlen( fullName )) { if (!fullName || !strlen( fullName )) {
file->error = (MPMarshalError){ MPMarshalErrorMissing, "Missing value for full name." }; mpw_marshal_error( file, MPMarshalErrorMissing, "Missing value for full name." );
return NULL; return NULL;
} }
MPIdenticon identicon = mpw_identicon_encoded( mpw_marshal_data_get_str( file->data, "user", "identicon", NULL ) ); MPIdenticon identicon = mpw_identicon_encoded( mpw_marshal_data_get_str( file->data, "user", "identicon", NULL ) );
const char *keyID = mpw_marshal_data_get_str( file->data, "user", "key_id", NULL ); const char *keyID = mpw_marshal_data_get_str( file->data, "user", "key_id", NULL );
MPResultType defaultType = mpw_default_n( MPResultTypeDefault, mpw_marshal_data_get_num( file->data, "user", "default_type", NULL ) ); MPResultType defaultType = mpw_default_n( MPResultTypeDefault, mpw_marshal_data_get_num( file->data, "user", "default_type", NULL ) );
if (!mpw_type_short_name( defaultType )) { if (!mpw_type_short_name( defaultType )) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user default type: %u", defaultType ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid user default type: %u", defaultType );
return NULL; return NULL;
} }
const char *str_lastUsed = mpw_marshal_data_get_str( file->data, "user", "last_used", NULL ); const char *str_lastUsed = mpw_marshal_data_get_str( file->data, "user", "last_used", NULL );
time_t lastUsed = mpw_timegm( str_lastUsed ); time_t lastUsed = mpw_timegm( str_lastUsed );
if (!lastUsed) { if (!lastUsed) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user last used: %s", str_lastUsed ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid user last used: %s", str_lastUsed );
return NULL; return NULL;
} }
MPMasterKey masterKey = NULL; MPMasterKey masterKey = NULL;
if (masterKeyProvider && !(masterKey = masterKeyProvider( algorithm, fullName ))) { if (masterKeyProvider && !(masterKey = masterKeyProvider( algorithm, fullName ))) {
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't derive master key." );
return NULL; return NULL;
} }
if (keyID && masterKey && !mpw_id_buf_equals( keyID, mpw_id_buf( masterKey, MPMasterKeySize ) )) { if (keyID && masterKey && !mpw_id_buf_equals( keyID, mpw_id_buf( masterKey, MPMasterKeySize ) )) {
file->error = (MPMarshalError){ MPMarshalErrorMasterPassword, "Master key doesn't match key ID." }; mpw_marshal_error( file, MPMarshalErrorMasterPassword, "Master key doesn't match key ID." );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
return NULL; return NULL;
} }
MPMarshalledUser *user = NULL; MPMarshalledUser *user = NULL;
if (!(user = mpw_marshal_user( fullName, masterKeyProvider, algorithm ))) { if (!(user = mpw_marshal_user( fullName, masterKeyProvider, algorithm ))) {
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate a new user." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't allocate a new user." );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;
@ -1189,21 +1196,21 @@ MPMarshalledUser *mpw_marshal_auth(
algorithm = mpw_default_n( user->algorithm, mpw_marshal_data_get_num( siteData, "algorithm", NULL ) ); algorithm = mpw_default_n( user->algorithm, mpw_marshal_data_get_num( siteData, "algorithm", NULL ) );
if (algorithm < MPAlgorithmVersionFirst || algorithm > MPAlgorithmVersionLast) { if (algorithm < MPAlgorithmVersionFirst || algorithm > MPAlgorithmVersionLast) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site algorithm: %s: %u", siteName, algorithm ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site algorithm: %s: %u", siteName, algorithm );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;
} }
MPCounterValue siteCounter = mpw_default_n( MPCounterValueDefault, mpw_marshal_data_get_num( siteData, "counter", NULL ) ); MPCounterValue siteCounter = mpw_default_n( MPCounterValueDefault, mpw_marshal_data_get_num( siteData, "counter", NULL ) );
if (siteCounter < MPCounterValueFirst || siteCounter > MPCounterValueLast) { if (siteCounter < MPCounterValueFirst || siteCounter > MPCounterValueLast) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site counter: %s: %d", siteName, siteCounter ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site counter: %s: %d", siteName, siteCounter );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;
} }
MPResultType siteType = mpw_default_n( user->defaultType, mpw_marshal_data_get_num( siteData, "type", NULL ) ); MPResultType siteType = mpw_default_n( user->defaultType, mpw_marshal_data_get_num( siteData, "type", NULL ) );
if (!mpw_type_short_name( siteType )) { if (!mpw_type_short_name( siteType )) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site type: %s: %u", siteName, siteType ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site type: %s: %u", siteName, siteType );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;
@ -1211,7 +1218,7 @@ MPMarshalledUser *mpw_marshal_auth(
const char *siteResultState = mpw_marshal_data_get_str( siteData, "password", NULL ); const char *siteResultState = mpw_marshal_data_get_str( siteData, "password", NULL );
MPResultType siteLoginType = mpw_default_n( MPResultTypeTemplateName, mpw_marshal_data_get_num( siteData, "login_type", NULL ) ); MPResultType siteLoginType = mpw_default_n( MPResultTypeTemplateName, mpw_marshal_data_get_num( siteData, "login_type", NULL ) );
if (!mpw_type_short_name( siteLoginType )) { if (!mpw_type_short_name( siteLoginType )) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site login type: %s: %u", siteName, siteLoginType ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site login type: %s: %u", siteName, siteLoginType );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;
@ -1221,7 +1228,7 @@ MPMarshalledUser *mpw_marshal_auth(
str_lastUsed = mpw_marshal_data_get_str( siteData, "last_used", NULL ); str_lastUsed = mpw_marshal_data_get_str( siteData, "last_used", NULL );
time_t siteLastUsed = mpw_timegm( str_lastUsed ); time_t siteLastUsed = mpw_timegm( str_lastUsed );
if (!siteLastUsed) { if (!siteLastUsed) {
file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site last used: %s: %s", siteName, str_lastUsed ) }; mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site last used: %s: %s", siteName, str_lastUsed );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;
@ -1231,7 +1238,7 @@ MPMarshalledUser *mpw_marshal_auth(
MPMarshalledSite *site = mpw_marshal_site( user, siteName, siteType, siteCounter, algorithm ); MPMarshalledSite *site = mpw_marshal_site( user, siteName, siteType, siteCounter, algorithm );
if (!site) { if (!site) {
file->error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate a new site." }; mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't allocate a new site." );
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;
@ -1245,10 +1252,7 @@ MPMarshalledUser *mpw_marshal_auth(
// Clear Text // Clear Text
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
if (!masterKeyProvider || !(masterKey = masterKeyProvider( site->algorithm, user->fullName ))) { if (!masterKeyProvider || !(masterKey = masterKeyProvider( site->algorithm, user->fullName ))) {
file->error = (MPMarshalError){ mpw_marshal_error( file, MPMarshalErrorInternal, "Couldn't derive master key." );
MPMarshalErrorInternal,
"Couldn't derive master key."
};
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
mpw_marshal_user_free( &user ); mpw_marshal_user_free( &user );
return NULL; return NULL;

View File

@ -246,6 +246,10 @@ MPMarshalledQuestion *mpw_marshal_question(
* @return The given file or new (allocated) if file is NULL; or NULL if the user is missing or the file couldn't be allocated. */ * @return The given file or new (allocated) if file is NULL; or NULL if the user is missing or the file couldn't be allocated. */
MPMarshalledFile *mpw_marshal_file( MPMarshalledFile *mpw_marshal_file(
MPMarshalledFile *file, MPMarshalledInfo *info, MPMarshalledData *data); MPMarshalledFile *file, MPMarshalledInfo *info, MPMarshalledData *data);
/** Record a marshal error.
* @return The given file or new (allocated) if file is NULL; or NULL if the file couldn't be allocated. */
MPMarshalledFile *mpw_marshal_error(
MPMarshalledFile *file, MPMarshalErrorType type, const char *format, ...);
//// Disposing. //// Disposing.