Exemplo n.º 1
0
/* Send req and get response */
int http_transaction(http_t *client, http_trans_t *trans)
{
	int rc = 0;

	ASSERT(client);
	ASSERT(trans);

	if (!client->initialized)
		return RC_HTTP_OBJECT_NOT_INITIALIZED;

	trans->rsp_len = 0;
	do {
#ifdef ENABLE_SSL
		if (client->ssl_enabled) {
			TRY(ssl_send(client, trans->p_req, trans->req_len));
			TRY(ssl_recv(client, trans->p_rsp, trans->max_rsp_len, &trans->rsp_len));
		}
		else
#endif
		{
			TRY(tcp_send(&client->tcp, trans->p_req, trans->req_len));
			TRY(tcp_recv(&client->tcp, trans->p_rsp, trans->max_rsp_len, &trans->rsp_len));
		}
	}
	while (0);

	trans->p_rsp[trans->rsp_len] = 0;
	http_response_parse(trans);

	return rc;
}
Exemplo n.º 2
0
/* Helper routines */
static IOResult client_recv(struct Client *cptr, char *buf, unsigned int length, unsigned int* count_out)
{
  if (cli_socket(cptr).s_ssl)
    return ssl_recv(&cli_socket(cptr), buf, length, count_out);
  else
    return os_recv_nonb(cli_fd(cptr), buf, length, count_out);
}
Exemplo n.º 3
0
int gitno_recv(gitno_buffer *buf)
{
	int ret;

#ifdef GIT_SSL
	if (buf->ssl != NULL) {
		if ((ret = ssl_recv(buf->ssl, buf->data + buf->offset, buf->len - buf->offset)) < 0)
			return -1;
	} else {
		ret = p_recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0);
		if (ret < 0) {
			net_set_error("Error receiving socket data");
			return -1;
		}
	}
#else
	ret = p_recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0);
	if (ret < 0) {
		net_set_error("Error receiving socket data");
		return -1;
	}
#endif

	buf->offset += ret;
	return ret;
}
Exemplo n.º 4
0
/*
 * Receives Plain Text file to the receiver
 * SSL *conn                -> The SSL connection of the sender
 * const char *fname        -> The name of the file to store
 * returns the total amount of bytes sent and encrypted
 */
ssize_t ssl_recv_file(SSL *conn, const char *fname)
{
    ssize_t len = 0, total = 0;
    char buf[BUFFSIZE];
    FILE *file = nullptr;
    if((file = fopen(fname, "wb")) == nullptr) return FILE_NOT_FOUND;
    while((len = ssl_recv(conn, buf, sizeof(buf))-1) > 0) {
        total += fwrite(buf+1, sizeof(char), (size_t)len, file);
    }
    fclose(file);
    if(len < 0) {
        perror("ssl_recv() failed");
        return -1;
    }
    return total;
}
Exemplo n.º 5
0
/*
 * Recieve up to len bytes from the socket in socket_fd and
 * store the result in buf.
 * Return value:
 *   Returns the number of bytes recieved, or -1 on failure.
 */
ssize_t
socket_recv(struct socket_in *s, const char *delim)
{
	ssize_t bytes = 0;
	
	/* Sanity checks. */
	if(s == NULL || s->buffer == NULL)
		return(-1);
	
#ifdef OPENSSL_ENABLED
	if(s->ssl != NULL)
		bytes = ssl_recv(s, delim);
		
	else
#endif /* OPENSSL_ENABLED */
	
	{
		struct socket_buf *b = s->buffer;
		ssize_t temp_bytes;
		bytes = (b->w_next-b->w_start);
		
		do
		{
			if((temp_bytes = recv(s->fd, b->w_next, SOCKET_WBUFSIZE-bytes, 0)) == -1)
			{
				if(errno != EAGAIN && errno != EINTR)
					return(errno);
				
				break;
			}
			
			bytes += temp_bytes;
			b->w_next += sizeof(*b->w_next)*temp_bytes;
		}
		while(strstr(b->w_start, delim) == NULL && bytes < SOCKET_WBUFSIZE);
	}
	
	/* Split up the results into a linked-list. */
	socket_chunk(s, delim);
	
	return(bytes);
}
Exemplo n.º 6
0
/*
 * Recieves AES-CBC-128 bit encrypted file from sender and decrypts the file
 * and saves it to the file specified in the arguments
 * SSL *conn                -> The SSL connection for the sender's node
 * const unsigned char *key -> The already instantiated AES Key for decryption
 * const char *fname        -> The name of the file to be stored
 * returns the total amount of bytes read and decrypted
 */
ssize_t crypto_recv_file(SSL *conn, const unsigned char *key, const char *fname)
{
    int len, ciph_len, first = 0;
    size_t total = 0;
    unsigned char plaintxt[BUFFSIZE];
    unsigned char ciphtxt[BUFFSIZE];
    unsigned char iv[IV_LEN];
    EVP_CIPHER_CTX cntx;
    FILE *file;
    if((file = fopen(fname, "wb")) == nullptr) {
        return FILE_NOT_FOUND;
    }
    while ((len = (int)ssl_recv(conn,(char *)ciphtxt, sizeof(ciphtxt))-1) > 0) {
        if(!first) {
            memcpy(iv, ciphtxt+1, sizeof(iv));
            EVP_CipherInit(&cntx, EVP_aes_128_cbc(), key, iv, DECRYPT);
        }
        EVP_CipherUpdate(&cntx, plaintxt, &ciph_len, ciphtxt+1, len);
        total += fwrite(plaintxt+(first?0:16), 1,
                        (size_t)ciph_len-(first?0:16), file);

        /* Last transmission of the file */
        if(len < BUFFSIZE-1) break;
        first++;
    }
    if (len < 0) goto err;
    EVP_CipherFinal(&cntx, plaintxt, &ciph_len);
    total+=fwrite(plaintxt, 1, (size_t)ciph_len, file);
    EVP_CIPHER_CTX_cleanup(&cntx);
    WAITFORACK(conn);
    fclose(file);
    return total;

    err:
    perror("GOTHERE");
    EVP_CIPHER_CTX_cleanup(&cntx);
    die_with_err("send() failed");
    return 1;
}
Exemplo n.º 7
0
/* Send req and get response */
int http_transaction(http_t *client, http_trans_t *trans)
{
	int rc = 0;

	ASSERT(client);
	ASSERT(trans);

	if (!client->initialized)
		return RC_HTTP_OBJECT_NOT_INITIALIZED;

	trans->rsp_len = 0;
	do {
		TRY(ssl_send(client, trans->req, trans->req_len));
		TRY(ssl_recv(client, trans->rsp, trans->max_rsp_len, &trans->rsp_len));
	}
	while (0);

	trans->rsp[trans->rsp_len] = 0;
	http_response_parse(trans);

	return rc;
}
int SocketReadHTTPSHeader( mico_ssl_t ssl, HTTPHeader_t *inHeader )
{
  int        err =0;
  char *          buf;
  char *          dst;
  char *          lim;
  char *          end;
  size_t          len;
  ssize_t         n;
  
  buf = inHeader->buf;
  dst = buf + inHeader->len;
  lim = buf + inHeader->bufLen;
  for( ;; )
  {
    if(findHeader( inHeader,  &end ))
      break ;
    n = ssl_recv( ssl, dst, (size_t)( lim - dst ) );
    if(      n  > 0 ) len = (size_t) n;
    else  { err = kConnectionErr; goto exit; }
    dst += len;
    inHeader->len += len;
  }
  
  inHeader->len = (size_t)( end - buf );
  err = HTTPHeaderParse( inHeader );
  require_noerr( err, exit );
  inHeader->extraDataLen = (size_t)( dst - end );
  if(inHeader->extraDataPtr) {
    free((uint8_t *)inHeader->extraDataPtr);
    inHeader->extraDataPtr = 0;
  }

  /* For chunked extra data without content length */
  if(inHeader->chunkedData == true){
    inHeader->chunkedDataBufferLen = (inHeader->extraDataLen > READ_LENGTH)? inHeader->extraDataLen:READ_LENGTH;
    inHeader->chunkedDataBufferPtr = calloc(inHeader->chunkedDataBufferLen, sizeof(uint8_t)); //Make extra data buffer larger than chunk length
    require_action(inHeader->chunkedDataBufferPtr, exit, err = kNoMemoryErr);
    memcpy((uint8_t *)inHeader->chunkedDataBufferPtr, end, inHeader->extraDataLen);
    inHeader->extraDataPtr = inHeader->chunkedDataBufferPtr;
    return kNoErr;
  }

  /* Extra data with content length */
  if (inHeader->contentLength != 0){ //Content length >0, create a memory buffer (Content length) and store extra data
    size_t copyDataLen = (inHeader->contentLength >= inHeader->extraDataLen)? inHeader->extraDataLen : inHeader->contentLength;
    if(inHeader->onReceivedDataCallback && (inHeader->onReceivedDataCallback)(inHeader, 0, (uint8_t *)end, copyDataLen, inHeader->userContext)==kNoErr){
      inHeader->isCallbackSupported = true;
      inHeader->extraDataPtr = calloc(READ_LENGTH, sizeof(uint8_t));
      require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
    }else{
      inHeader->isCallbackSupported = false;
      inHeader->extraDataPtr = calloc(inHeader->contentLength , sizeof(uint8_t));
      require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
      memcpy((uint8_t *)inHeader->extraDataPtr, end, copyDataLen);
    }
    err = kNoErr;
  }/* Extra data without content length, data is ended by conntection close */
  // else if(inHeader->extraDataLen != 0){ //Content length =0, but extra data length >0, create a memory buffer (1500)and store extra data
  //   inHeader->dataEndedbyClose = true;
  //   inHeader->extraDataPtr = calloc(1500, sizeof(uint8_t));
  //   require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
  //   memcpy((uint8_t *)inHeader->extraDataPtr, end, inHeader->extraDataLen);
  //   (inHeader->onReceivedDataCallback)(inHeader, 0, (uint8_t *)inHeader->extraDataPtr, inHeader->extraDataLen, inHeader->userContext);

  //   err = kNoErr;
  // }
  else
    return kNoErr;
  
exit:
  return err;
}
OSStatus SocketReadHTTPSBody( mico_ssl_t ssl, HTTPHeader_t *inHeader )
{
  OSStatus err = kParamErr;
  ssize_t readResult;
  int selectResult;
  fd_set readSet;
  size_t    lastChunkLen, chunckheaderLen; 
  char *nextPackagePtr;
  struct timeval_t t;
  size_t          readLength;
  uint32_t pos = 0;
  t.tv_sec = 5;
  t.tv_usec = 0;
  int inSock = CyaSSL_get_fd( ssl );
  
  require( inHeader, exit );
  err = kNotReadableErr;
  
  FD_ZERO( &readSet );
  FD_SET( inSock, &readSet );

  /* Chunked data without content length */
  if( inHeader->chunkedData == true ){
    do{
      /* Find Chunk data length */
      while ( findChunkedDataLength( inHeader->chunkedDataBufferPtr, inHeader->extraDataLen, &inHeader->extraDataPtr ,"%llu", &inHeader->contentLength ) == false){
        require_action(inHeader->extraDataLen < inHeader->chunkedDataBufferLen, exit, err=kMalformedErr );

        selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
        require_action( selectResult >= 1, exit, err = kNotReadableErr );

        readResult = ssl_recv( ssl, inHeader->chunkedDataBufferPtr + inHeader->extraDataLen, (size_t)( inHeader->chunkedDataBufferLen - inHeader->extraDataLen ) );

        if( readResult  > 0 ) inHeader->extraDataLen += readResult;
        else { err = kConnectionErr; goto exit; }
      }

      chunckheaderLen = inHeader->extraDataPtr - inHeader->chunkedDataBufferPtr;

      /* Check the last chunk */
      if(inHeader->contentLength == 0){ 
        while( findCRLF( inHeader->extraDataPtr, inHeader->extraDataLen - chunckheaderLen, &nextPackagePtr ) == false){ //find CRLF
          selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
          require_action( selectResult >= 1, exit, err = kNotReadableErr );

          readResult = ssl_recv( ssl,
                            (uint8_t *)( inHeader->extraDataPtr + inHeader->extraDataLen - chunckheaderLen ),
                            256 - inHeader->extraDataLen ); //Assume chunk trailer length is less than 256 (256 is the min chunk buffer, maybe dangerous

          if( readResult  > 0 ) inHeader->extraDataLen += readResult;
          else { err = kConnectionErr; goto exit; }
          (inHeader->onReceivedDataCallback)(inHeader, inHeader->extraDataLen - readResult, (uint8_t *)inHeader->extraDataPtr, readResult, inHeader->userContext);
        }

        err = kNoErr;
        goto exit;
      } 
      else{ // Read chunk data
        /* Chunk package already exist, callback, move to buffer's head */
        if( inHeader->extraDataLen >= inHeader->contentLength + chunckheaderLen + 2 ){
          require_action( *(inHeader->extraDataPtr + inHeader->contentLength ) == '\r' &&
                          *(inHeader->extraDataPtr + inHeader->contentLength + 1 ) == '\n', 
                          exit, err = kMalformedErr);

          (inHeader->onReceivedDataCallback)(inHeader,  pos, 
                                                        (uint8_t *)inHeader->extraDataPtr, 
                                                        inHeader->contentLength, 
                                                        inHeader->userContext);
          pos+=inHeader->contentLength;

          /* Move next chunk to chunked data buffer header point */
          lastChunkLen = inHeader->extraDataPtr - inHeader->chunkedDataBufferPtr + inHeader->contentLength;
          if(inHeader->contentLength) lastChunkLen += 2;  //Last chunck data has a CRLF tail
          memmove( inHeader->chunkedDataBufferPtr, inHeader->chunkedDataBufferPtr + lastChunkLen, inHeader->chunkedDataBufferLen - lastChunkLen  );
          inHeader->extraDataLen -= lastChunkLen;
        }
        /* Chunck exist without the last LF, generate callback abd recv LF */
        /* Callback , read LF */
        else if(inHeader->extraDataLen == inHeader->contentLength + chunckheaderLen +1){ //recv CR 

          require_action( *(inHeader->chunkedDataBufferPtr + inHeader->extraDataLen - 1) == '\r' ,
                          exit, err = kMalformedErr);

          (inHeader->onReceivedDataCallback)(inHeader,  pos, 
                                                        (uint8_t *)inHeader->extraDataPtr, 
                                                        inHeader->extraDataLen - chunckheaderLen-1, 
                                                        inHeader->userContext);
          pos+=inHeader->extraDataLen - chunckheaderLen-1;
          selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
          require_action( selectResult >= 1, exit, err = kNotReadableErr );

          readResult = ssl_recv( ssl, (uint8_t *)inHeader->extraDataPtr, 1);

          if( readResult  > 0 ) {}
          else { err = kConnectionErr; goto exit; }

          require_action( *(inHeader->extraDataPtr) == '\n', exit, err = kMalformedErr);
          inHeader->extraDataLen = 0;
        }
        else{
          /* Callback , read , callback , read CRLF */
          (inHeader->onReceivedDataCallback)(inHeader, pos, 
                                                       (uint8_t *)inHeader->extraDataPtr, 
                                                       inHeader->extraDataLen - chunckheaderLen, 
                                                       inHeader->userContext);
          pos += inHeader->extraDataLen - chunckheaderLen;

          while ( inHeader->extraDataLen < inHeader->contentLength + chunckheaderLen  ){
            selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
            require_action( selectResult >= 1, exit, err = kNotReadableErr );

            if( inHeader->contentLength - (inHeader->extraDataLen - chunckheaderLen) > inHeader->chunkedDataBufferLen - chunckheaderLen)
              //Data needed is greater than valid buffer size
              readLength = inHeader->chunkedDataBufferLen - chunckheaderLen; 
            else
              //Data needed is less than valid buffer size
              readLength = inHeader->contentLength - (inHeader->extraDataLen - chunckheaderLen) ; 

            readResult = ssl_recv( ssl, (uint8_t *)inHeader->extraDataPtr, readLength);
            
            if( readResult  > 0 ) inHeader->extraDataLen += readResult;
            else { err = kConnectionErr; goto exit; }

            (inHeader->onReceivedDataCallback)(inHeader, pos, 
                                                         (uint8_t *)inHeader->extraDataPtr, 
                                                         readResult, 
                                                         inHeader->userContext);
            pos += readResult;
          } 

          selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
          require_action( selectResult >= 1, exit, err = kNotReadableErr );

          readResult = ssl_recv( ssl, (uint8_t *)inHeader->extraDataPtr, 2);

          if( readResult  > 0 ) {}
          else { err = kConnectionErr; goto exit; }


          require_action( *(inHeader->extraDataPtr) == '\r' &&
                          *(inHeader->extraDataPtr+1 ) == '\n', 
                          exit, err = kMalformedErr);

          inHeader->extraDataLen = 0;
        }
      }
    }while(inHeader->contentLength != 0);
  }

  /* We has extra data but total length is not clear, store them to 1500 bytes buffer 
     return when connection is disconnected by remote server */
  // if( inHeader->dataEndedbyClose == true){ 
  //   if(inHeader->contentLength == 0) { //First read body, return using data received by SocketReadHTTPHeader
  //     inHeader->contentLength = inHeader->extraDataLen;
  //   }else{
  //     selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
  //     require_action( selectResult >= 1, exit, err = kNotReadableErr );
      
  //     readResult = read( inSock,
  //                       (uint8_t*)( inHeader->extraDataPtr ),
  //                       1500 );
  //     if( readResult  > 0 ) inHeader->contentLength = readResult;
  //     else { err = kConnectionErr; goto exit; }
  //   }
  //   err = kNoErr;
  //   goto exit;
  // }

  while ( inHeader->extraDataLen < inHeader->contentLength )
  {
    selectResult = select( inSock + 1, &readSet, NULL, NULL, &t );
    require_action( selectResult >= 1, exit, err = kNotReadableErr );

    if(inHeader->isCallbackSupported == true){
      /* We has extra data, and we give these data to application by onReceivedDataCallback function */
      readLength = inHeader->contentLength - inHeader->extraDataLen > READ_LENGTH? READ_LENGTH:inHeader->contentLength - inHeader->extraDataLen;
      readResult = ssl_recv( ssl,
                        (uint8_t*)( inHeader->extraDataPtr),
                        readLength );
      
      if( readResult  > 0 ) inHeader->extraDataLen += readResult;
      else { err = kConnectionErr; goto exit; }      
      (inHeader->onReceivedDataCallback)(inHeader, inHeader->extraDataLen - readResult, (uint8_t *)inHeader->extraDataPtr, readResult, inHeader->userContext);
    }else{
      /* We has extra data and we has a predefined buffer to store the total extra data return when all data has received*/
      readResult = ssl_recv( ssl,
                        (uint8_t*)( inHeader->extraDataPtr + inHeader->extraDataLen ),
                        ( inHeader->contentLength - inHeader->extraDataLen ) );
      
      if( readResult  > 0 ) inHeader->extraDataLen += readResult;
      else { err = kConnectionErr; goto exit; }
    }
  }
  err = kNoErr;
  
exit:
  if(err != kNoErr) inHeader->len = 0;
  return err;
}