95 CREDENTIAL_USERNAME_PASSWORD,
122 USERAUTH_CALLERCHECK,
197 const int nameLength;
198 const METHOD_TYPE
type;
201 static const METHOD_INFO methodInfoTbl[] = {
202 {
"none", 4, METHOD_QUERY },
203 {
"password", 8, METHOD_PASSWORD },
204 { NULL, 0, METHOD_NONE }, { NULL, 0, METHOD_NONE }
231 status = openPacketStreamSSH( &stream, sessionInfoPtr,
235 status = sendPacketSSH2( sessionInfoPtr, &stream,
FALSE );
236 sMemDisconnect( &stream );
243 const BOOLEAN allowFurtherAuth )
250 status = openPacketStreamSSH( &stream, sessionInfoPtr,
254 if( allowFurtherAuth )
255 writeString32( &stream,
"password", 8 );
257 writeUint32( &stream, 0 );
258 status = sputc( &stream, 0 );
260 status = sendPacketSSH2( sessionInfoPtr, &stream,
FALSE );
261 sMemDisconnect( &stream );
272 const void *userName,
274 const int userNameLength,
276 const METHOD_TYPE authMethod,
283 assert(
isReadPtr( userName, userNameLength ) );
286 REQUIRES( authMethod > METHOD_NONE && authMethod < METHOD_LAST );
290 getHashAtomicParameters(
CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic, NULL );
298 memcpy( sshInfo->authUserNameHash, userNameHash,
KEYID_SIZE );
299 sshInfo->authType = authMethod;
305 if( !compareDataConstTime( sshInfo->authUserNameHash, userNameHash,
320 if( sshInfo->authType == METHOD_QUERY )
324 if( authMethod == METHOD_QUERY )
329 sshInfo->authType = authMethod;
335 if( sshInfo->authType != authMethod )
351 OUT_ENUM( USERAUTH ) USERAUTH_TYPE *userAuthInfo,
353 const CREDENTIAL_TYPE credentialType,
358 const METHOD_INFO *methodInfoPtr = NULL;
365 REQUIRES( credentialType >= CREDENTIAL_NONE && \
366 credentialType < CREDENTIAL_LAST );
373 *userAuthInfo = USERAUTH_ERROR;
395 sMemConnect( &stream, sessionInfoPtr->receiveBuffer, length );
403 sMemDisconnect( &stream );
406 "Invalid user-authentication user name" ) );
408 status = readString32( &stream, stringBuffer, CRYPT_MAX_TEXTSIZE,
412 if( stringLength != 14 || \
413 memcmp( stringBuffer,
"ssh-connection", 14 ) )
417 status = readString32( &stream, stringBuffer, CRYPT_MAX_TEXTSIZE,
421 if( stringLength <= 0 || stringLength > CRYPT_MAX_TEXTSIZE )
426 sMemDisconnect( &stream );
429 "Invalid user-authentication service or method name" ) );
437 for( i = 0; methodInfoTbl[ i ].type != METHOD_NONE && \
440 const METHOD_INFO *methodInfo = &methodInfoTbl[ i ];
442 if( methodInfo->nameLength == stringLength && \
443 !memcmp( methodInfo->name, stringBuffer, stringLength ) )
445 methodInfoPtr = methodInfo;
450 if( methodInfoPtr == NULL )
452 sMemDisconnect( &stream );
455 "Unknown user-authentication method type '%s'",
456 sanitiseString( stringBuffer, CRYPT_MAX_TEXTSIZE,
459 ( void ) sgetc( &stream );
464 status = checkCredentialsConsistent( sessionInfoPtr->sessionSSH,
465 userNameBuffer, userNameLength,
470 sMemDisconnect( &stream );
479 "Client sent duplicate authentication requests with "
484 "Client supplied different credentials than the ones "
485 "supplied during a previous authentication attempt" ) );
490 if( methodInfoPtr->type != METHOD_QUERY )
492 status = readString32( &stream, stringBuffer, CRYPT_MAX_TEXTSIZE,
494 sMemDisconnect( &stream );
496 stringLength <= 0 || stringLength > CRYPT_MAX_TEXTSIZE )
500 "Invalid user-authentication payload" ) );
525 if( credentialType != CREDENTIAL_NONE )
528 findSessionInfoEx( sessionInfoPtr->attributeList,
530 userNameBuffer, userNameLength );
531 if( attributeListPtr == NULL )
533 ( void ) sendResponseFailure( sessionInfoPtr,
FALSE );
536 "Unknown/invalid user name '%s'",
537 sanitiseString( userNameBuffer, CRYPT_MAX_TEXTSIZE,
538 userNameLength ) ) );
543 sessionInfoPtr->attributeListCurrent = \
549 status = addSessionInfoS( &sessionInfoPtr->attributeList,
551 userNameBuffer, userNameLength );
556 "Error recording user name '%s'",
557 sanitiseString( userNameBuffer, CRYPT_MAX_TEXTSIZE,
558 userNameLength ) ) );
566 if( methodInfoPtr->type == METHOD_QUERY )
568 sMemDisconnect( &stream );
571 status = sendResponseFailure( sessionInfoPtr,
TRUE );
577 *userAuthInfo = USERAUTH_NOOP;
584 if( credentialType == CREDENTIAL_USERNAME_PASSWORD )
587 attributeListPtr = attributeListPtr->
next;
588 ENSURES( attributeListPtr != NULL && \
595 if( stringLength != attributeListPtr->
valueLength || \
596 !compareDataConstTime( stringBuffer, attributeListPtr->value,
601 "Invalid password for user '%s'",
602 sanitiseString( userNameBuffer, CRYPT_MAX_TEXTSIZE,
603 userNameLength ) ) );
609 *userAuthInfo = USERAUTH_SUCCESS;
621 status = updateSessionInfo( &sessionInfoPtr->attributeList,
623 stringBuffer, stringLength,
629 "Error recording password for user '%s'",
630 sanitiseString( userNameBuffer, CRYPT_MAX_TEXTSIZE,
631 userNameLength ) ) );
634 *userAuthInfo = USERAUTH_CALLERCHECK;
658 USERAUTH_TYPE userAuthInfo;
661 } FAILSAFE_AUTH_INFO;
663 static const FAILSAFE_AUTH_INFO failsafeAuthSuccessTemplate = \
666 #define initFailsafeAuthInfo( authInfo ) \
668 memset( ( authInfo ), 0, sizeof( FAILSAFE_AUTH_INFO ) ); \
669 ( authInfo )->canary = OK_SPECIAL; \
670 ( authInfo )->status = CRYPT_ERROR_FAILED; \
688 for( isFatalError =
FALSE, authAttempts = 0;
689 !isFatalError && authAttempts < 3; authAttempts++ )
696 initFailsafeAuthInfo( &authInfo );
697 authInfo.status = processUserAuth( sessionInfoPtr,
698 &authInfo.userAuthInfo,
699 CREDENTIAL_USERNAME_PASSWORD,
702 authInfo.userAuthInfo == USERAUTH_NOOP )
705 authInfo.status = processUserAuth( sessionInfoPtr,
706 &authInfo.userAuthInfo,
707 CREDENTIAL_USERNAME_PASSWORD,
711 !memcmp( &authInfo, &failsafeAuthSuccessTemplate, \
712 sizeof( FAILSAFE_AUTH_INFO ) ) )
717 return( sendResponseSuccess( sessionInfoPtr ) );
736 if( isFatalError || authAttempts >= 2 )
737 ( void ) sendResponseFailure( sessionInfoPtr,
FALSE );
742 status = sendResponseFailure( sessionInfoPtr,
TRUE );
751 return( authInfo.status );
758 SSH_INFO *sshInfo = sessionInfoPtr->sessionSSH;
759 USERAUTH_TYPE userAuthInfo;
767 if( userInfoPresent )
768 return( processFixedAuth( sessionInfoPtr ) );
779 return( sendResponseSuccess( sessionInfoPtr ) );
783 status = sendResponseFailure( sessionInfoPtr,
TRUE );
800 status = processUserAuth( sessionInfoPtr, &userAuthInfo,
801 CREDENTIAL_NONE,
TRUE );
802 if( status ==
OK_SPECIAL && userAuthInfo == USERAUTH_NOOP )
805 status = processUserAuth( sessionInfoPtr, &userAuthInfo,
806 CREDENTIAL_USERNAME,
FALSE );
811 status = processUserAuth( sessionInfoPtr, &userAuthInfo,
812 CREDENTIAL_USERNAME,
FALSE );
814 userAuthInfo == USERAUTH_NOOP ) );