Exemple #1
0
SECURITY_STATUS ssl_recv (void)
{
  SecBufferDesc  msg;
  SecBuffer      sb[4];
  DWORD          cbIoBuffer=0;
  SecBuffer      *pData=NULL, *pExtra=NULL;
  int            len, i;
  ss=SEC_E_INCOMPLETE_MESSAGE;
  
  do
  {
    if (cbIoBuffer==0 || ss==SEC_E_INCOMPLETE_MESSAGE)
    {
      len = recv (s, pbDataIn + cbIoBuffer, cbBufferLen - cbIoBuffer, 0);
      if (len<=0) break;
      
      cbIoBuffer += len;
      
      sb[0].pvBuffer   = pbDataIn;
      sb[0].cbBuffer   = cbIoBuffer;
    
      sb[0].BufferType = SECBUFFER_DATA;
      sb[1].BufferType = SECBUFFER_EMPTY;
      sb[2].BufferType = SECBUFFER_EMPTY;
      sb[3].BufferType = SECBUFFER_EMPTY;

      msg.ulVersion    = SECBUFFER_VERSION;
      msg.cBuffers     = 4;
      msg.pBuffers     = sb;
    
      ss = sspi->DecryptMessage (&hContext, &msg, 0, NULL);
    
      if (ss == SEC_I_CONTEXT_EXPIRED) break;
    
      for (i=0; i<4; i++) {
        if (pData==NULL && sb[i].BufferType==SECBUFFER_DATA) pData=&sb[i];
        if (pExtra==NULL && sb[i].BufferType==SECBUFFER_EXTRA) pExtra=&sb[i];
      }
      
      if (pData!=NULL)
      {
        cbDataIn=pData->cbBuffer;
        if (cbDataIn!=0)
        {
          memcpy (pbDataIn, pData->pvBuffer, cbDataIn);
          break;
        }
      }
    }
  } while (1);
  return SEC_E_OK;
}
int NetlibSslRead(SslHandle *ssl, char *buf, int num, int peek)
{
	if (ssl == NULL) return SOCKET_ERROR;

	if (num <= 0) return 0;

	if (ssl->state != sockOpen || (ssl->cbRecDataBuf != 0 && (!peek || ssl->cbRecDataBuf >= num)))
		return NetlibSslReadSetResult(ssl, buf, num, peek);

	SECURITY_STATUS scRet = SEC_E_OK;

	while (true) {
		if (0 == ssl->cbIoBuffer || scRet == SEC_E_INCOMPLETE_MESSAGE) {
			if (ssl->sbIoBuffer <= ssl->cbIoBuffer) {
				ssl->sbIoBuffer += 2048;
				ssl->pbIoBuffer = (PUCHAR)mir_realloc(ssl->pbIoBuffer, ssl->sbIoBuffer);
			}

			if (peek) {
				static const TIMEVAL tv = { 0 };
				fd_set fd;
				FD_ZERO(&fd);
				FD_SET(ssl->s, &fd);

				DWORD cbData = select(1, &fd, NULL, NULL, &tv);
				if (cbData == SOCKET_ERROR) {
					ssl->state = sockError;
					return NetlibSslReadSetResult(ssl, buf, num, peek);
				}

				if (cbData == 0 && ssl->cbRecDataBuf)
					return NetlibSslReadSetResult(ssl, buf, num, peek);
			}

			DWORD cbData = recv(ssl->s, (char*)ssl->pbIoBuffer + ssl->cbIoBuffer, ssl->sbIoBuffer - ssl->cbIoBuffer, 0);
			if (cbData == SOCKET_ERROR) {
				Netlib_Logf(NULL, "SSL failure recieving data (%d)", WSAGetLastError());
				ssl->state = sockError;
				return NetlibSslReadSetResult(ssl, buf, num, peek);
			}

			if (cbData == 0) {
				Netlib_Logf(NULL, "SSL connection gracefully closed");
				if (peek && ssl->cbRecDataBuf) {
					ssl->state = sockClosed;
					return NetlibSslReadSetResult(ssl, buf, num, peek);
				}

				// Server disconnected.
				if (ssl->cbIoBuffer) {
					ssl->state = sockError;
					return NetlibSslReadSetResult(ssl, buf, num, peek);
				}

				return 0;
			}
			ssl->cbIoBuffer += cbData;
		}

		// Attempt to decrypt the received data.
		SecBuffer Buffers[4];
		Buffers[0].pvBuffer = ssl->pbIoBuffer;
		Buffers[0].cbBuffer = ssl->cbIoBuffer;
		Buffers[0].BufferType = SECBUFFER_DATA;

		Buffers[1].BufferType = SECBUFFER_EMPTY;
		Buffers[2].BufferType = SECBUFFER_EMPTY;
		Buffers[3].BufferType = SECBUFFER_EMPTY;

		SecBufferDesc Message;
		Message.ulVersion = SECBUFFER_VERSION;
		Message.cBuffers = _countof(Buffers);
		Message.pBuffers = Buffers;

		if (g_pSSPI->DecryptMessage != NULL && g_pSSPI->DecryptMessage != PVOID(0x80000000))
			scRet = g_pSSPI->DecryptMessage(&ssl->hContext, &Message, 0, NULL);
		else
			scRet = ((DECRYPT_MESSAGE_FN)g_pSSPI->Reserved4)(&ssl->hContext, &Message, 0, NULL);

		// The input buffer contains only a fragment of an
		// encrypted record. Loop around and read some more
		// data.
		if (scRet == SEC_E_INCOMPLETE_MESSAGE)
			continue;

		if (scRet != SEC_E_OK && scRet != SEC_I_RENEGOTIATE && scRet != SEC_I_CONTEXT_EXPIRED) {
			ReportSslError(scRet, __LINE__);
			ssl->state = sockError;
			return NetlibSslReadSetResult(ssl, buf, num, peek);
		}

		// Locate data and (optional) extra buffers.
		SecBuffer *pDataBuffer = NULL;
		SecBuffer *pExtraBuffer = NULL;
		for (int i = 1; i < _countof(Buffers); i++) {
			if (pDataBuffer == NULL && Buffers[i].BufferType == SECBUFFER_DATA)
				pDataBuffer = &Buffers[i];

			if (pExtraBuffer == NULL && Buffers[i].BufferType == SECBUFFER_EXTRA)
				pExtraBuffer = &Buffers[i];
		}

		// Return decrypted data.
		DWORD resNum = 0;
		if (pDataBuffer) {
			DWORD bytes = peek ? 0 : min((DWORD)num, pDataBuffer->cbBuffer);
			DWORD rbytes = pDataBuffer->cbBuffer - bytes;
			if (rbytes > 0) {
				int nbytes = ssl->cbRecDataBuf + rbytes;
				if (ssl->sbRecDataBuf < nbytes) {
					ssl->sbRecDataBuf = nbytes;
					ssl->pbRecDataBuf = (PUCHAR)mir_realloc(ssl->pbRecDataBuf, nbytes);
				}
				memcpy(ssl->pbRecDataBuf + ssl->cbRecDataBuf, (char*)pDataBuffer->pvBuffer + bytes, rbytes);
				ssl->cbRecDataBuf = nbytes;
			}

			if (peek) {
				resNum = bytes = min(num, ssl->cbRecDataBuf);
				memcpy(buf, ssl->pbRecDataBuf, bytes);
			}
			else {
				resNum = bytes;
				memcpy(buf, pDataBuffer->pvBuffer, bytes);
			}
		}

		// Move any "extra" data to the input buffer.
		if (pExtraBuffer) {
			memmove(ssl->pbIoBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer);
			ssl->cbIoBuffer = pExtraBuffer->cbBuffer;
		}
		else ssl->cbIoBuffer = 0;

		if (pDataBuffer && resNum)
			return resNum;

		// Server signaled end of session
		if (scRet == SEC_I_CONTEXT_EXPIRED) {
			Netlib_Logf(NULL, "SSL Server signaled SSL Shutdown");
			ssl->state = sockClosed;
			return NetlibSslReadSetResult(ssl, buf, num, peek);
		}

		if (scRet == SEC_I_RENEGOTIATE) {
			// The server wants to perform another handshake
			// sequence.

			scRet = ClientHandshakeLoop(ssl, FALSE);
			if (scRet != SEC_E_OK) {
				ssl->state = sockError;
				return NetlibSslReadSetResult(ssl, buf, num, peek);
			}
		}
	}
}
Exemple #3
0
char* CompleteGssapi(HANDLE hSecurity, unsigned char *szChallenge, unsigned chlsz)
{
	if (!szChallenge || !szChallenge[0]) return NULL;

	NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity;
	unsigned char inDataBuffer[1024];

	SecBuffer inBuffers[2] = 
	{
		{ sizeof(inDataBuffer), SECBUFFER_DATA, inDataBuffer },
		{ chlsz, SECBUFFER_STREAM, szChallenge },
	};

	SecBufferDesc inBuffersDesc = { SECBUFFER_VERSION, 2, inBuffers };

	unsigned long qop = 0;
	SECURITY_STATUS sc = g_pSSPI->DecryptMessage(&hNtlm->hClientContext, &inBuffersDesc, 0, &qop);
	if (sc != SEC_E_OK) 
	{
		ReportSecError(sc, __LINE__);
		return NULL;
	}

	unsigned char LayerMask = inDataBuffer[0];
	unsigned int MaxMessageSize = htonl(*(unsigned*)&inDataBuffer[1]);

	SecPkgContext_Sizes sizes;
	sc = g_pSSPI->QueryContextAttributes(&hNtlm->hClientContext, SECPKG_ATTR_SIZES, &sizes);
	if (sc != SEC_E_OK) 
	{
		ReportSecError(sc, __LINE__);
		return NULL;
	}

	unsigned char *tokenBuffer = (unsigned char*)alloca(sizes.cbSecurityTrailer);
	unsigned char *paddingBuffer = (unsigned char*)alloca(sizes.cbBlockSize);

	unsigned char outDataBuffer[4] = { 1, 0, 16, 0 };

	SecBuffer outBuffers[3] = 
	{
		{ sizes.cbSecurityTrailer, SECBUFFER_TOKEN, tokenBuffer },
		{ sizeof(outDataBuffer), SECBUFFER_DATA, outDataBuffer },
		{ sizes.cbBlockSize, SECBUFFER_PADDING, paddingBuffer }
	};
	SecBufferDesc outBuffersDesc = { SECBUFFER_VERSION, 3, outBuffers };

	sc = g_pSSPI->EncryptMessage(&hNtlm->hClientContext, SECQOP_WRAP_NO_ENCRYPT, &outBuffersDesc, 0);
	if (sc != SEC_E_OK) 
	{
		ReportSecError(sc, __LINE__);
		return NULL;
	}

	unsigned i, ressz = 0;
	for (i = 0; i < outBuffersDesc.cBuffers; i++) 
		ressz += outBuffersDesc.pBuffers[i].cbBuffer;


	unsigned char *response = (unsigned char*)alloca(ressz), *p = response;
	for (i = 0; i < outBuffersDesc.cBuffers; i++) 
	{
		memcpy(p, outBuffersDesc.pBuffers[i].pvBuffer, outBuffersDesc.pBuffers[i].cbBuffer);
		p += outBuffersDesc.pBuffers[i].cbBuffer;
	}

	NETLIBBASE64 nlb64;
	nlb64.cbDecoded = ressz;
	nlb64.pbDecoded = response;
	nlb64.cchEncoded = Netlib_GetBase64EncodedBufferSize(nlb64.cbDecoded);
	nlb64.pszEncoded = (char*)alloca(nlb64.cchEncoded);
	if (!NetlibBase64Encode(0,(LPARAM)&nlb64)) return NULL;

	return mir_strdup(nlb64.pszEncoded);
} 
Exemple #4
0
SECURITY_STATUS ReadDecrypt (void)

// calls recv() - blocking socket read
// http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx

// The encrypted message is decrypted in place, overwriting the original contents of its buffer.
// http://msdn.microsoft.com/en-us/library/aa375211(VS.85).aspx

{
  SecBuffer       ExtraBuffer;
  SecBuffer       *pDataBuffer, *pExtraBuffer;

  SECURITY_STATUS scRet;            // unsigned long cbBuffer;    // Size of the buffer, in bytes
  SecBufferDesc   Message;        // unsigned long BufferType;  // Type of the buffer (below)
  SecBuffer       Buffers[4];    // void    SEC_FAR * pvBuffer;   // Pointer to the buffer

  DWORD           cbIoBuffer, cbData, length;
  PBYTE           buff;
  int             i;

  // Read data from server until done.
  cbIoBuffer = 0;
  scRet = 0;
  
  while(TRUE) // Read some data.
  {
    if( cbIoBuffer == 0 || scRet == SEC_E_INCOMPLETE_MESSAGE ) // get the data
    {
      cbDataIn = recv(s, pbBufferIn + cbIoBuffer, cbBufferLen - cbIoBuffer, 0);
      if(cbDataIn == SOCKET_ERROR)
      {
        printf("**** Error %d reading data from server\n", WSAGetLastError());
        scRet = SEC_E_INTERNAL_ERROR;
        break;
      }
      else if(cbDataIn == 0) // Server disconnected.
      {
        if(cbIoBuffer)
        {
          printf("**** Server unexpectedly disconnected\n");
          scRet = SEC_E_INTERNAL_ERROR;
          return scRet;
        }
        else
        break; // All Done
      }
      else // success
      {
        cbIoBuffer += cbDataIn;
      }
    }

    // Decrypt the received data.
    Buffers[0].pvBuffer     = pbBufferIn;
    Buffers[0].cbBuffer     = cbIoBuffer;
    Buffers[0].BufferType   = SECBUFFER_DATA;  // Initial Type of the buffer 1
    Buffers[1].BufferType   = SECBUFFER_EMPTY; // Initial Type of the buffer 2
    Buffers[2].BufferType   = SECBUFFER_EMPTY; // Initial Type of the buffer 3
    Buffers[3].BufferType   = SECBUFFER_EMPTY; // Initial Type of the buffer 4

    Message.ulVersion       = SECBUFFER_VERSION;    // Version number
    Message.cBuffers        = 4;                                    // Number of buffers - must contain four SecBuffer structures.
    Message.pBuffers        = Buffers;                        // Pointer to array of buffers
    
    scRet = sspi->DecryptMessage(&hContext, &Message, 0, NULL);
    
    if( scRet == SEC_I_CONTEXT_EXPIRED ) break; // Server signalled end of session
    
    //      if( scRet == SEC_E_INCOMPLETE_MESSAGE - Input buffer has partial encrypted record, read more
    if( scRet != SEC_E_OK &&
        scRet != SEC_I_RENEGOTIATE &&
        scRet != SEC_I_CONTEXT_EXPIRED )
    { printf("**** DecryptMessage ");
      return scRet; }

    // Locate data and (optional) extra buffers.
    pDataBuffer  = NULL;
    pExtraBuffer = NULL;
    
    for(i = 1; i < 4; i++)
    {
      if( pDataBuffer  == NULL && Buffers[i].BufferType == SECBUFFER_DATA  ) pDataBuffer  = &Buffers[i];
      if( pExtraBuffer == NULL && Buffers[i].BufferType == SECBUFFER_EXTRA ) pExtraBuffer = &Buffers[i];
    }

    if (pDataBuffer!=NULL)
    {
      cbDataIn=pDataBuffer->cbBuffer;
      if (cbDataIn!=0)
      {
        memcpy (pbDataIn, pDataBuffer->pvBuffer, cbDataIn);
      }
    }
      
    // Move any "extra" data to the input buffer.
    if(pExtraBuffer)
    {
      printf ("extra");
      MoveMemory(pbBufferIn, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer);
      cbIoBuffer = pExtraBuffer->cbBuffer; // printf("cbIoBuffer= %d  \n", cbIoBuffer);
    }
    else
    cbIoBuffer = 0;
  printf ("\nhello");
  }

  return SEC_E_OK;
}