Exemplo n.º 1
0
long Srv_rpc_srp_verifier_verify_session(
     handle_t hServer,
     srp_verifier_handle_t hSrp,
     rpc_p_srp_bytes_container user_M_cont,
     rpc_p_srp_bytes_container *ret_bytes_HAMK_cont)
{
    long sts = 0;
    struct SRPVerifier *ver = (struct SRPVerifier *) hSrp;
    char *bytes_M = NULL;
    const char *bytes_HAMK = NULL;
    rpc_p_srp_bytes_container bytes_HAMK_cont = NULL;
    long bytes_HAMK_len = 0;

    if (!ver)
    {
        sts = rpc_s_invalid_handle;
        goto error;
    }

    /* Oddly enough, the length for user_M isn't used here. */
    bytes_M = user_M_cont->bytes_B;
    srp_verifier_verify_session(ver,
                                bytes_M,
                                &bytes_HAMK);
    if (!bytes_HAMK)
    {
        *ret_bytes_HAMK_cont = NULL;
        sts = rpc_s_auth_mut_fail;
        goto error;
    }
    bytes_HAMK_len = srp_verifier_get_session_key_length(ver);

    sts = _srp_bytes_container_allocate(bytes_HAMK,
                                        bytes_HAMK_len,
                                        &bytes_HAMK_cont);
    if (sts)
    {
        goto error;
    }
    *ret_bytes_HAMK_cont = bytes_HAMK_cont;

error:
    if (sts)
    {
        _srp_bytes_container_free(bytes_HAMK_cont);
    }
    return sts;
}
Exemplo n.º 2
0
long Srv_rpc_srp_verifier_get_session_key_length(
     handle_t hServer,
     srp_verifier_handle_t hSrp,
     long *ret_key_length)
{
    long sts = 0;
    int key_length = 0;
    struct SRPVerifier *ver = (struct SRPVerifier *) hSrp;

    if (!ver)
    {
        sts = rpc_s_invalid_handle;
        goto error;
    }
    key_length = srp_verifier_get_session_key_length(ver);
    *ret_key_length = key_length;

error:
    return sts;
}
Exemplo n.º 3
0
//*****************************************************************************
//
bool SERVER_ProcessSRPClientCommand( LONG lCommand, BYTESTREAM_s *pByteStream )
{
	switch ( lCommand )
	{
	case CLC_SRP_USER_REQUEST_LOGIN:
		{
			CLIENT_s *pClient = SERVER_GetClient(SERVER_GetCurrentClient());

			pClient->username = NETWORK_ReadString( pByteStream );
			pClient->clientSessionID = M_Random.GenRand32();

#if EMULATE_AUTH_SERVER
			SERVERCOMMANDS_SRPUserStartAuthentication ( SERVER_GetCurrentClient() );
#else
			// [BB] The client wants to log in, so start negotiating with the auth server.
			SERVER_AUTH_Negotiate ( pClient->username.GetChars(), pClient->clientSessionID );
#endif
		}
		break;

	case CLC_SRP_USER_START_AUTHENTICATION:
		{
			CLIENT_s *pClient = SERVER_GetClient(SERVER_GetCurrentClient());

			const int lenA = NETWORK_ReadShort( pByteStream );

			if ( lenA > 0 )
			{
				pClient->bytesA.Resize ( lenA ); 
				for ( int i = 0; i < lenA; ++i )
					pClient->bytesA[i] = NETWORK_ReadByte( pByteStream );
			}
			else
				Printf ( "CLC_SRP_USER_START_AUTHENTICATION: Invalid length\n" );

#if EMULATE_AUTH_SERVER
			const unsigned char * bytesS = NULL;
			const unsigned char * bytesV = NULL;
			int lenS   = 0;
			int lenV   = 0;
			const char *password = "******";
			srp_create_salted_verification_key( SRP_SHA256, SRP_NG_2048, pClient->username.GetChars(), reinterpret_cast<const unsigned char *>(password), strlen(password), 
                &bytesS, &lenS, &bytesV, &lenV, NULL, NULL );

			pClient->salt.Resize ( lenS ); 
			for ( int i = 0; i < lenS; ++i )
				pClient->salt[i] = bytesS[i];
			
			const unsigned char * bytesB = NULL;
			int lenB = 0;
			if ( g_ver != NULL )
				 srp_verifier_delete( g_ver );
			g_ver = srp_verifier_new( SRP_SHA256, SRP_NG_2048, pClient->username.GetChars(), bytesS, lenS, bytesV, lenV, &(pClient->bytesA[0]), lenA, &bytesB, &lenB, NULL, NULL, 1 );

			if ( ( bytesB == NULL ) || ( lenB == 0 ) )
			{
		        Printf ( "Verifier SRP-6a safety check violated!\n" );
				pClient->bytesB.Clear(); 
			}
			else
			{
		        Printf ( "Verifier SRP-6a safety check passed.\n" );
				pClient->bytesB.Resize ( lenB ); 
				for ( int i = 0; i < lenB; ++i )
					pClient->bytesB[i] = bytesB[i];

				SERVERCOMMANDS_SRPUserProcessChallenge ( SERVER_GetCurrentClient() );
			}

			free( (char *)bytesS );
			free( (char *)bytesV );
#else
			SERVER_AUTH_SRPMessage ( SERVER_AUTH_SRP_STEP_ONE, pClient->SRPsessionID, pClient->bytesA );
#endif

			return ( false );
		}
		break;
	case CLC_SRP_USER_PROCESS_CHALLENGE:
		{
			CLIENT_s *pClient = SERVER_GetClient(SERVER_GetCurrentClient());

			const int lenM = NETWORK_ReadShort( pByteStream );
			if ( lenM > 0 )
			{
				pClient->bytesM.Resize ( lenM ); 
				for ( int i = 0; i < lenM; ++i )
					pClient->bytesM[i] = NETWORK_ReadByte( pByteStream );
			}
			else
				Printf ( "CLC_SRP_USER_PROCESS_CHALLENGE: Invalid length\n" );

#if EMULATE_AUTH_SERVER
			unsigned char bytesM[SHA512_DIGEST_LENGTH];
			for ( int i = 0; i < lenM; ++i )
				bytesM[i] = pClient->bytesM[i];

			if ( g_ver == NULL )
				Printf ( "Error: Verifier pointer is NULL.\n" );
			else
			{
				const unsigned char * bytesHAMK = NULL;
				srp_verifier_verify_session( g_ver, bytesM, &bytesHAMK );

				if ( bytesHAMK == NULL )
				{
					SERVER_InitClientSRPData ( SERVER_GetCurrentClient() );
					Printf ( "User authentication failed!\n" );
					SERVER_PrintfPlayer( PRINT_HIGH, SERVER_GetCurrentClient(), "User authentication failed!\n" );
				}
				else
				{
					Printf ( "User authentication successfully.\n" );
					// [BB] The user has logged in in successfully.
					SERVER_GetClient(SERVER_GetCurrentClient())->loggedIn = true;

					pClient->bytesHAMK.Resize ( srp_verifier_get_session_key_length( g_ver ) );
					for ( unsigned int i = 0; i < pClient->bytesHAMK.Size(); ++i )
						pClient->bytesHAMK[i] = bytesHAMK[i];

					SERVERCOMMANDS_SRPUserVerifySession ( SERVER_GetCurrentClient() );
				}
			}
#else
			if ( pClient->SRPsessionID != -1 )
				SERVER_AUTH_SRPMessage ( SERVER_AUTH_SRP_STEP_THREE, pClient->SRPsessionID, pClient->bytesM );
#endif

			return ( false );
		}
		break;

	default:
		Printf ( "Error: Received unknown SRP command '%d' from client %d.\n", static_cast<int>(lCommand), static_cast<int>(SERVER_GetCurrentClient()) );
		break;
	}
	return ( false );
}
Exemplo n.º 4
0
static
OM_uint32
_srp_gss_validate_client(
    OM_uint32 *minor_status,
    srp_gss_ctx_id_t srp_context_handle,
    int state,
    gss_buffer_t input_token,
    gss_buffer_t output_token)
{
    OM_uint32 maj = 0;
    OM_uint32 min = 0;
    int berror = 0;
    ber_tag_t ber_state = 0;
    BerElement *ber = NULL;
    BerElement *ber_resp = NULL;
    struct berval ber_HAMK = {0};
    struct berval *ber_srp_bytes_M = NULL;
    struct berval ber_ctx = {0};
    const unsigned char *bytes_HAMK = NULL;
    int bytes_HAMK_len = 0;
    struct berval *flatten = NULL;
    PVMDIR_SERVER_CONTEXT hServer = NULL;

    ber_ctx.bv_val = (void *) input_token->value;
    ber_ctx.bv_len = input_token->length;
    ber = ber_init(&ber_ctx);
    if (!ber)
    {
        maj = GSS_S_FAILURE;
        goto error;
    }

    srp_debug_printf("_srp_gss_validate_client(): "
                     "state=SRP_AUTH_CLIENT_VALIDATE\n");

    /*
     * ptr points to ASN.1 encoded data which is dependent on the authentication
     * state. The appropriate decoder format string is applied for each state
     */
    berror = ber_scanf(ber, "t{O}", &ber_state, &ber_srp_bytes_M);
    if (berror == -1)
    {
        maj = GSS_S_FAILURE;
        min = GSS_S_DEFECTIVE_TOKEN;
        goto error;
    }

    /*
     * This is mostly impossible, as state IS the "t" field.
     * More a double check for proper decoding.
     */
    if ((int) ber_state != state || ber_srp_bytes_M->bv_len == 0)
    {
        maj = GSS_S_FAILURE;
        goto error;
    }

    srp_print_hex(ber_srp_bytes_M->bv_val, (int) ber_srp_bytes_M->bv_len,
                  "_srp_gss_validate_client(accept_sec_ctx) received bytes_M");

    if (srp_context_handle->bUseCSRP)
    {
        srp_verifier_verify_session(
            srp_context_handle->srp_ver,
            ber_srp_bytes_M->bv_val,
            &bytes_HAMK);
        if (!bytes_HAMK)
        {
            min = rpc_s_auth_mut_fail;
        }
    }
    else
    {
        hServer = srp_context_handle->hServer;
        min = cli_rpc_srp_verifier_verify_session(
                  hServer->hBinding,
                  srp_context_handle->srp_ver,
                  ber_srp_bytes_M->bv_val, (int) ber_srp_bytes_M->bv_len,
                  &bytes_HAMK, &bytes_HAMK_len);
    }
    if (min || !bytes_HAMK)
    {
        /*
         * Bad password will cause this to fail. Do not bail on error here.
         * Merely generate a NULL HAMK response below, to complete the
         * SRP protocol exchange with the client. The client tests for an
         * empty HAMK token, and formulates the proper error.
         */
        srp_debug_printf("_srp_gss_validate_client: "
                         "srp_verifier_verify_session() failed!!!\n");
    }

    /*
     * ASN.1 encode the bytes_HAMK value, sending it back to the client
     * for validation. That will complete the authentication process if that
     * succeeds.
     */

    ber_resp = ber_alloc_t(LBER_USE_DER);
    if (!ber_resp)
    {
        maj = GSS_S_FAILURE;
        min = ENOMEM;
        goto error;
    }
    if (min == 0)
    {
        if (srp_context_handle->bUseCSRP)
        {
            bytes_HAMK_len = srp_verifier_get_session_key_length(srp_context_handle->srp_ver);
        }
        else
        {
            /*
             * Generate HAMK response. When min is an error code,
             * an empty HAMK response (zero length) is created.
             */
            min = cli_rpc_srp_verifier_get_session_key_length(
                      hServer->hBinding,
                      srp_context_handle->srp_ver,
                      (long *) &ber_HAMK.bv_len);
            if (min)
            {
                maj = GSS_S_FAILURE;
                goto error;
            }
        }
    }

    ber_HAMK.bv_val = (void *) bytes_HAMK;
    ber_HAMK.bv_len = bytes_HAMK_len;
    berror = ber_printf(ber_resp, "t{O}",
                  (int) SRP_AUTH_SERVER_VALIDATE,
                  &ber_HAMK);
    if (berror == -1)
    {
        maj = GSS_S_FAILURE;
        goto error;
    }

    berror = ber_flatten(ber_resp, &flatten);
    if (berror == -1)
    {
        maj = GSS_S_FAILURE;
        goto error;
    }

    output_token->value = gssalloc_calloc(1, flatten->bv_len);
    if (!output_token->value)
    {
        maj = GSS_S_FAILURE;
        goto error;
    }
    output_token->length = flatten->bv_len;
    memcpy(output_token->value, flatten->bv_val, flatten->bv_len);

    /*
     * From server's perspective, authentication is done. However,
     * there is a final output_token to process by gss_init_sec_context().
     */
    maj = GSS_S_COMPLETE;

error:
    if (ber_srp_bytes_M)
    {
        ber_bvfree(ber_srp_bytes_M);
    }
    if (!srp_context_handle->bUseCSRP && bytes_HAMK)
    {
        free((void *) bytes_HAMK);
    }
    ber_bvfree(flatten);
    ber_free(ber, 1);
    ber_free(ber_resp, 1);
    if (maj)
    {
        if (min)
        {
            *minor_status = min;
        }
    }
    return maj;
}