Case insensitive compare values that don't need to rely on exact case.
This commit is contained in:
		@@ -385,7 +385,7 @@ void cli_masterPassword(Arguments *args, Operation *operation) {
 | 
			
		||||
    mpw_free_string( &operation->masterPassword );
 | 
			
		||||
 | 
			
		||||
    if (args->masterPasswordFD) {
 | 
			
		||||
        operation->masterPassword = mpw_read_fd( atoi( args->masterPasswordFD ) );
 | 
			
		||||
        operation->masterPassword = mpw_read_fd( (int)strtol( args->masterPasswordFD, NULL, 10 ) );
 | 
			
		||||
        if (!operation->masterPassword && errno)
 | 
			
		||||
            wrn( "Error reading master password from FD %s: %s", args->masterPasswordFD, strerror( errno ) );
 | 
			
		||||
    }
 | 
			
		||||
@@ -660,7 +660,7 @@ void cli_siteCounter(Arguments *args, Operation *operation) {
 | 
			
		||||
    if (!operation->site)
 | 
			
		||||
        abort();
 | 
			
		||||
 | 
			
		||||
    long long int siteCounterInt = atoll( args->siteCounter );
 | 
			
		||||
    long long int siteCounterInt = strtoll( args->siteCounter, NULL, 0 );
 | 
			
		||||
    if (siteCounterInt < MPCounterValueFirst || siteCounterInt > MPCounterValueLast) {
 | 
			
		||||
        ftl( "Invalid site counter: %s", args->siteCounter );
 | 
			
		||||
        cli_free( args, operation );
 | 
			
		||||
@@ -694,19 +694,19 @@ void cli_algorithmVersion(Arguments *args, Operation *operation) {
 | 
			
		||||
    if (!operation->site)
 | 
			
		||||
        abort();
 | 
			
		||||
 | 
			
		||||
    int algorithmVersionInt = atoi( args->algorithmVersion );
 | 
			
		||||
    if (algorithmVersionInt < MPAlgorithmVersionFirst || algorithmVersionInt > MPAlgorithmVersionLast) {
 | 
			
		||||
    unsigned long algorithmVersion = strtoul( args->algorithmVersion, NULL, 10 );
 | 
			
		||||
    if (algorithmVersion < MPAlgorithmVersionFirst || algorithmVersion > MPAlgorithmVersionLast) {
 | 
			
		||||
        ftl( "Invalid algorithm version: %s", args->algorithmVersion );
 | 
			
		||||
        cli_free( args, operation );
 | 
			
		||||
        exit( EX_USAGE );
 | 
			
		||||
    }
 | 
			
		||||
    operation->site->algorithm = (MPAlgorithmVersion)algorithmVersionInt;
 | 
			
		||||
    operation->site->algorithm = (MPAlgorithmVersion)algorithmVersion;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cli_sitesRedacted(Arguments *args, Operation *operation) {
 | 
			
		||||
 | 
			
		||||
    if (args->sitesRedacted)
 | 
			
		||||
        operation->user->redacted = strcmp( args->sitesRedacted, "1" ) == OK;
 | 
			
		||||
        operation->user->redacted = mpw_get_bool( args->sitesRedacted );
 | 
			
		||||
 | 
			
		||||
    else if (!operation->user->redacted)
 | 
			
		||||
        wrn( "Sites configuration is not redacted.  Use -R 1 to change this." );
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,7 @@ uint32_t mpw_xmlTestCaseInteger(xmlNodePtr context, const char *nodeName) {
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    xmlChar *string = mpw_xmlTestCaseString( context, nodeName );
 | 
			
		||||
    uint32_t integer = string? (uint32_t)atol( (char *)string ): 0;
 | 
			
		||||
    uint32_t integer = string? (uint32_t)strtoul( (char *)string, NULL, 10 ): 0;
 | 
			
		||||
    xmlFree( string );
 | 
			
		||||
 | 
			
		||||
    return integer;
 | 
			
		||||
 
 | 
			
		||||
@@ -199,14 +199,14 @@ const char *mpw_site_derived_password_v0(
 | 
			
		||||
                err( "Missing key size parameter." );
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
            int resultParamInt = atoi( resultParam );
 | 
			
		||||
            if (!resultParamInt)
 | 
			
		||||
                resultParamInt = 512;
 | 
			
		||||
            if (resultParamInt < 128 || resultParamInt > 512 || resultParamInt % 8 != 0) {
 | 
			
		||||
            long parameter = strtol( resultParam, NULL, 10 );
 | 
			
		||||
            if (!parameter)
 | 
			
		||||
                parameter = 512;
 | 
			
		||||
            if (parameter < 128 || parameter > 512 || parameter % 8 != 0) {
 | 
			
		||||
                err( "Parameter is not a valid key size (should be 128 - 512): %s", resultParam );
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
            uint16_t keySize = (uint16_t)(resultParamInt / 8);
 | 
			
		||||
            uint16_t keySize = (uint16_t)(parameter / 8);
 | 
			
		||||
            trc( "keySize: %u", keySize );
 | 
			
		||||
 | 
			
		||||
            // Derive key
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,11 @@ char *mpw_get_token(const char **in, const char *eol, const char *delim) {
 | 
			
		||||
    return token;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool mpw_get_bool(const char *in) {
 | 
			
		||||
 | 
			
		||||
    return in && (in[0] == 'y' || in[0] == 't' || strtol( in, NULL, 10 ) > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t mpw_timegm(const char *time) {
 | 
			
		||||
 | 
			
		||||
    // TODO: Support for parsing non-UTC time strings
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,10 @@ MP_LIBS_END
 | 
			
		||||
 * @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, const char *delim);
 | 
			
		||||
/** Get a boolean value as expressed by the given string.
 | 
			
		||||
 * @return true if the string is not NULL and holds a number larger than 0, or starts with a t (for true) or y (for yes). */
 | 
			
		||||
bool mpw_get_bool(
 | 
			
		||||
        const char *in);
 | 
			
		||||
/** Convert an RFC 3339 time string into epoch time.
 | 
			
		||||
 * @return ERR if the string could not be parsed. */
 | 
			
		||||
time_t mpw_timegm(
 | 
			
		||||
 
 | 
			
		||||
@@ -890,29 +890,29 @@ static void mpw_marshal_read_flat(
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (strcmp( headerName, "Format" ) == OK)
 | 
			
		||||
                format = (unsigned int)atoi( headerValue );
 | 
			
		||||
            if (strcmp( headerName, "Date" ) == OK)
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Format" ) == OK)
 | 
			
		||||
                format = (unsigned int)strtoul( headerValue, NULL, 10 );
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Date" ) == OK)
 | 
			
		||||
                exportDate = mpw_timegm( headerValue );
 | 
			
		||||
            if (strcmp( headerName, "Passwords" ) == OK)
 | 
			
		||||
                importRedacted = strcmp( headerValue, "VISIBLE" ) != OK;
 | 
			
		||||
            if (strcmp( headerName, "Algorithm" ) == OK) {
 | 
			
		||||
                int value = atoi( headerValue );
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Passwords" ) == OK)
 | 
			
		||||
                importRedacted = mpw_strcasecmp( headerValue, "VISIBLE" ) != OK;
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Algorithm" ) == OK) {
 | 
			
		||||
                unsigned long value = strtoul( headerValue, NULL, 10 );
 | 
			
		||||
                if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast)
 | 
			
		||||
                    file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user algorithm version: %s", headerValue ) };
 | 
			
		||||
                else
 | 
			
		||||
                    algorithm = (MPAlgorithmVersion)value;
 | 
			
		||||
            }
 | 
			
		||||
            if (strcmp( headerName, "Avatar" ) == OK)
 | 
			
		||||
                avatar = (unsigned int)atoi( headerValue );
 | 
			
		||||
            if (strcmp( headerName, "Full Name" ) == OK || strcmp( headerName, "User Name" ) == OK)
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Avatar" ) == OK)
 | 
			
		||||
                avatar = (unsigned int)strtoul( headerValue, NULL, 10 );
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Full Name" ) == OK || mpw_strcasecmp( headerName, "User Name" ) == OK)
 | 
			
		||||
                fullName = mpw_strdup( headerValue );
 | 
			
		||||
            if (strcmp( headerName, "Identicon" ) == OK)
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Identicon" ) == OK)
 | 
			
		||||
                identicon = mpw_identicon_encoded( headerValue );
 | 
			
		||||
            if (strcmp( headerName, "Key ID" ) == OK)
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Key ID" ) == OK)
 | 
			
		||||
                keyID = mpw_strdup( headerValue );
 | 
			
		||||
            if (strcmp( headerName, "Default Type" ) == OK) {
 | 
			
		||||
                int value = atoi( headerValue );
 | 
			
		||||
            if (mpw_strcasecmp( headerName, "Default Type" ) == OK) {
 | 
			
		||||
                unsigned long value = strtoul( headerValue, NULL, 10 );
 | 
			
		||||
                if (!mpw_type_short_name( (MPResultType)value ))
 | 
			
		||||
                    file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid user default type: %s", headerValue ) };
 | 
			
		||||
                else
 | 
			
		||||
@@ -970,18 +970,18 @@ static void mpw_marshal_read_flat(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (siteName && str_type && str_counter && str_algorithm && str_uses && str_lastUsed) {
 | 
			
		||||
            MPResultType siteType = (MPResultType)atoi( str_type );
 | 
			
		||||
            MPResultType siteType = (MPResultType)strtoul( str_type, NULL, 10 );
 | 
			
		||||
            if (!mpw_type_short_name( siteType )) {
 | 
			
		||||
                file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site type: %s: %s", siteName, str_type ) };
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            long long int value = atoll( str_counter );
 | 
			
		||||
            long long int value = strtoll( str_counter, NULL, 10 );
 | 
			
		||||
            if (value < MPCounterValueFirst || value > MPCounterValueLast) {
 | 
			
		||||
                file->error = (MPMarshalError){ MPMarshalErrorIllegal, mpw_str( "Invalid site counter: %s: %s", siteName, str_counter ) };
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            MPCounterValue siteCounter = (MPCounterValue)value;
 | 
			
		||||
            value = atoll( str_algorithm );
 | 
			
		||||
            value = strtoll( str_algorithm, NULL, 0 );
 | 
			
		||||
            if (value < MPAlgorithmVersionFirst || value > MPAlgorithmVersionLast) {
 | 
			
		||||
                file->error = (MPMarshalError){
 | 
			
		||||
                        MPMarshalErrorIllegal, mpw_str( "Invalid site algorithm: %s: %s", siteName, str_algorithm )
 | 
			
		||||
@@ -1001,10 +1001,12 @@ static void mpw_marshal_read_flat(
 | 
			
		||||
            mpw_marshal_data_set_num( siteCounter, file->data, "sites", siteName, "counter", NULL );
 | 
			
		||||
            mpw_marshal_data_set_num( siteAlgorithm, file->data, "sites", siteName, "algorithm", NULL );
 | 
			
		||||
            mpw_marshal_data_set_num( siteType, file->data, "sites", siteName, "type", NULL );
 | 
			
		||||
            mpw_marshal_data_set_str( siteResultState && strlen( siteResultState )? siteResultState: NULL, file->data, "sites", siteName, "password", NULL );
 | 
			
		||||
            mpw_marshal_data_set_str( siteResultState && strlen( siteResultState )? siteResultState: NULL, file->data, "sites", siteName,
 | 
			
		||||
                    "password", NULL );
 | 
			
		||||
            mpw_marshal_data_set_num( MPResultTypeDefault, file->data, "sites", siteName, "login_type", NULL );
 | 
			
		||||
            mpw_marshal_data_set_str( siteLoginState && strlen( siteLoginState )? siteLoginState: NULL, file->data, "sites", siteName, "login_name", NULL );
 | 
			
		||||
            mpw_marshal_data_set_num( atoi( str_uses ), file->data, "sites", siteName, "uses", NULL );
 | 
			
		||||
            mpw_marshal_data_set_str( siteLoginState && strlen( siteLoginState )? siteLoginState: NULL, file->data, "sites", siteName,
 | 
			
		||||
                    "login_name", NULL );
 | 
			
		||||
            mpw_marshal_data_set_num( strtol( str_uses, NULL, 10 ), file->data, "sites", siteName, "uses", NULL );
 | 
			
		||||
            if (strftime( dateString, sizeof( dateString ), "%FT%TZ", gmtime( &siteLastUsed ) ))
 | 
			
		||||
                mpw_marshal_data_set_str( dateString, file->data, "sites", siteName, "last_used", NULL );
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -118,7 +118,7 @@ typedef struct MPMarshalledInfo {
 | 
			
		||||
    /** User metadata: The identicon that was generated to represent this file's user identity. */
 | 
			
		||||
    MPIdenticon identicon;
 | 
			
		||||
    /** A unique identifier (hex) for the user's master key, primarily for authentication/verification. */
 | 
			
		||||
    const char *keyID;
 | 
			
		||||
    MPKeyID keyID;
 | 
			
		||||
    /** User metadata: Date of the most recent action taken by this user. */
 | 
			
		||||
    time_t lastUsed;
 | 
			
		||||
} MPMarshalledInfo;
 | 
			
		||||
@@ -176,7 +176,7 @@ typedef struct MPMarshalledUser {
 | 
			
		||||
    /** Algorithm version to use for user operations (eg. key ID operations). */
 | 
			
		||||
    MPAlgorithmVersion algorithm;
 | 
			
		||||
    /** A unique identifier (hex) for the user's master key, primarily for authentication/verification. */
 | 
			
		||||
    const char *keyID;
 | 
			
		||||
    MPKeyID keyID;
 | 
			
		||||
    /** The initial result type to use for new sites created by the user. */
 | 
			
		||||
    MPResultType defaultType;
 | 
			
		||||
    /** User metadata: Date of the most recent action taken by this user. */
 | 
			
		||||
 
 | 
			
		||||
@@ -106,6 +106,9 @@ void mpw_log_ssink(LogLevel level, const char *file, int line, const char *funct
 | 
			
		||||
    if (!sinks_count)
 | 
			
		||||
        mpw_log_sink_file( &record );
 | 
			
		||||
 | 
			
		||||
    if (record.level <= LogLevelError) {
 | 
			
		||||
        /* error breakpoint */;
 | 
			
		||||
    }
 | 
			
		||||
    if (record.level <= LogLevelFatal)
 | 
			
		||||
        abort();
 | 
			
		||||
}
 | 
			
		||||
@@ -495,7 +498,7 @@ const MPKeyID mpw_id_buf(const void *buf, const size_t length) {
 | 
			
		||||
    return mpw_hex( hash, sizeof( hash ) / sizeof( uint8_t ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool mpw_id_buf_equals(const char *id1, const char *id2) {
 | 
			
		||||
bool mpw_id_buf_equals(MPKeyID id1, MPKeyID id2) {
 | 
			
		||||
 | 
			
		||||
    if (!id1 || !id2)
 | 
			
		||||
        return !id1 && !id2;
 | 
			
		||||
@@ -504,11 +507,7 @@ bool mpw_id_buf_equals(const char *id1, const char *id2) {
 | 
			
		||||
    if (size != strlen( id2 ))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    for (size_t c = 0; c < size; ++c)
 | 
			
		||||
        if (tolower( id1[c] ) != tolower( id2[c] ))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
    return mpw_strncasecmp( id1, id2, size ) == OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *mpw_str(const char *format, ...) {
 | 
			
		||||
@@ -665,10 +664,15 @@ char *mpw_strndup(const char *src, const size_t max) {
 | 
			
		||||
    return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mpw_strcasecmp(const char *s1, const char *s2) {
 | 
			
		||||
 | 
			
		||||
    return mpw_strncasecmp( s1, s2, s1 && s2? min( strlen( s1 ), strlen( s2 ) ): 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mpw_strncasecmp(const char *s1, const char *s2, size_t max) {
 | 
			
		||||
 | 
			
		||||
    int cmp = 0;
 | 
			
		||||
    for (; !cmp && max-- > 0 && s1 && s2; ++s1, ++s2)
 | 
			
		||||
    int cmp = s1 && s2 && max > 0? 0: s1? 1: -1;
 | 
			
		||||
    for (; !cmp && max && max-- > 0 && s1 && s2; ++s1, ++s2)
 | 
			
		||||
        cmp = tolower( (unsigned char)*s1 ) - tolower( (unsigned char)*s2 );
 | 
			
		||||
 | 
			
		||||
    return cmp;
 | 
			
		||||
 
 | 
			
		||||
@@ -252,7 +252,7 @@ const uint8_t *mpw_unhex(const char *hex, 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);
 | 
			
		||||
bool mpw_id_buf_equals(MPKeyID id1, MPKeyID id2);
 | 
			
		||||
 | 
			
		||||
//// String utilities.
 | 
			
		||||
 | 
			
		||||
@@ -269,6 +269,8 @@ 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, const size_t max);
 | 
			
		||||
/** Drop-in for POSIX strcasecmp(3). */
 | 
			
		||||
int mpw_strcasecmp(const char *s1, const char *s2);
 | 
			
		||||
/** Drop-in for POSIX strncasecmp(3). */
 | 
			
		||||
int mpw_strncasecmp(const char *s1, const char *s2, const size_t max);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user