Пример #1
0
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput)
{
	int status;
	int ssl_error;
	PSecBuffer pBuffer;

	if (!context->connected)
	{
		if (pInput)
		{
			if (pInput->cBuffers < 1)
				return SEC_E_INVALID_TOKEN;

			pBuffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN);

			if (!pBuffer)
				return SEC_E_INVALID_TOKEN;

			status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer);
		}

		status = SSL_connect(context->ssl);

		if (status < 0)
		{
			ssl_error = SSL_get_error(context->ssl, status);
			WLog_ERR(TAG, "SSL_connect error: %s", openssl_get_ssl_error_string(ssl_error));
		}

		if (status == 1)
			context->connected = TRUE;

		status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN);

		if (pOutput->cBuffers < 1)
			return SEC_E_INVALID_TOKEN;

		pBuffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN);

		if (!pBuffer)
			return SEC_E_INVALID_TOKEN;

		if (status > 0)
		{
			if (pBuffer->cbBuffer < (unsigned long) status)
				return SEC_E_INSUFFICIENT_MEMORY;

			CopyMemory(pBuffer->pvBuffer, context->ReadBuffer, status);
			pBuffer->cbBuffer = status;
			return (context->connected) ? SEC_E_OK : SEC_I_CONTINUE_NEEDED;
		}
		else
		{
			pBuffer->cbBuffer = 0;
			return (context->connected) ? SEC_E_OK : SEC_I_CONTINUE_NEEDED;
		}
	}

	return SEC_E_OK;
}
Пример #2
0
SECURITY_STATUS schannel_openssl_decrypt_message(SCHANNEL_OPENSSL* context, PSecBufferDesc pMessage)
{
	int status;
	int length;
	BYTE* buffer;
	int ssl_error;
	PSecBuffer pBuffer;
	pBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_DATA);

	if (!pBuffer)
		return SEC_E_INVALID_TOKEN;

	status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer);
	status = SSL_read(context->ssl, pBuffer->pvBuffer, pBuffer->cbBuffer);

	if (status < 0)
	{
		ssl_error = SSL_get_error(context->ssl, status);
		WLog_ERR(TAG, "SSL_read: %s", openssl_get_ssl_error_string(ssl_error));
	}

	length = status;
	buffer = pBuffer->pvBuffer;
	pMessage->pBuffers[0].BufferType = SECBUFFER_STREAM_HEADER;
	pMessage->pBuffers[0].cbBuffer = 5;
	pMessage->pBuffers[1].BufferType = SECBUFFER_DATA;
	pMessage->pBuffers[1].pvBuffer = buffer;
	pMessage->pBuffers[1].cbBuffer = length;
	pMessage->pBuffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
	pMessage->pBuffers[2].cbBuffer = 36;
	pMessage->pBuffers[3].BufferType = SECBUFFER_EMPTY;
	pMessage->pBuffers[3].cbBuffer = 0;
	return SEC_E_OK;
}
Пример #3
0
SECURITY_STATUS schannel_openssl_encrypt_message(SCHANNEL_OPENSSL* context, PSecBufferDesc pMessage)
{
	int status;
	int length;
	int offset;
	int ssl_error;
	PSecBuffer pStreamBodyBuffer;
	PSecBuffer pStreamHeaderBuffer;
	PSecBuffer pStreamTrailerBuffer;
	pStreamHeaderBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_STREAM_HEADER);
	pStreamBodyBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_DATA);
	pStreamTrailerBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_STREAM_TRAILER);

	if ((!pStreamHeaderBuffer) || (!pStreamBodyBuffer) || (!pStreamTrailerBuffer))
		return SEC_E_INVALID_TOKEN;

	status = SSL_write(context->ssl, pStreamBodyBuffer->pvBuffer, pStreamBodyBuffer->cbBuffer);

	if (status < 0)
	{
		ssl_error = SSL_get_error(context->ssl, status);
		WLog_ERR(TAG, "SSL_write: %s", openssl_get_ssl_error_string(ssl_error));
	}

	status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN);

	if (status > 0)
	{
		offset = 0;
		length = (pStreamHeaderBuffer->cbBuffer > (unsigned long) status) ? status :
		         pStreamHeaderBuffer->cbBuffer;
		CopyMemory(pStreamHeaderBuffer->pvBuffer, &context->ReadBuffer[offset], length);
		status -= length;
		offset += length;
		length = (pStreamBodyBuffer->cbBuffer > (unsigned long) status) ? status :
		         pStreamBodyBuffer->cbBuffer;
		CopyMemory(pStreamBodyBuffer->pvBuffer, &context->ReadBuffer[offset], length);
		status -= length;
		offset += length;
		length = (pStreamTrailerBuffer->cbBuffer > (unsigned long) status) ? status :
		         pStreamTrailerBuffer->cbBuffer;
		CopyMemory(pStreamTrailerBuffer->pvBuffer, &context->ReadBuffer[offset], length);
	}

	return SEC_E_OK;
}
Пример #4
0
SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
		SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
		PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
		PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
{
	NTLM_CONTEXT* context;
	SECURITY_STATUS status;
	SSPI_CREDENTIALS* credentials;
	PSecBuffer input_buffer = NULL;
	PSecBuffer output_buffer = NULL;
	PSecBuffer channel_bindings = NULL;

	context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);

	if (!context)
	{
		context = ntlm_ContextNew();

		if (!context)
			return SEC_E_INSUFFICIENT_MEMORY;

		if (fContextReq & ISC_REQ_CONFIDENTIALITY)
			context->confidentiality = TRUE;

		credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
		context->credentials = credentials;

		if (context->Workstation.Length < 1)
		{
			if (ntlm_SetContextWorkstation(context, NULL) < 0)
				return SEC_E_INTERNAL_ERROR;
		}

		if (ntlm_SetContextServicePrincipalNameW(context, pszTargetName) < 0)
			return SEC_E_INTERNAL_ERROR;

		sspi_SecureHandleSetLowerPointer(phNewContext, context);
		sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME);
	}

	if ((!pInput) || (context->state == NTLM_STATE_AUTHENTICATE))
	{
		if (!pOutput)
			return SEC_E_INVALID_TOKEN;

		if (pOutput->cBuffers < 1)
			return SEC_E_INVALID_TOKEN;

		output_buffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN);

		if (!output_buffer)
			return SEC_E_INVALID_TOKEN;

		if (output_buffer->cbBuffer < 1)
			return SEC_E_INVALID_TOKEN;

		if (context->state == NTLM_STATE_INITIAL)
			context->state = NTLM_STATE_NEGOTIATE;

		if (context->state == NTLM_STATE_NEGOTIATE)
			return ntlm_write_NegotiateMessage(context, output_buffer);

		return SEC_E_OUT_OF_SEQUENCE;
	}
	else
	{
		if (pInput->cBuffers < 1)
			return SEC_E_INVALID_TOKEN;

		input_buffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN);

		if (!input_buffer)
			return SEC_E_INVALID_TOKEN;

		if (input_buffer->cbBuffer < 1)
			return SEC_E_INVALID_TOKEN;

		channel_bindings = sspi_FindSecBuffer(pInput, SECBUFFER_CHANNEL_BINDINGS);

		if (channel_bindings)
		{
			context->Bindings.BindingsLength = channel_bindings->cbBuffer;
			context->Bindings.Bindings = (SEC_CHANNEL_BINDINGS*) channel_bindings->pvBuffer;
		}

		if (context->state == NTLM_STATE_CHALLENGE)
		{
			status = ntlm_read_ChallengeMessage(context, input_buffer);

			if (!pOutput)
				return SEC_E_INVALID_TOKEN;

			if (pOutput->cBuffers < 1)
				return SEC_E_INVALID_TOKEN;

			output_buffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN);

			if (!output_buffer)
				return SEC_E_INVALID_TOKEN;

			if (output_buffer->cbBuffer < 1)
				return SEC_E_INSUFFICIENT_MEMORY;

			if (context->state == NTLM_STATE_AUTHENTICATE)
				return ntlm_write_AuthenticateMessage(context, output_buffer);
		}

		return SEC_E_OUT_OF_SEQUENCE;
	}

	return SEC_E_OUT_OF_SEQUENCE;
}
Пример #5
0
/**
 * @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa374707
 */
SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext,
		PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
		PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp)
{
	NTLM_CONTEXT* context;
	SECURITY_STATUS status;
	SSPI_CREDENTIALS* credentials;
	PSecBuffer input_buffer;
	PSecBuffer output_buffer;

	context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);

	if (!context)
	{
		context = ntlm_ContextNew();

		if (!context)
			return SEC_E_INSUFFICIENT_MEMORY;

		context->server = TRUE;

		if (fContextReq & ASC_REQ_CONFIDENTIALITY)
			context->confidentiality = TRUE;

		credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
		context->credentials = credentials;

		ntlm_SetContextTargetName(context, NULL);

		sspi_SecureHandleSetLowerPointer(phNewContext, context);
		sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME);
	}

	if (context->state == NTLM_STATE_INITIAL)
	{
		context->state = NTLM_STATE_NEGOTIATE;

		if (!pInput)
			return SEC_E_INVALID_TOKEN;

		if (pInput->cBuffers < 1)
			return SEC_E_INVALID_TOKEN;

		input_buffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN);

		if (!input_buffer)
			return SEC_E_INVALID_TOKEN;

		if (input_buffer->cbBuffer < 1)
			return SEC_E_INVALID_TOKEN;

		status = ntlm_read_NegotiateMessage(context, input_buffer);

		if (context->state == NTLM_STATE_CHALLENGE)
		{
			if (!pOutput)
				return SEC_E_INVALID_TOKEN;

			if (pOutput->cBuffers < 1)
				return SEC_E_INVALID_TOKEN;

			output_buffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN);

			if (!output_buffer->BufferType)
				return SEC_E_INVALID_TOKEN;

			if (output_buffer->cbBuffer < 1)
				return SEC_E_INSUFFICIENT_MEMORY;

			return ntlm_write_ChallengeMessage(context, output_buffer);
		}

		return SEC_E_OUT_OF_SEQUENCE;
	}
	else if (context->state == NTLM_STATE_AUTHENTICATE)
	{
		if (!pInput)
			return SEC_E_INVALID_TOKEN;

		if (pInput->cBuffers < 1)
			return SEC_E_INVALID_TOKEN;

		input_buffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN);

		if (!input_buffer)
			return SEC_E_INVALID_TOKEN;

		if (input_buffer->cbBuffer < 1)
			return SEC_E_INVALID_TOKEN;

		status = ntlm_read_AuthenticateMessage(context, input_buffer);

		if (pOutput)
		{
			ULONG i;

			for (i = 0; i < pOutput->cBuffers; i++)
			{
				pOutput->pBuffers[i].cbBuffer = 0;
				pOutput->pBuffers[i].BufferType = SECBUFFER_TOKEN;
			}
		}

		return status;
	}

	return SEC_E_OUT_OF_SEQUENCE;
}