int osauthVerifyResponse( char *challenge, char *username, char *response ) { #if defined(OS_AUTH) static char fname[] = "osauthVerifyResponse"; char authenticator[16]; /* MD5 hash */ char md5buffer[CHALLENGE_LEN + MAX_PASSWORD_LEN + 2]; char md5digest[RESPONSE_LEN + 2]; int uid, status, i; char *keybuf = NULL; int key_len; MD5_CTX ctx; uid = osauthGetUid( username ); if ( uid == -1 ) { return SYS_USER_RETRIEVE_ERR; } /* read the key from the key file */ if ( ( status = osauthGetKey( &keybuf, &key_len ) ) ) { rodsLogError( LOG_ERROR, status, "%s: error retrieving key.", fname ); return status; } /* generate the authenticator */ status = osauthGenerateAuthenticator( username, uid, challenge, keybuf, key_len, authenticator, 16 ); if ( status ) { rodsLog( LOG_ERROR, "%s: could not generate the authenticator", fname ); free( keybuf ); return status; } free( keybuf ); /* now append this hash with the challenge, and take the md5 sum of that */ memset( md5buffer, 0, sizeof( md5buffer ) ); memset( md5digest, 0, sizeof( md5digest ) ); memcpy( md5buffer, challenge, CHALLENGE_LEN ); memcpy( md5buffer + CHALLENGE_LEN, authenticator, 16 ); MD5Init( &ctx ); MD5Update( &ctx, ( unsigned char* )md5buffer, CHALLENGE_LEN + MAX_PASSWORD_LEN ); MD5Final( ( unsigned char* )md5digest, &ctx ); for ( i = 0; i < RESPONSE_LEN; i++ ) { /* make sure 'string' doesn't end early (this matches client digest generation). */ if ( md5digest[i] == '\0' ) { md5digest[i]++; } } /* compare the calculated digest to the client response */ for ( i = 0; i < RESPONSE_LEN; i++ ) { if ( response[i] != md5digest[i] ) { rodsLog( LOG_ERROR, "%s: calculated digest doesn't match client response", fname ); return CAT_INVALID_AUTHENTICATION; } } return 0; #else /* defined OS_AUTH */ if ( ProcessType == CLIENT_PT ) { return OSAUTH_NOT_BUILT_INTO_CLIENT; } else { return OSAUTH_NOT_BUILT_INTO_SERVER; } #endif }
int main( int argc, char *argv[] ) { /* make sure the provided username matches what the OS thinks */ char * username = getenv( OS_AUTH_ENV_USER ); if ( username == NULL ) { if ( argc > 0 ) { /* probably means someone has run from command-line */ printf( "%s is run through an iRODS library call, and probably won't do anything useful for you.\n", argv[0] ); printf( "%s exiting.\n", argv[0] ); return 1; } printf( "Username is null" ); return 1; } char username2[NAME_LEN]; int uid = osauthGetUsername( username2, NAME_LEN ); if ( uid == -1 ) { return 1; } if ( strcmp( username, username2 ) ) { printf( "Username %s does not match OS user %s", username, username2 ); return 1; } /* read the challenge from stdin */ int challenge_len; if ( sizeof( challenge_len ) != read( 0, ( void* )&challenge_len, sizeof( challenge_len ) ) ) { printf( "Couldn't read challenge length from stdin: %s", strerror( errno ) ); return 1; } if ( challenge_len != CHALLENGE_LEN ) { printf( "Challenge length must be %ju", ( uintmax_t )CHALLENGE_LEN ); return 1; } std::vector<char> challenge( CHALLENGE_LEN ); if ( CHALLENGE_LEN != read( 0, &challenge[0], CHALLENGE_LEN ) ) { printf( "Couldn't read challenge from stdin: %s", strerror( errno ) ); return 1; } /* read the key from the key file */ char * keybuf = NULL; int key_len; if ( osauthGetKey( &keybuf, &key_len ) ) { printf( "Error retrieving key. Exiting." ); return 1; } char authenticator[16]; /* hard coded at 16 bytes .. size of an md5 hash */ if ( osauthGenerateAuthenticator( username, uid, &challenge[0], keybuf, key_len, authenticator, 16 ) ) { printf( "Could not generate the authenticator" ); return 1; } /* write out the authenticator to stdout */ if ( write( 1, authenticator, 16 ) == -1 ) { int errsv = errno; printf( "Error %s writing the authenticator to stdout.", strerror( errsv ) ); return 1; } return 0; }