youda008

SSL timeout

May 17th, 2023
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.92 KB | Source Code | 0 0
  1. #include <cstdio>        // printf, scanf
  2. #include <cstring>       // strerror
  3. #include <cerrno>
  4.  
  5. #ifdef _WIN32
  6.     #include <winsock2.h>
  7.     #include <ws2tcpip.h>    // getaddrinfo
  8. #else
  9.     #include <unistd.h>      // open, close, read, write
  10.     #include <sys/socket.h>  // socket
  11.     #include <netdb.h>       // getaddrinfo, gethostbyname
  12.     #include <netinet/in.h>  // sockaddr_in, in_addr, ntoh, hton
  13.     #include <arpa/inet.h>   // inet_addr, inet_ntoa
  14. #endif // _WIN32
  15.  
  16. #include <openssl/ssl.h>
  17.  
  18. using namespace std;
  19.  
  20.  
  21. typedef unsigned int  uint;
  22. typedef unsigned char uchar;
  23. typedef          int  fd_t;
  24.  
  25.  
  26. int getLastError()
  27. {
  28.  #ifdef _WIN32
  29.     return int( WSAGetLastError() );
  30.  #else
  31.     return errno;
  32.  #endif // _WIN32
  33. }
  34.  
  35. bool setTimeout( fd_t sock, uint timeout_ms )
  36. {
  37.  #ifdef _WIN32
  38.     DWORD timeout = (DWORD)timeout_ms;
  39.  #else
  40.     struct timeval timeout;
  41.     timeout.tv_sec  = long( timeout_ms / 1000 );
  42.     timeout.tv_usec = long( timeout_ms % 1000 ) * 1000;
  43.  #endif // _WIN32
  44.  
  45.     return ::setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout) ) == 0;
  46. }
  47.  
  48. int main( int argc, char * argv [] )
  49. {
  50.     int port;
  51.     struct addrinfo * ainfo;
  52.     fd_t socketFd;
  53.     SSL_CTX * ctx;
  54.     SSL * ssl;
  55.     char request [1024];
  56.     unsigned char * buffer [1024];
  57.     int received;
  58.  
  59. #ifdef _WIN32
  60.     WSADATA wsaData;
  61.     WSAStartup( MAKEWORD(2, 2), &wsaData );
  62. #endif // _WIN32
  63.  
  64.     if (argc < 4 || !sscanf(argv[2], "%d", &port)) {
  65.         fprintf( stderr, "usage: %s <hostname> <port> <item>\n", argv[0] );
  66.         return 1;
  67.     }
  68.  
  69.     const char * hostName = argv[1];
  70.     const char * portStr = argv[2];
  71.  
  72.     if (getaddrinfo( hostName, portStr, NULL, &ainfo ) != 0)
  73.     {
  74.         fprintf( stderr, " failed to get host info (%d)\n", getLastError() );
  75.         return 2;
  76.     }
  77.  
  78.     socketFd = socket( ainfo->ai_family, SOCK_STREAM, 0 );
  79.     if (socketFd == -1) {
  80.         fprintf( stderr, " failed to create socket (%d)\n", getLastError() );
  81.         freeaddrinfo( ainfo );
  82.         return 2;
  83.     }
  84.  
  85.     if (connect( socketFd, ainfo->ai_addr, ainfo->ai_addrlen ) != 0) {
  86.         fprintf( stderr, " failed to connect to %s:%s  (%d)\n", hostName, portStr, getLastError() );
  87.         freeaddrinfo( ainfo );
  88.         return 2;
  89.     }
  90.  
  91.     freeaddrinfo( ainfo );
  92.  
  93.     if (!setTimeout(socketFd, 5000)) {
  94.         fprintf( stderr, " failed to set timeout\n" );
  95.         return 2;
  96.     }
  97.  
  98.     SSL_library_init();
  99.     ctx = SSL_CTX_new( SSLv23_client_method() );
  100.     if (!ctx)
  101.     {
  102.         printf( "SSL_CTX_new failed (%d)\n", SSL_get_error( ssl, 0 ) );
  103.         return 3;
  104.     }
  105.     //SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
  106.     ssl = SSL_new( ctx );
  107.     if (!ssl)
  108.     {
  109.         printf( "SSL_new failed (%d)\n", SSL_get_error( ssl, 0 ) );
  110.         return 3;
  111.     }
  112.     int r1 = SSL_set_fd( ssl, socketFd );
  113.     if (r1 <= 0)
  114.     {
  115.         printf( "SSL_set_fd failed (%d)\n", SSL_get_error( ssl, r1 ) );
  116.         return 3;
  117.     }
  118.     int r2 = SSL_connect( ssl );
  119.     if (r2 <= 0)
  120.     {
  121.         printf( "SSL_connect failed (%d, %d)\n", SSL_get_error( ssl, r2 ), getLastError() );
  122.         return 3;
  123.     }
  124.  
  125.     sprintf( request, "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", argv[3], argv[1] );
  126.     int written = SSL_write( ssl, request, strlen(request) );
  127.     if (written <= 0)
  128.     {
  129.         printf( "write failed (%d)\n", SSL_get_error( ssl, written ) );
  130.         return 3;
  131.     }
  132.  
  133.     if (!setTimeout( socketFd, 1 )) {
  134.         fprintf( stderr, " failed to set timeout\n" );
  135.         return 2;
  136.     }
  137.  
  138.     while (true)
  139.     {
  140.         received = SSL_read( ssl, buffer, sizeof(buffer) );
  141.         if (received > 0)
  142.         {
  143.             printf( "(%d) %*s\n", received, received, buffer ); fflush( stdout );
  144.         }
  145.         else if (received == 0)
  146.         {
  147.             printf( "connection closed\n" ); fflush( stdout );
  148.             break;
  149.         }
  150.         else
  151.         {
  152.             int error = SSL_get_error( ssl, received );
  153.             printf( "read failed (%d, %d)\n", error, getLastError() ); fflush( stdout );
  154.             break;
  155.         }
  156.  
  157.         while (getchar() != '\n') {}
  158.     }
  159.  
  160.     SSL_shutdown( ssl );
  161.     SSL_free( ssl );
  162.     SSL_CTX_free( ctx );
  163. #ifdef _WIN32
  164.     closesocket(socketFd);
  165.     WSACleanup();
  166. #else
  167.     close( socketFd );
  168. #endif // _WIN32
  169.  
  170.     return 0;
  171. }
  172.  
Tags: SSL
Advertisement
Add Comment
Please, Sign In to add comment