Marshal data API & fixes.
This commit is contained in:
parent
ddb786c332
commit
4c6d7ac36c
@ -272,7 +272,7 @@ void cli_free(Arguments *args, Operation *operation) {
|
||||
mpw_free_strings( &operation->fullName, &operation->masterPassword, &operation->siteName, NULL );
|
||||
mpw_free_strings( &operation->keyContext, &operation->resultState, &operation->resultParam, NULL );
|
||||
mpw_free_strings( &operation->identicon, &operation->sitesPath, NULL );
|
||||
mpw_marshal_free( &operation->file );
|
||||
mpw_marshal_file_free( &operation->file );
|
||||
operation->site = NULL;
|
||||
operation->question = NULL;
|
||||
cli_masterKeyProvider_free();
|
||||
@ -487,7 +487,7 @@ void cli_user(Arguments *args, Operation *operation) {
|
||||
if (!sitesFile) {
|
||||
// If no user from mpsites, create a new one.
|
||||
mpw_free_string( &operation->sitesPath );
|
||||
mpw_marshal_free( &operation->file );
|
||||
mpw_marshal_file_free( &operation->file );
|
||||
operation->file = mpw_marshal_file( mpw_marshal_user(
|
||||
operation->fullName, cli_masterKeyProvider_op( operation ), MPAlgorithmVersionCurrent ), NULL );
|
||||
}
|
||||
@ -501,7 +501,7 @@ void cli_user(Arguments *args, Operation *operation) {
|
||||
|
||||
// Parse file.
|
||||
MPMarshalError marshalError = { .type = MPMarshalSuccess };
|
||||
mpw_marshal_free( &operation->file );
|
||||
mpw_marshal_file_free( &operation->file );
|
||||
operation->file = mpw_marshal_read( sitesInputData,
|
||||
cli_masterKeyProvider_op( operation ), &marshalError );
|
||||
if (marshalError.type == MPMarshalErrorMasterPassword && operation->allowPasswordUpdate) {
|
||||
@ -516,7 +516,7 @@ void cli_user(Arguments *args, Operation *operation) {
|
||||
importMasterPassword = mpw_getpass( "Old master password: " );
|
||||
}
|
||||
|
||||
mpw_marshal_free( &operation->file );
|
||||
mpw_marshal_file_free( &operation->file );
|
||||
operation->file = mpw_marshal_read( sitesInputData,
|
||||
cli_masterKeyProvider_str( importMasterPassword ), &marshalError );
|
||||
if (operation->file && operation->file->user)
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "mpw-algorithm_v2.c"
|
||||
#include "mpw-algorithm_v3.c"
|
||||
|
||||
MPMasterKey mpw_master_key(const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion) {
|
||||
const MPMasterKey mpw_master_key(const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion) {
|
||||
|
||||
if (fullName && !strlen( fullName ))
|
||||
fullName = NULL;
|
||||
@ -56,8 +56,8 @@ MPMasterKey mpw_master_key(const char *fullName, const char *masterPassword, con
|
||||
}
|
||||
}
|
||||
|
||||
MPSiteKey mpw_site_key(
|
||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPSiteKey mpw_site_key(
|
||||
const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion) {
|
||||
|
||||
if (keyContext && !strlen( keyContext ))
|
||||
@ -93,7 +93,7 @@ MPSiteKey mpw_site_key(
|
||||
}
|
||||
|
||||
const char *mpw_site_result(
|
||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPKeyPurpose keyPurpose, const char *keyContext,
|
||||
const MPResultType resultType, const char *resultParam,
|
||||
const MPAlgorithmVersion algorithmVersion) {
|
||||
@ -171,7 +171,7 @@ const char *mpw_site_result(
|
||||
}
|
||||
|
||||
const char *mpw_site_state(
|
||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPKeyPurpose keyPurpose, const char *keyContext,
|
||||
const MPResultType resultType, const char *resultParam,
|
||||
const MPAlgorithmVersion algorithmVersion) {
|
||||
@ -223,7 +223,7 @@ static const char *mpw_identicon_accessories[] = {
|
||||
"♨", "♩", "♪", "♫", "⚐", "⚑", "⚔", "⚖", "⚙", "⚠", "⌘", "⏎", "✄", "✆", "✈", "✉", "✌"
|
||||
};
|
||||
|
||||
MPIdenticon mpw_identicon(const char *fullName, const char *masterPassword) {
|
||||
const MPIdenticon mpw_identicon(const char *fullName, const char *masterPassword) {
|
||||
|
||||
const uint8_t *seed = NULL;
|
||||
if (fullName && strlen( fullName ) && masterPassword && strlen( masterPassword ))
|
||||
@ -246,7 +246,7 @@ MPIdenticon mpw_identicon(const char *fullName, const char *masterPassword) {
|
||||
}
|
||||
|
||||
const char *mpw_identicon_encode(
|
||||
MPIdenticon identicon) {
|
||||
const MPIdenticon identicon) {
|
||||
|
||||
if (identicon.color == MPIdenticonColorUnset)
|
||||
return "";
|
||||
@ -255,7 +255,7 @@ const char *mpw_identicon_encode(
|
||||
identicon.color, identicon.leftArm, identicon.body, identicon.rightArm, identicon.accessory );
|
||||
}
|
||||
|
||||
MPIdenticon mpw_identicon_encoded(
|
||||
const MPIdenticon mpw_identicon_encoded(
|
||||
const char *encoding) {
|
||||
|
||||
MPIdenticon identicon = MPIdenticonUnset;
|
||||
|
@ -38,20 +38,20 @@ typedef mpw_enum( unsigned int, MPAlgorithmVersion ) {
|
||||
|
||||
/** Derive the master key for a user based on their name and master password.
|
||||
* @return A buffer (allocated, MPMasterKeySize) or NULL if the fullName or masterPassword is missing, the algorithm is unknown, or an algorithm error occurred. */
|
||||
MPMasterKey mpw_master_key(
|
||||
const MPMasterKey mpw_master_key(
|
||||
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion);
|
||||
|
||||
/** Derive the site key for a user's site from the given master key and site parameters.
|
||||
* @return A buffer (allocated, MPSiteKeySize) or NULL if the masterKey or siteName is missing, the algorithm is unknown, or an algorithm error occurred. */
|
||||
MPSiteKey mpw_site_key(
|
||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPSiteKey mpw_site_key(
|
||||
const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion);
|
||||
|
||||
/** Generate a site result token from the given parameters.
|
||||
* @param resultParam A parameter for the resultType. For stateful result types, the output of mpw_site_state.
|
||||
* @return A string (allocated) or NULL if the masterKey or siteName is missing, the algorithm is unknown, or an algorithm error occurred. */
|
||||
const char *mpw_site_result(
|
||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPKeyPurpose keyPurpose, const char *keyContext,
|
||||
const MPResultType resultType, const char *resultParam,
|
||||
const MPAlgorithmVersion algorithmVersion);
|
||||
@ -60,19 +60,19 @@ const char *mpw_site_result(
|
||||
* @param resultParam A parameter for the resultType. For stateful result types, the desired mpw_site_result.
|
||||
* @return A string (allocated) or NULL if the masterKey, siteName or resultParam is missing, the algorithm is unknown, or an algorithm error occurred. */
|
||||
const char *mpw_site_state(
|
||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||
const MPKeyPurpose keyPurpose, const char *keyContext,
|
||||
const MPResultType resultType, const char *resultParam,
|
||||
const MPAlgorithmVersion algorithmVersion);
|
||||
|
||||
/** @return An identicon (static) that represents the user's identity. */
|
||||
MPIdenticon mpw_identicon(
|
||||
const MPIdenticon mpw_identicon(
|
||||
const char *fullName, const char *masterPassword);
|
||||
/** @return An encoded representation (shared) of the given identicon or an empty string if the identicon is unset. */
|
||||
const char *mpw_identicon_encode(
|
||||
MPIdenticon identicon);
|
||||
const MPIdenticon identicon);
|
||||
/** @return An identicon (static) decoded from the given encoded identicon representation or an identicon with empty fields if the identicon could not be parsed. */
|
||||
MPIdenticon mpw_identicon_encoded(
|
||||
const MPIdenticon mpw_identicon_encoded(
|
||||
const char *encoding);
|
||||
|
||||
#endif // _MPW_ALGORITHM_H
|
||||
|
@ -23,7 +23,7 @@ MP_LIBS_BEGIN
|
||||
#include <string.h>
|
||||
MP_LIBS_END
|
||||
|
||||
char *mpw_get_token(const char **in, const char *eol, char *delim) {
|
||||
char *mpw_get_token(const char **in, const char *eol, const char *delim) {
|
||||
|
||||
// Skip leading spaces.
|
||||
for (; **in == ' '; ++*in);
|
||||
@ -60,7 +60,7 @@ time_t mpw_timegm(const char *time) {
|
||||
#if MPW_JSON
|
||||
|
||||
json_object *mpw_get_json_object(
|
||||
json_object *obj, const char *key, bool create) {
|
||||
json_object *obj, const char *key, const bool create) {
|
||||
|
||||
if (!obj)
|
||||
return NULL;
|
||||
@ -86,7 +86,7 @@ const char *mpw_get_json_string(
|
||||
}
|
||||
|
||||
int64_t mpw_get_json_int(
|
||||
json_object *obj, const char *key, int64_t defaultValue) {
|
||||
json_object *obj, const char *key, const int64_t defaultValue) {
|
||||
|
||||
json_object *json_value = mpw_get_json_object( obj, key, false );
|
||||
if (!json_value)
|
||||
@ -96,7 +96,7 @@ int64_t mpw_get_json_int(
|
||||
}
|
||||
|
||||
bool mpw_get_json_boolean(
|
||||
json_object *obj, const char *key, bool defaultValue) {
|
||||
json_object *obj, const char *key, const bool defaultValue) {
|
||||
|
||||
json_object *json_value = mpw_get_json_object( obj, key, false );
|
||||
if (!json_value)
|
||||
@ -107,7 +107,7 @@ bool mpw_get_json_boolean(
|
||||
|
||||
#endif
|
||||
|
||||
bool mpw_update_master_key(MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, MPAlgorithmVersion targetKeyAlgorithm,
|
||||
bool mpw_update_master_key(MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, const MPAlgorithmVersion targetKeyAlgorithm,
|
||||
const char *fullName, const char *masterPassword) {
|
||||
|
||||
if (masterKey && (!*masterKey || *masterKeyAlgorithm != targetKeyAlgorithm)) {
|
||||
|
@ -34,7 +34,7 @@ MP_LIBS_END
|
||||
* The input string reference is advanced beyond the token delimitor if one is found.
|
||||
* @return A string (allocated) containing the token or NULL if the delim wasn't found before eol. */
|
||||
char *mpw_get_token(
|
||||
const char **in, const char *eol, char *delim);
|
||||
const char **in, const char *eol, const char *delim);
|
||||
/** Convert an RFC 3339 time string into epoch time.
|
||||
* @return ERR if the string could not be parsed. */
|
||||
time_t mpw_timegm(
|
||||
@ -48,7 +48,7 @@ time_t mpw_timegm(
|
||||
* @param create If true, create and insert new objects for any missing path components.
|
||||
* @return An object (shared) or a new object (shared) installed in the tree if the path's object path was not found. */
|
||||
json_object *mpw_get_json_object(
|
||||
json_object *obj, const char *key, bool create);
|
||||
json_object *obj, const char *key, const bool create);
|
||||
/** Search for a string in a JSON object tree.
|
||||
* @param key A dot-delimited list of JSON object keys to walk toward the child object.
|
||||
* @return A string (shared) or defaultValue if one of the path's object keys was not found in the source object's tree. */
|
||||
@ -58,12 +58,12 @@ const char *mpw_get_json_string(
|
||||
* @param key A dot-delimited list of JSON object keys to walk toward the child object.
|
||||
* @return The integer value or defaultValue if one of the path's object keys was not found in the source object's tree. */
|
||||
int64_t mpw_get_json_int(
|
||||
json_object *obj, const char *key, int64_t defaultValue);
|
||||
json_object *obj, const char *key, const int64_t defaultValue);
|
||||
/** Search for a boolean in a JSON object tree.
|
||||
* @param key A dot-delimited list of JSON object keys to walk toward the child object.
|
||||
* @return The boolean value or defaultValue if one of the path's object keys was not found in the source object's tree. */
|
||||
bool mpw_get_json_boolean(
|
||||
json_object *obj, const char *key, bool defaultValue);
|
||||
json_object *obj, const char *key, const bool defaultValue);
|
||||
#endif
|
||||
|
||||
/// mpw.
|
||||
@ -72,7 +72,7 @@ bool mpw_get_json_boolean(
|
||||
* @param masterKey A buffer (allocated, MPMasterKeySize).
|
||||
* @return false if an error occurred during the derivation of the master key. */
|
||||
bool mpw_update_master_key(
|
||||
MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, MPAlgorithmVersion targetKeyAlgorithm,
|
||||
MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, const MPAlgorithmVersion targetKeyAlgorithm,
|
||||
const char *fullName, const char *masterPassword);
|
||||
|
||||
#endif // _MPW_MARSHAL_UTIL_H
|
||||
|
@ -120,75 +120,309 @@ MPMarshalledFile *mpw_marshal_file(
|
||||
return file;
|
||||
}
|
||||
|
||||
bool mpw_marshal_info_free(
|
||||
void mpw_marshal_info_free(
|
||||
MPMarshalInfo **info) {
|
||||
|
||||
if (!info || !*info)
|
||||
return true;
|
||||
return;
|
||||
|
||||
bool success = true;
|
||||
success &= mpw_free_strings( &(*info)->fullName, &(*info)->keyID, NULL );
|
||||
success &= mpw_free( info, sizeof( MPMarshalInfo ) );
|
||||
|
||||
return success;
|
||||
mpw_free_strings( &(*info)->fullName, &(*info)->keyID, NULL );
|
||||
mpw_free( info, sizeof( MPMarshalInfo ) );
|
||||
}
|
||||
|
||||
static bool mpw_marshal_user_free(
|
||||
void mpw_marshal_user_free(
|
||||
MPMarshalledUser **user) {
|
||||
|
||||
if (!user || !*user)
|
||||
return true;
|
||||
return;
|
||||
|
||||
bool success = mpw_free_strings( &(*user)->fullName, &(*user)->keyID, NULL );
|
||||
mpw_free_strings( &(*user)->fullName, &(*user)->keyID, NULL );
|
||||
|
||||
for (size_t s = 0; s < (*user)->sites_count; ++s) {
|
||||
MPMarshalledSite *site = &(*user)->sites[s];
|
||||
success &= mpw_free_strings( &site->siteName, &site->resultState, &site->loginState, &site->url, NULL );
|
||||
mpw_free_strings( &site->siteName, &site->resultState, &site->loginState, &site->url, NULL );
|
||||
|
||||
for (size_t q = 0; q < site->questions_count; ++q) {
|
||||
MPMarshalledQuestion *question = &site->questions[q];
|
||||
success &= mpw_free_strings( &question->keyword, &question->state, NULL );
|
||||
mpw_free_strings( &question->keyword, &question->state, NULL );
|
||||
}
|
||||
success &= mpw_free( &site->questions, sizeof( MPMarshalledQuestion ) * site->questions_count );
|
||||
mpw_free( &site->questions, sizeof( MPMarshalledQuestion ) * site->questions_count );
|
||||
}
|
||||
|
||||
success &= mpw_free( &(*user)->sites, sizeof( MPMarshalledSite ) * (*user)->sites_count );
|
||||
success &= mpw_free( user, sizeof( MPMarshalledUser ) );
|
||||
|
||||
return success;
|
||||
mpw_free( &(*user)->sites, sizeof( MPMarshalledSite ) * (*user)->sites_count );
|
||||
mpw_free( user, sizeof( MPMarshalledUser ) );
|
||||
}
|
||||
|
||||
static bool mpw_marshal_data_null(
|
||||
MPMarshalledData *data) {
|
||||
|
||||
if (!data)
|
||||
return true;
|
||||
|
||||
bool success = mpw_free_strings( &data->key, &data->str_value, NULL );
|
||||
for (unsigned int c = 0; c < data->children_count; ++c)
|
||||
success &= mpw_marshal_data_null( &data->children[c] );
|
||||
success &= mpw_free( &data->children, sizeof( MPMarshalledData ) * data->children_count );
|
||||
data->children_count = 0;
|
||||
data->num_value = NAN;
|
||||
data->is_bool = false;
|
||||
data->is_null = true;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool mpw_marshal_free(
|
||||
void mpw_marshal_file_free(
|
||||
MPMarshalledFile **file) {
|
||||
|
||||
if (!file || !*file)
|
||||
return true;
|
||||
return;
|
||||
|
||||
bool success = true;
|
||||
mpw_marshal_info_free( &(*file)->info );
|
||||
mpw_marshal_user_free( &(*file)->user );
|
||||
if ((*file)->data) {
|
||||
mpw_marshal_data_set_null( (*file)->data, NULL );
|
||||
mpw_free_string( &(*file)->data->key );
|
||||
mpw_free( &(*file)->data, sizeof( MPMarshalledData ) );
|
||||
}
|
||||
mpw_free( file, sizeof( MPMarshalledFile ) );
|
||||
}
|
||||
|
||||
success &= mpw_marshal_info_free( &(*file)->info );
|
||||
success &= mpw_marshal_user_free( &(*file)->user );
|
||||
success &= mpw_marshal_data_null( (*file)->data );
|
||||
success &= mpw_free( &(*file)->data, sizeof( MPMarshalledData ) );
|
||||
success &= mpw_free( file, sizeof( MPMarshalledFile ) );
|
||||
MPMarshalledData *mpw_marshal_data_new() {
|
||||
|
||||
MPMarshalledData *data = malloc( sizeof( MPMarshalledData ) );
|
||||
*data = (MPMarshalledData){};
|
||||
mpw_marshal_data_set_null( data, NULL );
|
||||
return data;
|
||||
}
|
||||
|
||||
MPMarshalledData *mpw_marshal_data_vget(
|
||||
MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
MPMarshalledData *parent = data, *child;
|
||||
for (const char *node; parent && (node = va_arg( nodes, const char * )); parent = child) {
|
||||
child = NULL;
|
||||
|
||||
for (size_t c = 0; c < parent->children_count; ++c) {
|
||||
const char *key = parent->children[c].key;
|
||||
if (key && strcmp( node, key ) == OK) {
|
||||
child = &parent->children[c];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!child) {
|
||||
if (!mpw_realloc( &parent->children, NULL, sizeof( MPMarshalledData ) * ++parent->children_count )) {
|
||||
--parent->children_count;
|
||||
break;
|
||||
}
|
||||
*(child = &parent->children[parent->children_count - 1]) = (MPMarshalledData){ .key = mpw_strdup( node ) };
|
||||
mpw_marshal_data_set_null( child, NULL );
|
||||
child->is_null = false;
|
||||
}
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
MPMarshalledData *mpw_marshal_data_get(
|
||||
MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
const MPMarshalledData *mpw_marshal_data_vfind(
|
||||
const MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
const MPMarshalledData *parent = data, *child;
|
||||
for (const char *node; parent && (node = va_arg( nodes, const char * )); parent = child) {
|
||||
child = NULL;
|
||||
|
||||
for (size_t c = 0; c < parent->children_count; ++c) {
|
||||
const char *key = parent->children[c].key;
|
||||
if (key && strcmp( node, key ) == OK) {
|
||||
child = &parent->children[c];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!child)
|
||||
break;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
const MPMarshalledData *mpw_marshal_data_find(
|
||||
const MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_vis_null(
|
||||
const MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
|
||||
return !child || child->is_null;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_is_null(
|
||||
const MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
bool value = mpw_marshal_data_vis_null( data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_vset_null(
|
||||
MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
|
||||
if (!child)
|
||||
return false;
|
||||
|
||||
mpw_free_string( &child->str_value );
|
||||
for (unsigned int c = 0; c < child->children_count; ++c) {
|
||||
mpw_marshal_data_set_null( &child->children[c], NULL );
|
||||
mpw_free_string( &child->children[c].key );
|
||||
}
|
||||
mpw_free( &child->children, sizeof( MPMarshalledData ) * child->children_count );
|
||||
child->children_count = 0;
|
||||
child->num_value = NAN;
|
||||
child->is_bool = false;
|
||||
child->is_null = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_set_null(
|
||||
MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
bool success = mpw_marshal_data_vset_null( data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_vget_bool(
|
||||
const MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
|
||||
return child && child->is_bool && child->num_value != false;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_get_bool(
|
||||
const MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
bool value = mpw_marshal_data_vget_bool( data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_vset_bool(
|
||||
const bool value, MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
|
||||
if (!child || !mpw_marshal_data_set_null( child, NULL ))
|
||||
return false;
|
||||
|
||||
child->is_null = false;
|
||||
child->is_bool = true;
|
||||
child->num_value = value != false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_set_bool(
|
||||
const bool value, MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
bool success = mpw_marshal_data_vset_bool( value, data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
double mpw_marshal_data_vget_num(
|
||||
const MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
|
||||
return child == NULL? NAN: child->num_value;
|
||||
}
|
||||
|
||||
double mpw_marshal_data_get_num(
|
||||
const MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
double value = mpw_marshal_data_vget_num( data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_vset_num(
|
||||
const double value, MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
|
||||
if (!child || !mpw_marshal_data_set_null( child, NULL ))
|
||||
return false;
|
||||
|
||||
child->is_null = false;
|
||||
child->num_value = value;
|
||||
child->str_value = mpw_strdup( mpw_str( "%g", value ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_set_num(
|
||||
const double value, MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
bool success = mpw_marshal_data_vset_num( value, data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
const char *mpw_marshal_data_vget_str(
|
||||
const MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
|
||||
return child == NULL? NULL: mpw_strdup( child->str_value );
|
||||
}
|
||||
|
||||
const char *mpw_marshal_data_get_str(
|
||||
const MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
const char *value = mpw_marshal_data_vget_str( data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_vset_str(
|
||||
const char *value, MPMarshalledData *data, va_list nodes) {
|
||||
|
||||
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
|
||||
if (!child || !mpw_marshal_data_set_null( child, NULL ))
|
||||
return false;
|
||||
|
||||
if (value) {
|
||||
child->is_null = false;
|
||||
child->str_value = mpw_strdup( value );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mpw_marshal_data_set_str(
|
||||
const char *value, MPMarshalledData *data, ...) {
|
||||
|
||||
va_list nodes;
|
||||
va_start( nodes, data );
|
||||
bool success = mpw_marshal_data_vset_str( value, data, nodes );
|
||||
va_end( nodes );
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -285,20 +519,24 @@ static const char *mpw_marshal_write_flat(
|
||||
#if MPW_JSON
|
||||
|
||||
static json_object *mpw_get_json_data(
|
||||
MPMarshalledData *data) {
|
||||
const MPMarshalledData *data) {
|
||||
|
||||
if (!data || data->is_null)
|
||||
return NULL;
|
||||
if (data->is_bool)
|
||||
return json_object_new_boolean( data->num_value != false );
|
||||
if (!isnan( data->num_value ))
|
||||
return json_object_new_double_s( data->num_value, data->str_value );
|
||||
if (!isnan( data->num_value )) {
|
||||
if (data->str_value)
|
||||
return json_object_new_double_s( data->num_value, data->str_value );
|
||||
else
|
||||
return json_object_new_double( data->num_value );
|
||||
}
|
||||
if (data->str_value)
|
||||
return json_object_new_string( data->str_value );
|
||||
|
||||
json_object *obj = NULL;
|
||||
for (size_t index = 0; index < data->children_count; ++index) {
|
||||
MPMarshalledData *child = &data->children[index];
|
||||
for (size_t c = 0; c < data->children_count; ++c) {
|
||||
MPMarshalledData *child = &data->children[c];
|
||||
if (!obj) {
|
||||
if (child->key)
|
||||
obj = json_object_new_object();
|
||||
@ -505,8 +743,8 @@ static void mpw_marshal_read_flat_info(
|
||||
break;
|
||||
|
||||
// Header
|
||||
char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" );
|
||||
char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" );
|
||||
const char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" );
|
||||
const char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" );
|
||||
if (!headerName || !headerValue)
|
||||
continue;
|
||||
|
||||
@ -605,8 +843,8 @@ static MPMarshalledFile *mpw_marshal_read_flat(
|
||||
}
|
||||
|
||||
// Header
|
||||
char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" );
|
||||
char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" );
|
||||
const char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" );
|
||||
const char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" );
|
||||
if (!headerName || !headerValue) {
|
||||
error->type = MPMarshalErrorStructure;
|
||||
error->message = mpw_str( "Invalid header: %s", mpw_strndup( positionInLine, (size_t)(endOfLine - positionInLine) ) );
|
||||
@ -672,8 +910,8 @@ static MPMarshalledFile *mpw_marshal_read_flat(
|
||||
continue;
|
||||
|
||||
// Site
|
||||
char *siteName = NULL, *siteResultState = NULL, *siteLoginState = NULL;
|
||||
char *str_lastUsed = NULL, *str_uses = NULL, *str_type = NULL, *str_algorithm = NULL, *str_counter = NULL;
|
||||
const char *siteName = NULL, *siteResultState = NULL, *siteLoginState = NULL;
|
||||
const char *str_lastUsed = NULL, *str_uses = NULL, *str_type = NULL, *str_algorithm = NULL, *str_counter = NULL;
|
||||
switch (format) {
|
||||
case 0: {
|
||||
str_lastUsed = mpw_get_token( &positionInLine, endOfLine, " \t\n" );
|
||||
@ -834,6 +1072,9 @@ static MPMarshalledFile *mpw_marshal_read_flat(
|
||||
static void mpw_set_json_data(
|
||||
MPMarshalledData *data, json_object *obj) {
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
json_type type = json_object_get_type( obj );
|
||||
data->is_null = type == json_type_null;
|
||||
data->is_bool = type == json_type_boolean;
|
||||
@ -860,16 +1101,15 @@ static void mpw_set_json_data(
|
||||
size_t newChildrenCount = 0;
|
||||
for (size_t c = 0; c < data->children_count; ++c) {
|
||||
MPMarshalledData *child = &data->children[c];
|
||||
if ((type != json_type_object && type != json_type_array) ||
|
||||
(child->key && type != json_type_object) || (!isnan( child->index ) && type != json_type_array)) {
|
||||
mpw_marshal_data_null( child );
|
||||
if (!newChildren) {
|
||||
newChildren = malloc( sizeof( MPMarshalledData ) * newChildrenCount );
|
||||
if (newChildren)
|
||||
memcpy( newChildren, data->children, sizeof( MPMarshalledData ) * newChildrenCount );
|
||||
}
|
||||
if ((type != json_type_object && type != json_type_array) || (child->key && type != json_type_object)) {
|
||||
// Not a valid child in this object, remove it.
|
||||
mpw_marshal_data_set_null( child, NULL );
|
||||
mpw_free_string( &child->key );
|
||||
if (!newChildren)
|
||||
newChildren = mpw_memdup( data->children, sizeof( MPMarshalledData ) * newChildrenCount );
|
||||
}
|
||||
else {
|
||||
// Valid child in this object, keep it.
|
||||
++newChildrenCount;
|
||||
if (newChildren) {
|
||||
if (!mpw_realloc( &newChildren, NULL, sizeof( MPMarshalledData ) * newChildrenCount )) {
|
||||
@ -896,7 +1136,7 @@ static void mpw_set_json_data(
|
||||
// Find existing child.
|
||||
for (size_t c = 0; c < data->children_count; ++c)
|
||||
if (data->children[c].key == entry.key ||
|
||||
(data->children[c].key && entry.key && strcmp( data->children[c].key, entry.key )) == OK) {
|
||||
(data->children[c].key && entry.key && strcmp( data->children[c].key, entry.key ) == OK)) {
|
||||
child = &data->children[c];
|
||||
break;
|
||||
}
|
||||
@ -965,7 +1205,7 @@ static void mpw_marshal_read_json_info(
|
||||
}
|
||||
|
||||
static MPMarshalledFile *mpw_marshal_read_json(
|
||||
const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
|
||||
const char *in, const MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
|
||||
|
||||
*error = (MPMarshalError){ MPMarshalErrorInternal, "Unexpected internal error." };
|
||||
if (!in || !strlen( in )) {
|
||||
@ -1173,11 +1413,8 @@ static MPMarshalledFile *mpw_marshal_read_json(
|
||||
}
|
||||
mpw_free( &masterKey, MPMasterKeySize );
|
||||
|
||||
MPMarshalledData *data = malloc( sizeof( MPMarshalledData ) );
|
||||
if (data) {
|
||||
*data = (MPMarshalledData){};
|
||||
mpw_set_json_data( data, json_file );
|
||||
}
|
||||
MPMarshalledData *data = mpw_marshal_data_new();
|
||||
mpw_set_json_data( data, json_file );
|
||||
json_object_put( json_file );
|
||||
|
||||
MPMarshalledFile *file = mpw_marshal_file( user, data );
|
||||
@ -1223,7 +1460,7 @@ MPMarshalInfo *mpw_marshal_read_info(
|
||||
}
|
||||
|
||||
MPMarshalledFile *mpw_marshal_read(
|
||||
const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
|
||||
const char *in, const MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
|
||||
|
||||
MPMarshalInfo *info = mpw_marshal_read_info( in );
|
||||
if (!info)
|
||||
@ -1314,10 +1551,10 @@ const char **mpw_marshal_format_extensions(
|
||||
return NULL;
|
||||
case MPMarshalFormatFlat:
|
||||
return mpw_strings( count,
|
||||
mpw_marshal_format_extension( format ), "mpsites.txt", "txt" );
|
||||
mpw_marshal_format_extension( format ), "mpsites.txt", "txt", NULL );
|
||||
case MPMarshalFormatJSON:
|
||||
return mpw_strings( count,
|
||||
mpw_marshal_format_extension( format ), "mpsites.json", "json" );
|
||||
mpw_marshal_format_extension( format ), "mpsites.json", "json", NULL );
|
||||
default: {
|
||||
dbg( "Unknown format: %d", format );
|
||||
return NULL;
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
MP_LIBS_BEGIN
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
MP_LIBS_END
|
||||
|
||||
//// Types.
|
||||
@ -161,14 +162,14 @@ MPMarshalInfo *mpw_marshal_read_info(
|
||||
/** Unmarshall sites in the given input buffer by parsing it using the given marshalling format.
|
||||
* @return A user object (allocated), or NULL if the format provides no marshalling or a format error occurred. */
|
||||
MPMarshalledFile *mpw_marshal_read(
|
||||
const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error);
|
||||
const char *in, const MPMasterKeyProvider masterKeyProvider, MPMarshalError *error);
|
||||
|
||||
//// Utilities.
|
||||
//// Creating.
|
||||
|
||||
/** Create a new user object ready for marshalling.
|
||||
* @return A user object (allocated), or NULL if the fullName is missing or the marshalled user couldn't be allocated. */
|
||||
MPMarshalledUser *mpw_marshal_user(
|
||||
const char *fullName, MPMasterKeyProvider masterKeyProvider, const MPAlgorithmVersion algorithmVersion);
|
||||
const char *fullName, const MPMasterKeyProvider masterKeyProvider, const MPAlgorithmVersion algorithmVersion);
|
||||
/** Create a new site attached to the given user object, ready for marshalling.
|
||||
* @return A site object (allocated), or NULL if the siteName is missing or the marshalled site couldn't be allocated. */
|
||||
MPMarshalledSite *mpw_marshal_site(
|
||||
@ -183,11 +184,77 @@ MPMarshalledQuestion *mpw_marshal_question(
|
||||
MPMarshalledFile *mpw_marshal_file(
|
||||
MPMarshalledUser *user, MPMarshalledData *data);
|
||||
|
||||
//// Disposing.
|
||||
|
||||
/** Free the given user object and all associated data. */
|
||||
bool mpw_marshal_info_free(
|
||||
void mpw_marshal_info_free(
|
||||
MPMarshalInfo **info);
|
||||
bool mpw_marshal_free(
|
||||
MPMarshalledFile **user);
|
||||
void mpw_marshal_user_free(
|
||||
MPMarshalledUser **user);
|
||||
void mpw_marshal_file_free(
|
||||
MPMarshalledFile **file);
|
||||
|
||||
//// Exploring.
|
||||
|
||||
/** Create a null value.
|
||||
* @return A new data value (allocated), initialized to a null value, or NULL if the value couldn't be allocated. */
|
||||
MPMarshalledData *mpw_marshal_data_new(void);
|
||||
/** Get or create a value for the given path in the data store.
|
||||
* @return The value at this path (shared), or NULL if the value didn't exist and couldn't be created. */
|
||||
MPMarshalledData *mpw_marshal_data_get(
|
||||
MPMarshalledData *data, ...);
|
||||
MPMarshalledData *mpw_marshal_data_vget(
|
||||
MPMarshalledData *data, va_list nodes);
|
||||
/** Look up the value at the given path in the data store.
|
||||
* @return The value at this path (shared), or NULL if there is no value at this path. */
|
||||
const MPMarshalledData *mpw_marshal_data_find(
|
||||
const MPMarshalledData *data, ...);
|
||||
const MPMarshalledData *mpw_marshal_data_vfind(
|
||||
const MPMarshalledData *data, va_list nodes);
|
||||
/** Check if the data represents a NULL value.
|
||||
* @return true if the value at this path is null or is missing, false if it is a non-null type. */
|
||||
bool mpw_marshal_data_is_null(
|
||||
const MPMarshalledData *data, ...);
|
||||
bool mpw_marshal_data_vis_null(
|
||||
const MPMarshalledData *data, va_list nodes);
|
||||
/** Set a null value at the given path in the data store.
|
||||
* @return true if the object was successfully modified. */
|
||||
bool mpw_marshal_data_set_null(
|
||||
MPMarshalledData *data, ...);
|
||||
bool mpw_marshal_data_vset_null(
|
||||
MPMarshalledData *data, va_list nodes);
|
||||
/** Look up the boolean value at the given path in the data store.
|
||||
* @return true if the value at this path is true, false if it is not or there is no boolean value at this path. */
|
||||
bool mpw_marshal_data_get_bool(
|
||||
const MPMarshalledData *data, ...);
|
||||
bool mpw_marshal_data_vget_bool(
|
||||
const MPMarshalledData *data, va_list nodes);
|
||||
/** Set a boolean value at the given path in the data store.
|
||||
* @return true if the object was successfully modified. */
|
||||
bool mpw_marshal_data_set_bool(
|
||||
const bool value, MPMarshalledData *data, ...);
|
||||
bool mpw_marshal_data_vset_bool(
|
||||
const bool value, MPMarshalledData *data, va_list nodes);
|
||||
/** Look up the numeric value at the given path in the data store.
|
||||
* @return A number or NAN if there is no numeric value at this path. */
|
||||
double mpw_marshal_data_get_num(
|
||||
const MPMarshalledData *data, ...);
|
||||
double mpw_marshal_data_vget_num(
|
||||
const MPMarshalledData *data, va_list nodes);
|
||||
bool mpw_marshal_data_set_num(
|
||||
const double value, MPMarshalledData *data, ...);
|
||||
bool mpw_marshal_data_vset_num(
|
||||
const double value, MPMarshalledData *data, va_list nodes);
|
||||
/** Look up the string value at the given path in the data store.
|
||||
* @return The string value (allocated) or string representation of the number at this path; NULL if there is no such value at this path. */
|
||||
const char *mpw_marshal_data_get_str(
|
||||
const MPMarshalledData *data, ...);
|
||||
const char *mpw_marshal_data_vget_str(
|
||||
const MPMarshalledData *data, va_list nodes);
|
||||
bool mpw_marshal_data_set_str(
|
||||
const char *value, MPMarshalledData *data, ...);
|
||||
bool mpw_marshal_data_vset_str(
|
||||
const char *value, MPMarshalledData *data, va_list nodes);
|
||||
|
||||
//// Format.
|
||||
|
||||
|
@ -90,7 +90,7 @@ const MPResultType mpw_type_named(const char *typeName) {
|
||||
return (MPResultType)ERR;
|
||||
}
|
||||
|
||||
const char *mpw_type_abbreviation(MPResultType resultType) {
|
||||
const char *mpw_type_abbreviation(const MPResultType resultType) {
|
||||
|
||||
switch (resultType) {
|
||||
case MPResultTypeTemplateMaximum:
|
||||
@ -122,7 +122,7 @@ const char *mpw_type_abbreviation(MPResultType resultType) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *mpw_type_short_name(MPResultType resultType) {
|
||||
const char *mpw_type_short_name(const MPResultType resultType) {
|
||||
|
||||
switch (resultType) {
|
||||
case MPResultTypeTemplateMaximum:
|
||||
@ -154,7 +154,7 @@ const char *mpw_type_short_name(MPResultType resultType) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *mpw_type_long_name(MPResultType resultType) {
|
||||
const char *mpw_type_long_name(const MPResultType resultType) {
|
||||
|
||||
switch (resultType) {
|
||||
case MPResultTypeTemplateMaximum:
|
||||
@ -186,7 +186,7 @@ const char *mpw_type_long_name(MPResultType resultType) {
|
||||
}
|
||||
}
|
||||
|
||||
const char **mpw_type_templates(MPResultType type, size_t *count) {
|
||||
const char **mpw_type_templates(const MPResultType type, size_t *count) {
|
||||
|
||||
if (!(type & MPResultTypeClassTemplate)) {
|
||||
dbg( "Not a generated type: %d", type );
|
||||
@ -231,7 +231,7 @@ const char **mpw_type_templates(MPResultType type, size_t *count) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *mpw_type_template(MPResultType type, uint8_t templateIndex) {
|
||||
const char *mpw_type_template(const MPResultType type, const uint8_t templateIndex) {
|
||||
|
||||
size_t count = 0;
|
||||
const char **templates = mpw_type_templates( type, &count );
|
||||
@ -254,7 +254,7 @@ const MPKeyPurpose mpw_purpose_named(const char *purposeName) {
|
||||
return (MPKeyPurpose)ERR;
|
||||
}
|
||||
|
||||
const char *mpw_purpose_name(MPKeyPurpose purpose) {
|
||||
const char *mpw_purpose_name(const MPKeyPurpose purpose) {
|
||||
|
||||
switch (purpose) {
|
||||
case MPKeyPurposeAuthentication:
|
||||
@ -270,7 +270,7 @@ const char *mpw_purpose_name(MPKeyPurpose purpose) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *mpw_purpose_scope(MPKeyPurpose purpose) {
|
||||
const char *mpw_purpose_scope(const MPKeyPurpose purpose) {
|
||||
|
||||
switch (purpose) {
|
||||
case MPKeyPurposeAuthentication:
|
||||
@ -286,7 +286,7 @@ const char *mpw_purpose_scope(MPKeyPurpose purpose) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *mpw_class_characters(char characterClass) {
|
||||
const char *mpw_class_characters(const char characterClass) {
|
||||
|
||||
switch (characterClass) {
|
||||
case 'V':
|
||||
@ -316,7 +316,7 @@ const char *mpw_class_characters(char characterClass) {
|
||||
}
|
||||
}
|
||||
|
||||
const char mpw_class_character(char characterClass, uint8_t seedByte) {
|
||||
const char mpw_class_character(const char characterClass, const uint8_t seedByte) {
|
||||
|
||||
const char *classCharacters = mpw_class_characters( characterClass );
|
||||
if (!classCharacters || !strlen( classCharacters ))
|
||||
|
@ -152,11 +152,11 @@ const MPKeyPurpose mpw_purpose_named(const char *purposeName);
|
||||
/**
|
||||
* @return The standard name (static) for the given purpose or NULL if the purpose is not known.
|
||||
*/
|
||||
const char *mpw_purpose_name(MPKeyPurpose purpose);
|
||||
const char *mpw_purpose_name(const MPKeyPurpose purpose);
|
||||
/**
|
||||
* @return The scope identifier (static) to apply when encoding for the given purpose or NULL if the purpose is not known.
|
||||
*/
|
||||
const char *mpw_purpose_scope(MPKeyPurpose purpose);
|
||||
const char *mpw_purpose_scope(const MPKeyPurpose purpose);
|
||||
|
||||
/**
|
||||
* @return The password type represented by the given name or ERR if the name does not represent a known type.
|
||||
@ -165,34 +165,34 @@ const MPResultType mpw_type_named(const char *typeName);
|
||||
/**
|
||||
* @return The standard identifying name (static) for the given password type or NULL if the type is not known.
|
||||
*/
|
||||
const char *mpw_type_abbreviation(MPResultType resultType);
|
||||
const char *mpw_type_abbreviation(const MPResultType resultType);
|
||||
/**
|
||||
* @return The standard identifying name (static) for the given password type or NULL if the type is not known.
|
||||
*/
|
||||
const char *mpw_type_short_name(MPResultType resultType);
|
||||
const char *mpw_type_short_name(const MPResultType resultType);
|
||||
/**
|
||||
* @return The descriptive name (static) for the given password type or NULL if the type is not known.
|
||||
*/
|
||||
const char *mpw_type_long_name(MPResultType resultType);
|
||||
const char *mpw_type_long_name(const MPResultType resultType);
|
||||
|
||||
/**
|
||||
* @return An array (allocated, count) of strings (static) that express the templates to use for the given type.
|
||||
* NULL if the type is not known or is not a MPResultTypeClassTemplate.
|
||||
*/
|
||||
const char **mpw_type_templates(MPResultType type, size_t *count);
|
||||
const char **mpw_type_templates(const MPResultType type, size_t *count);
|
||||
/**
|
||||
* @return A string (static) that contains the password encoding template of the given type for a seed that starts with the given byte.
|
||||
* NULL if the type is not known or is not a MPResultTypeClassTemplate.
|
||||
*/
|
||||
const char *mpw_type_template(MPResultType type, uint8_t templateIndex);
|
||||
const char *mpw_type_template(const MPResultType type, const uint8_t templateIndex);
|
||||
|
||||
/**
|
||||
* @return An string (static) with all the characters in the given character class or NULL if the character class is not known.
|
||||
*/
|
||||
const char *mpw_class_characters(char characterClass);
|
||||
const char *mpw_class_characters(const char characterClass);
|
||||
/**
|
||||
* @return A character from given character class that encodes the given byte or NUL if the character class is not known or is empty.
|
||||
*/
|
||||
const char mpw_class_character(char characterClass, uint8_t seedByte);
|
||||
const char mpw_class_character(const char characterClass, const uint8_t seedByte);
|
||||
|
||||
#endif // _MPW_TYPES_H
|
||||
|
@ -175,7 +175,7 @@ bool __mpw_free(void **buffer, const size_t bufferSize) {
|
||||
|
||||
bool __mpw_free_string(char **string) {
|
||||
|
||||
return *string && __mpw_free( (void **)string, strlen( *string ) );
|
||||
return string && *string && __mpw_free( (void **)string, strlen( *string ) );
|
||||
}
|
||||
|
||||
bool __mpw_free_strings(char **strings, ...) {
|
||||
@ -193,7 +193,7 @@ bool __mpw_free_strings(char **strings, ...) {
|
||||
}
|
||||
|
||||
uint8_t const *mpw_kdf_scrypt(const size_t keySize, const uint8_t *secret, const size_t secretSize, const uint8_t *salt, const size_t saltSize,
|
||||
uint64_t N, uint32_t r, uint32_t p) {
|
||||
const uint64_t N, const uint32_t r, const uint32_t p) {
|
||||
|
||||
if (!secret || !salt || !secretSize || !saltSize)
|
||||
return NULL;
|
||||
@ -367,7 +367,7 @@ const char *mpw_hotp(const uint8_t *key, size_t keySize, uint64_t movingFactor,
|
||||
}
|
||||
#endif
|
||||
|
||||
MPKeyID mpw_id_buf(const void *buf, size_t length) {
|
||||
const MPKeyID mpw_id_buf(const void *buf, const size_t length) {
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
@ -443,7 +443,7 @@ const char *mpw_vstr(const char *format, va_list args) {
|
||||
return str_str[str_str_i];
|
||||
}
|
||||
|
||||
const char *mpw_hex(const void *buf, size_t length) {
|
||||
const char *mpw_hex(const void *buf, const size_t length) {
|
||||
|
||||
if (!buf || !length)
|
||||
return NULL;
|
||||
@ -461,7 +461,7 @@ const char *mpw_hex(const void *buf, size_t length) {
|
||||
return mpw_hex_buf[mpw_hex_buf_i];
|
||||
}
|
||||
|
||||
const char *mpw_hex_l(uint32_t number) {
|
||||
const char *mpw_hex_l(const uint32_t number) {
|
||||
|
||||
uint8_t buf[4 /* 32 / 8 */];
|
||||
buf[0] = (uint8_t)((number >> 24) & UINT8_MAX);
|
||||
@ -496,7 +496,7 @@ size_t mpw_utf8_strchars(const char *utf8String) {
|
||||
return strchars;
|
||||
}
|
||||
|
||||
void *mpw_memdup(const void *src, size_t len) {
|
||||
void *mpw_memdup(const void *src, const size_t len) {
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
@ -517,7 +517,7 @@ char *mpw_strdup(const char *src) {
|
||||
return mpw_memdup( src, len + 1 );
|
||||
}
|
||||
|
||||
char *mpw_strndup(const char *src, size_t max) {
|
||||
char *mpw_strndup(const char *src, const size_t max) {
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
@ -525,8 +525,7 @@ char *mpw_strndup(const char *src, size_t max) {
|
||||
size_t len = 0;
|
||||
for (; len < max && src[len] != '\0'; ++len);
|
||||
|
||||
char *dst = malloc( len + 1 );
|
||||
memcpy( dst, src, len );
|
||||
char *dst = mpw_memdup( src, len + 1 );
|
||||
dst[len] = '\0';
|
||||
|
||||
return dst;
|
||||
|
@ -122,7 +122,7 @@ bool mpw_string_push(
|
||||
bool mpw_string_pushf(
|
||||
char **string, const char *pushFormat, ...);
|
||||
|
||||
// These defines merely exist to force the void** cast (& do type-checking), since void** casts are not automatic.
|
||||
// These defines merely exist to do type-checking, force the void** cast & drop any const qualifier.
|
||||
/** Reallocate the given buffer from the given size by adding the delta size.
|
||||
* On success, the buffer size pointer will be updated to the buffer's new size
|
||||
* and the buffer pointer may be updated to a new memory address.
|
||||
@ -176,7 +176,7 @@ bool __mpw_free_string(
|
||||
bool __mpw_free_strings(
|
||||
char **strings, ...);
|
||||
void mpw_zero(
|
||||
void *buffer, size_t bufferSize);
|
||||
void *buffer, const size_t bufferSize);
|
||||
|
||||
//// Cryptographic functions.
|
||||
|
||||
@ -184,7 +184,7 @@ void mpw_zero(
|
||||
* @return A buffer (allocated, keySize) containing the key or NULL if secret or salt is missing, key could not be allocated or the KDF failed. */
|
||||
uint8_t const *mpw_kdf_scrypt(
|
||||
const size_t keySize, const uint8_t *secret, const size_t secretSize, const uint8_t *salt, const size_t saltSize,
|
||||
uint64_t N, uint32_t r, uint32_t p);
|
||||
const uint64_t N, const uint32_t r, const uint32_t p);
|
||||
/** Derive a subkey from the given key using the blake2b KDF.
|
||||
* @return A buffer (allocated, keySize) containing the key or NULL if the key or subkeySize is missing, the key sizes are out of bounds, the subkey could not be allocated or derived. */
|
||||
uint8_t const *mpw_kdf_blake2b(
|
||||
@ -217,11 +217,11 @@ const char *mpw_str(const char *format, ...);
|
||||
const char *mpw_vstr(const char *format, va_list args);
|
||||
/** Encode a buffer as a string of hexadecimal characters.
|
||||
* @return A string (shared); or NULL if the buffer is missing or the result could not be allocated. */
|
||||
const char *mpw_hex(const void *buf, size_t length);
|
||||
const char *mpw_hex_l(uint32_t number);
|
||||
const char *mpw_hex(const void *buf, const size_t length);
|
||||
const char *mpw_hex_l(const uint32_t number);
|
||||
/** Encode a fingerprint for a buffer.
|
||||
* @return A string (shared); or NULL if the buffer is missing or the result could not be allocated. */
|
||||
MPKeyID mpw_id_buf(const void *buf, size_t length);
|
||||
const MPKeyID mpw_id_buf(const void *buf, const size_t length);
|
||||
/** Compare two fingerprints for equality.
|
||||
* @return true if the buffers represent identical fingerprints or are both NULL. */
|
||||
bool mpw_id_buf_equals(const char *id1, const char *id2);
|
||||
@ -234,14 +234,14 @@ size_t mpw_utf8_charlen(const char *utf8String);
|
||||
size_t mpw_utf8_strchars(const char *utf8String);
|
||||
/** Drop-in for memdup(3).
|
||||
* @return A buffer (allocated, len) with len bytes copied from src or NULL if src is missing or the buffer could not be allocated. */
|
||||
void *mpw_memdup(const void *src, size_t len);
|
||||
void *mpw_memdup(const void *src, const size_t len);
|
||||
/** Drop-in for POSIX strdup(3).
|
||||
* @return A string (allocated) copied from src or NULL if src is missing or the buffer could not be allocated. */
|
||||
char *mpw_strdup(const char *src);
|
||||
/** Drop-in for POSIX strndup(3).
|
||||
* @return A string (allocated) with no more than max bytes copied from src or NULL if src is missing or the buffer could not be allocated. */
|
||||
char *mpw_strndup(const char *src, size_t max);
|
||||
char *mpw_strndup(const char *src, const size_t max);
|
||||
/** Drop-in for POSIX strncasecmp(3). */
|
||||
int mpw_strncasecmp(const char *s1, const char *s2, size_t max);
|
||||
int mpw_strncasecmp(const char *s1, const char *s2, const size_t max);
|
||||
|
||||
#endif // _MPW_UTIL_H
|
||||
|
Loading…
Reference in New Issue
Block a user