2
0

More flexible API for providing marshalling master key.

This commit is contained in:
Maarten Billemont 2019-05-11 19:02:55 -04:00
parent 44a9ee0f15
commit 39eb0027b5
4 changed files with 79 additions and 52 deletions

View File

@ -29,6 +29,7 @@
#include "mpw-algorithm.h" #include "mpw-algorithm.h"
#include "mpw-util.h" #include "mpw-util.h"
#include "mpw-marshal.h" #include "mpw-marshal.h"
#include "mpw-marshal-util.h"
/** Output the program's usage documentation. */ /** Output the program's usage documentation. */
static void usage() { static void usage() {
@ -182,6 +183,9 @@ void cli_sitesRedacted(Arguments *args, Operation *operation);
void cli_mpw(Arguments *args, Operation *operation); void cli_mpw(Arguments *args, Operation *operation);
void cli_save(Arguments *args, Operation *operation); void cli_save(Arguments *args, Operation *operation);
MPMasterKeyProvider cli_masterKeyProvider_op(Operation *operation);
MPMasterKeyProvider cli_masterKeyProvider_str(const char *masterPassword);
/** ======================================================================== /** ========================================================================
* MAIN */ * MAIN */
int main(const int argc, char *const argv[]) { int main(const int argc, char *const argv[]) {
@ -230,7 +234,6 @@ int main(const int argc, char *const argv[]) {
dbg( "-----------------" ); dbg( "-----------------" );
if (operation.user) { if (operation.user) {
dbg( "fullName : %s", operation.user->fullName ); dbg( "fullName : %s", operation.user->fullName );
trc( "masterPassword : %s", operation.user->masterPassword );
dbg( "identicon : %s", operation.identicon ); dbg( "identicon : %s", operation.identicon );
dbg( "sitesFormat : %s%s", mpw_nameForFormat( operation.sitesFormat ), operation.sitesFormatFixed? " (fixed)": "" ); dbg( "sitesFormat : %s%s", mpw_nameForFormat( operation.sitesFormat ), operation.sitesFormatFixed? " (fixed)": "" );
dbg( "sitesPath : %s", operation.sitesPath ); dbg( "sitesPath : %s", operation.sitesPath );
@ -247,11 +250,11 @@ int main(const int argc, char *const argv[]) {
dbg( "-----------------" ); dbg( "-----------------" );
// Finally ready to perform the actual operation. // Finally ready to perform the actual operation.
cli_mpw( &args, &operation ); cli_mpw( NULL, &operation );
// Save changes and clean up. // Save changes and clean up.
cli_save( &args, &operation ); cli_save( NULL, &operation );
cli_free( &args, &operation ); cli_free( NULL, &operation );
return EX_OK; return EX_OK;
} }
@ -487,7 +490,7 @@ void cli_user(Arguments *args, Operation *operation) {
MPMarshalError marshalError = { .type = MPMarshalSuccess }; MPMarshalError marshalError = { .type = MPMarshalSuccess };
mpw_marshal_info_free( &sitesInputInfo ); mpw_marshal_info_free( &sitesInputInfo );
mpw_marshal_free( &operation->user ); mpw_marshal_free( &operation->user );
operation->user = mpw_marshal_read( sitesInputData, sitesInputFormat, operation->masterPassword, &marshalError ); operation->user = mpw_marshal_read( sitesInputData, sitesInputFormat, cli_masterKeyProvider_op( operation ), &marshalError );
if (marshalError.type == MPMarshalErrorMasterPassword && operation->allowPasswordUpdate) { if (marshalError.type == MPMarshalErrorMasterPassword && operation->allowPasswordUpdate) {
// Update master password in mpsites. // Update master password in mpsites.
while (marshalError.type == MPMarshalErrorMasterPassword) { while (marshalError.type == MPMarshalErrorMasterPassword) {
@ -499,12 +502,10 @@ void cli_user(Arguments *args, Operation *operation) {
importMasterPassword = mpw_getpass( "Old master password: " ); importMasterPassword = mpw_getpass( "Old master password: " );
mpw_marshal_free( &operation->user ); mpw_marshal_free( &operation->user );
operation->user = mpw_marshal_read( sitesInputData, sitesInputFormat, importMasterPassword, &marshalError ); operation->user = mpw_marshal_read( sitesInputData, sitesInputFormat, cli_masterKeyProvider_str( importMasterPassword ), &marshalError );
mpw_free_string( &importMasterPassword ); mpw_free_string( &importMasterPassword );
}
if (operation->user) { operation->user->masterKeyProvider = cli_masterKeyProvider_op( operation );
mpw_free_string( &operation->user->masterPassword );
operation->user->masterPassword = mpw_strdup( operation->masterPassword );
} }
} }
mpw_free_string( &sitesInputData ); mpw_free_string( &sitesInputData );
@ -527,7 +528,7 @@ void cli_user(Arguments *args, Operation *operation) {
// If no user from mpsites, create a new one. // If no user from mpsites, create a new one.
if (!operation->user) if (!operation->user)
operation->user = mpw_marshal_user( operation->user = mpw_marshal_user(
operation->fullName, operation->masterPassword, MPAlgorithmVersionCurrent ); operation->fullName, cli_masterKeyProvider_op( operation ), MPAlgorithmVersionCurrent );
} }
void cli_site(Arguments *args, Operation *operation) { void cli_site(Arguments *args, Operation *operation) {
@ -572,7 +573,7 @@ void cli_question(Arguments *args, Operation *operation) {
void cli_operation(Arguments *args, Operation *operation) { void cli_operation(Arguments *args, Operation *operation) {
mpw_free_string( &operation->identicon ); mpw_free_string( &operation->identicon );
operation->identicon = mpw_identicon_str( mpw_identicon( operation->user->fullName, operation->user->masterPassword ) ); operation->identicon = mpw_identicon_str( mpw_identicon( operation->user->fullName, operation->masterPassword ) );
if (!operation->site) if (!operation->site)
abort(); abort();
@ -702,8 +703,7 @@ void cli_mpw(Arguments *args, Operation *operation) {
operation->user->fullName, operation->purposeResult, operation->site->name, operation->identicon ); operation->user->fullName, operation->purposeResult, operation->site->name, operation->identicon );
// Determine master key. // Determine master key.
MPMasterKey masterKey = mpw_masterKey( MPMasterKey masterKey = operation->user->masterKeyProvider( operation->site->algorithm, operation->user->fullName );
operation->user->fullName, operation->user->masterPassword, operation->site->algorithm );
if (!masterKey) { if (!masterKey) {
ftl( "Couldn't derive master key." ); ftl( "Couldn't derive master key." );
cli_free( args, operation ); cli_free( args, operation );
@ -799,3 +799,32 @@ void cli_save(Arguments *args, Operation *operation) {
mpw_free_string( &buf ); mpw_free_string( &buf );
fclose( sitesFile ); fclose( sitesFile );
} }
static MPMasterKey __cli_masterKeyProvider_currentKey;
static MPAlgorithmVersion __cli_masterKeyProvider_currentAlgorithm;
static const char *__cli_masterKeyProvider_currentPassword;
static Operation *__cli_masterKeyProvider_currentOperation;
static MPMasterKey __cli_masterKeyProvider_op(MPAlgorithmVersion algorithm, const char *fullName) {
if (mpw_update_masterKey(&__cli_masterKeyProvider_currentKey, &__cli_masterKeyProvider_currentAlgorithm,
algorithm, fullName, __cli_masterKeyProvider_currentOperation->masterPassword))
return __cli_masterKeyProvider_currentKey;
return NULL;
}
static MPMasterKey __cli_masterKeyProvider_str(MPAlgorithmVersion algorithm, const char *fullName) {
if (mpw_update_masterKey(&__cli_masterKeyProvider_currentKey, &__cli_masterKeyProvider_currentAlgorithm,
algorithm, fullName, __cli_masterKeyProvider_currentPassword))
return __cli_masterKeyProvider_currentKey;
return NULL;
}
MPMasterKeyProvider cli_masterKeyProvider_op(Operation *operation) {
__cli_masterKeyProvider_currentOperation = operation;
return __cli_masterKeyProvider_op;
}
MPMasterKeyProvider cli_masterKeyProvider_str(const char *masterPassword) {
__cli_masterKeyProvider_currentPassword = masterPassword;
return __cli_masterKeyProvider_str;
}

View File

@ -106,7 +106,7 @@ bool mpw_get_json_boolean(
bool mpw_update_masterKey(MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, MPAlgorithmVersion targetKeyAlgorithm, bool mpw_update_masterKey(MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, MPAlgorithmVersion targetKeyAlgorithm,
const char *fullName, const char *masterPassword) { const char *fullName, const char *masterPassword) {
if (*masterKeyAlgorithm != targetKeyAlgorithm) { if (masterKey && (!*masterKey || *masterKeyAlgorithm != targetKeyAlgorithm)) {
mpw_free( masterKey, MPMasterKeySize ); mpw_free( masterKey, MPMasterKeySize );
*masterKeyAlgorithm = targetKeyAlgorithm; *masterKeyAlgorithm = targetKeyAlgorithm;
*masterKey = mpw_masterKey( fullName, masterPassword, *masterKeyAlgorithm ); *masterKey = mpw_masterKey( fullName, masterPassword, *masterKeyAlgorithm );

View File

@ -26,15 +26,15 @@
#include "mpw-marshal-util.h" #include "mpw-marshal-util.h"
MPMarshalledUser *mpw_marshal_user( MPMarshalledUser *mpw_marshal_user(
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion) { const char *fullName, MPMasterKeyProvider masterKeyProvider, const MPAlgorithmVersion algorithmVersion) {
MPMarshalledUser *user; MPMarshalledUser *user;
if (!fullName || !masterPassword || !(user = malloc( sizeof( MPMarshalledUser ) ))) if (!fullName || !masterKeyProvider || !(user = malloc( sizeof( MPMarshalledUser ) )))
return NULL; return NULL;
*user = (MPMarshalledUser){ *user = (MPMarshalledUser){
.fullName = mpw_strdup( fullName ), .fullName = mpw_strdup( fullName ),
.masterPassword = mpw_strdup( masterPassword ), .masterKeyProvider = masterKeyProvider,
.algorithm = algorithmVersion, .algorithm = algorithmVersion,
.redacted = true, .redacted = true,
@ -113,7 +113,7 @@ bool mpw_marshal_free(
return true; return true;
bool success = true; bool success = true;
success &= mpw_free_strings( &(*user)->fullName, &(*user)->masterPassword, NULL ); success &= mpw_free_strings( &(*user)->fullName, NULL );
for (size_t s = 0; s < (*user)->sites_count; ++s) { for (size_t s = 0; s < (*user)->sites_count; ++s) {
MPMarshalledSite *site = &(*user)->sites[s]; MPMarshalledSite *site = &(*user)->sites[s];
@ -140,13 +140,8 @@ static bool mpw_marshal_write_flat(
*error = (MPMarshalError){ MPMarshalErrorMissing, "Missing full name." }; *error = (MPMarshalError){ MPMarshalErrorMissing, "Missing full name." };
return false; return false;
} }
if (!user->masterPassword || !strlen( user->masterPassword )) { MPMasterKey masterKey = user->masterKeyProvider( user->algorithm, user->fullName );
*error = (MPMarshalError){ MPMarshalErrorMasterPassword, "Missing master password." }; if (!masterKey) {
return false;
}
MPMasterKey masterKey = NULL;
MPAlgorithmVersion masterKeyAlgorithm = user->algorithm - 1;
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, user->algorithm, user->fullName, user->masterPassword )) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return false; return false;
} }
@ -185,7 +180,8 @@ static bool mpw_marshal_write_flat(
const char *content = NULL, *loginContent = NULL; const char *content = NULL, *loginContent = NULL;
if (!user->redacted) { if (!user->redacted) {
// Clear Text // Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site->algorithm, user->fullName, user->masterPassword )) { mpw_free( &masterKey, MPMasterKeySize );
if (!(masterKey = user->masterKeyProvider( user->algorithm, user->fullName ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return false; return false;
} }
@ -224,13 +220,8 @@ static bool mpw_marshal_write_json(
*error = (MPMarshalError){ MPMarshalErrorMissing, "Missing full name." }; *error = (MPMarshalError){ MPMarshalErrorMissing, "Missing full name." };
return false; return false;
} }
if (!user->masterPassword || !strlen( user->masterPassword )) { MPMasterKey masterKey = user->masterKeyProvider( user->algorithm, user->fullName );
*error = (MPMarshalError){ MPMarshalErrorMasterPassword, "Missing master password." }; if (!masterKey) {
return false;
}
MPMasterKey masterKey = NULL;
MPAlgorithmVersion masterKeyAlgorithm = user->algorithm - 1;
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, user->algorithm, user->fullName, user->masterPassword )) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return false; return false;
} }
@ -271,7 +262,8 @@ static bool mpw_marshal_write_json(
const char *content = NULL, *loginContent = NULL; const char *content = NULL, *loginContent = NULL;
if (!user->redacted) { if (!user->redacted) {
// Clear Text // Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site->algorithm, user->fullName, user->masterPassword )) { mpw_free( &masterKey, MPMasterKeySize );
if (!(masterKey = user->masterKeyProvider( user->algorithm, user->fullName ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return false; return false;
} }
@ -341,8 +333,8 @@ static bool mpw_marshal_write_json(
mpw_string_pushf( out, "%s\n", json_object_to_json_string_ext( json_file, mpw_string_pushf( out, "%s\n", json_object_to_json_string_ext( json_file,
JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_NOSLASHESCAPE ) ); JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_NOSLASHESCAPE ) );
mpw_free( &masterKey, MPMasterKeySize );
json_object_put( json_file ); json_object_put( json_file );
mpw_free( &masterKey, MPMasterKeySize );
*error = (MPMarshalError){ .type = MPMarshalSuccess }; *error = (MPMarshalError){ .type = MPMarshalSuccess };
return true; return true;
@ -416,7 +408,7 @@ static void mpw_marshal_read_flat_info(
} }
static MPMarshalledUser *mpw_marshal_read_flat( static MPMarshalledUser *mpw_marshal_read_flat(
const char *in, const char *masterPassword, MPMarshalError *error) { const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Unexpected internal error." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Unexpected internal error." };
if (!in || !strlen( in )) { if (!in || !strlen( in )) {
@ -430,7 +422,7 @@ static MPMarshalledUser *mpw_marshal_read_flat(
MPMarshalledUser *user = NULL; MPMarshalledUser *user = NULL;
unsigned int format = 0, avatar = 0; unsigned int format = 0, avatar = 0;
char *fullName = NULL, *keyID = NULL; char *fullName = NULL, *keyID = NULL;
MPAlgorithmVersion algorithm = MPAlgorithmVersionCurrent, masterKeyAlgorithm = (MPAlgorithmVersion)-1; MPAlgorithmVersion algorithm = MPAlgorithmVersionCurrent;
MPResultType defaultType = MPResultTypeDefault; MPResultType defaultType = MPResultTypeDefault;
bool headerStarted = false, headerEnded = false, importRedacted = false; bool headerStarted = false, headerEnded = false, importRedacted = false;
for (const char *endOfLine, *positionInLine = in; (endOfLine = strstr( positionInLine, "\n" )); positionInLine = endOfLine + 1) { for (const char *endOfLine, *positionInLine = in; (endOfLine = strstr( positionInLine, "\n" )); positionInLine = endOfLine + 1) {
@ -504,7 +496,8 @@ static MPMarshalledUser *mpw_marshal_read_flat(
continue; continue;
if (!user) { if (!user) {
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, algorithm, fullName, masterPassword )) { mpw_free( &masterKey, MPMasterKeySize );
if (!(masterKey = masterKeyProvider( algorithm, fullName ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return NULL; return NULL;
} }
@ -512,7 +505,7 @@ static MPMarshalledUser *mpw_marshal_read_flat(
*error = (MPMarshalError){ MPMarshalErrorMasterPassword, "Master password doesn't match key ID." }; *error = (MPMarshalError){ MPMarshalErrorMasterPassword, "Master password doesn't match key ID." };
return NULL; return NULL;
} }
if (!(user = mpw_marshal_user( fullName, masterPassword, algorithm ))) { if (!(user = mpw_marshal_user( fullName, masterKeyProvider, algorithm ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate a new user." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate a new user." };
return NULL; return NULL;
} }
@ -597,7 +590,8 @@ static MPMarshalledUser *mpw_marshal_read_flat(
site->lastUsed = siteLastUsed; site->lastUsed = siteLastUsed;
if (!user->redacted) { if (!user->redacted) {
// Clear Text // Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site->algorithm, fullName, masterPassword )) { mpw_free( &masterKey, MPMasterKeySize );
if (!(masterKey = masterKeyProvider( user->algorithm, user->fullName ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return NULL; return NULL;
} }
@ -661,7 +655,7 @@ static void mpw_marshal_read_json_info(
} }
static MPMarshalledUser *mpw_marshal_read_json( static MPMarshalledUser *mpw_marshal_read_json(
const char *in, const char *masterPassword, MPMarshalError *error) { const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Unexpected internal error." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Unexpected internal error." };
if (!in || !strlen( in )) { if (!in || !strlen( in )) {
@ -680,7 +674,6 @@ static MPMarshalledUser *mpw_marshal_read_json(
// Parse import data. // Parse import data.
MPMasterKey masterKey = NULL; MPMasterKey masterKey = NULL;
MPAlgorithmVersion masterKeyAlgorithm = (MPAlgorithmVersion)-1;
MPMarshalledUser *user = NULL; MPMarshalledUser *user = NULL;
// Section: "export" // Section: "export"
@ -716,7 +709,7 @@ static MPMarshalledUser *mpw_marshal_read_json(
*error = (MPMarshalError){ MPMarshalErrorMissing, "Missing value for full name." }; *error = (MPMarshalError){ MPMarshalErrorMissing, "Missing value for full name." };
return NULL; return NULL;
} }
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, algorithm, fullName, masterPassword )) { if (!(masterKey = masterKeyProvider( user->algorithm, user->fullName ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return NULL; return NULL;
} }
@ -724,7 +717,7 @@ static MPMarshalledUser *mpw_marshal_read_json(
*error = (MPMarshalError){ MPMarshalErrorMasterPassword, "Master password doesn't match key ID." }; *error = (MPMarshalError){ MPMarshalErrorMasterPassword, "Master password doesn't match key ID." };
return NULL; return NULL;
} }
if (!(user = mpw_marshal_user( fullName, masterPassword, algorithm ))) { if (!(user = mpw_marshal_user( fullName, masterKeyProvider, algorithm ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate a new user." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't allocate a new user." };
return NULL; return NULL;
} }
@ -781,7 +774,8 @@ static MPMarshalledUser *mpw_marshal_read_json(
site->lastUsed = siteLastUsed; site->lastUsed = siteLastUsed;
if (!user->redacted) { if (!user->redacted) {
// Clear Text // Clear Text
if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site->algorithm, fullName, masterPassword )) { mpw_free( &masterKey, MPMasterKeySize );
if (!(masterKey = masterKeyProvider( user->algorithm, user->fullName ))) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Couldn't derive master key." };
return NULL; return NULL;
} }
@ -824,6 +818,7 @@ static MPMarshalledUser *mpw_marshal_read_json(
} }
} }
json_object_put( json_file ); json_object_put( json_file );
mpw_free( &masterKey, MPMasterKeySize );
*error = (MPMarshalError){ .type = MPMarshalSuccess }; *error = (MPMarshalError){ .type = MPMarshalSuccess };
return user; return user;
@ -853,17 +848,17 @@ MPMarshalInfo *mpw_marshal_read_info(
} }
MPMarshalledUser *mpw_marshal_read( MPMarshalledUser *mpw_marshal_read(
const char *in, const MPMarshalFormat inFormat, const char *masterPassword, MPMarshalError *error) { const char *in, const MPMarshalFormat inFormat, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
switch (inFormat) { switch (inFormat) {
case MPMarshalFormatNone: case MPMarshalFormatNone:
*error = (MPMarshalError){ .type = MPMarshalSuccess }; *error = (MPMarshalError){ .type = MPMarshalSuccess };
return false; return false;
case MPMarshalFormatFlat: case MPMarshalFormatFlat:
return mpw_marshal_read_flat( in, masterPassword, error ); return mpw_marshal_read_flat( in, masterKeyProvider, error );
#if MPW_JSON #if MPW_JSON
case MPMarshalFormatJSON: case MPMarshalFormatJSON:
return mpw_marshal_read_json( in, masterPassword, error ); return mpw_marshal_read_json( in, masterKeyProvider, error );
#endif #endif
default: default:
*error = (MPMarshalError){ MPMarshalErrorFormat, mpw_str( "Unsupported input format: %u", inFormat ) }; *error = (MPMarshalError){ MPMarshalErrorFormat, mpw_str( "Unsupported input format: %u", inFormat ) };

View File

@ -56,6 +56,9 @@ typedef mpw_enum( unsigned int, MPMarshalErrorType ) {
/** An internal system error interrupted marshalling. */ /** An internal system error interrupted marshalling. */
MPMarshalErrorInternal, MPMarshalErrorInternal,
}; };
typedef MPMasterKey (*MPMasterKeyProvider)(MPAlgorithmVersion algorithm, const char *fullName);
typedef struct MPMarshalError { typedef struct MPMarshalError {
MPMarshalErrorType type; MPMarshalErrorType type;
const char *description; const char *description;
@ -87,7 +90,7 @@ typedef struct MPMarshalledSite {
typedef struct MPMarshalledUser { typedef struct MPMarshalledUser {
const char *fullName; const char *fullName;
const char *masterPassword; MPMasterKeyProvider masterKeyProvider;
MPAlgorithmVersion algorithm; MPAlgorithmVersion algorithm;
bool redacted; bool redacted;
@ -118,13 +121,13 @@ MPMarshalInfo *mpw_marshal_read_info(
const char *in); const char *in);
/** Unmarshall sites in the given input buffer by parsing it using the given marshalling format. */ /** Unmarshall sites in the given input buffer by parsing it using the given marshalling format. */
MPMarshalledUser *mpw_marshal_read( MPMarshalledUser *mpw_marshal_read(
const char *in, const MPMarshalFormat inFormat, const char *masterPassword, MPMarshalError *error); const char *in, const MPMarshalFormat inFormat, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error);
//// Utilities. //// Utilities.
/** Create a new user object ready for marshalling. */ /** Create a new user object ready for marshalling. */
MPMarshalledUser *mpw_marshal_user( MPMarshalledUser *mpw_marshal_user(
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion); const char *fullName, MPMasterKeyProvider masterKeyProvider, const MPAlgorithmVersion algorithmVersion);
/** Create a new site attached to the given user object, ready for marshalling. */ /** Create a new site attached to the given user object, ready for marshalling. */
MPMarshalledSite *mpw_marshal_site( MPMarshalledSite *mpw_marshal_site(
MPMarshalledUser *user, MPMarshalledUser *user,