int authenticate_gss_client_unwrap()

in src/kerberosgss.c [349:419]


int authenticate_gss_client_unwrap(
    gss_client_state *state, const char *challenge
) {
	OM_uint32 maj_stat;
	OM_uint32 min_stat;
	gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
	gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
	int ret = AUTH_GSS_CONTINUE;
	int conf = 0;
    
	// Always clear out the old response
	if (state->response != NULL) {
		free(state->response);
		state->response = NULL;
		state->responseConf = 0;
	}
    
	// If there is a challenge (data from the server) we need to give it to GSS
	if (challenge && *challenge) {
		size_t len;
		input_token.value = base64_decode(challenge, &len);
		if (input_token.value == NULL) {
		    PyErr_NoMemory();
		    ret = AUTH_GSS_ERROR;
		    goto end;
		}
		input_token.length = len;
	}
    
	// Do GSSAPI step
	maj_stat = gss_unwrap(
        &min_stat,
        state->context,
        &input_token,
        &output_token,
        &conf,
        NULL
    );
    
	if (maj_stat != GSS_S_COMPLETE)	{
		set_gss_error(maj_stat, min_stat);
		ret = AUTH_GSS_ERROR;
		goto end;
	} else {
		ret = AUTH_GSS_COMPLETE;
    }
    
	// Grab the client response
	if (output_token.length) {
		state->response = base64_encode(
            (const unsigned char *)output_token.value, output_token.length
        );
		if (state->response == NULL)
		{
		    PyErr_NoMemory();
		    ret = AUTH_GSS_ERROR;
		    goto end;
		}
		state->responseConf = conf;
		maj_stat = gss_release_buffer(&min_stat, &output_token);
	}

end:
	if (output_token.value) {
		gss_release_buffer(&min_stat, &output_token);
    }
	if (input_token.value) {
		free(input_token.value);
    }
	return ret;
}