Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

client.cpp 4.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /******************************************************************************/
  2. /**
  3. \Author Krzysztof Kwiatkowski
  4. \File client.cpp
  5. \Description The SSL client which connects to the server.cpp
  6. and initiates renegotitaion after RENEG_INIT_LEN
  7. chars exchanged with the server
  8. *******************************************************************************/
  9. #include "client.h"
  10. #include <unistd.h>
  11. #include "defs.h"
  12. #include <sys/socket.h>
  13. #include <arpa/inet.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <iostream>
  18. #include <netinet/in.h>
  19. #include <boost/thread/thread.hpp>
  20. #include <boost/thread/mutex.hpp>
  21. #include <boost/thread/locks.hpp>
  22. #include <fcntl.h>
  23. #include <openssl/err.h>
  24. using namespace std;
  25. using namespace boost;
  26. int Handler = 0;
  27. SSL* SSLHandler = 0;
  28. int CharsRead = 0;
  29. // with this you can block sender thread during renegotiation
  30. mutex WriteReadMutex;
  31. void Sender()
  32. {
  33. while(1)
  34. {
  35. string buf(EXCHANGE_STRING);
  36. int len = 0;
  37. SSL_write(SSLHandler, buf.c_str()+len, buf.size()-len);
  38. /*
  39. do
  40. {
  41. lock_guard<mutex> lock(WriteReadMutex);
  42. len+=SSL_write(SSLHandler, buf.c_str()+len, buf.size()-len);
  43. // for debugging re-neg
  44. // cout << "SSL STATE: " << SSL_state_string(handler.second) << endl;
  45. } while( len != static_cast<int>(buf.size()) );
  46. */
  47. }
  48. };
  49. void Client::receive()
  50. {
  51. char buf[MAX_PACKET_SIZE];
  52. // TODO: this way it takes 100% CPU, some signal would be usefull
  53. memset(buf,'\0',MAX_PACKET_SIZE);
  54. int len_rcv = 0;
  55. {
  56. lock_guard<mutex> lock(WriteReadMutex);
  57. cout << "A" << endl;
  58. len_rcv = SSL_read(SSLHandler, buf, MAX_PACKET_SIZE);
  59. }
  60. if( len_rcv != 0 )
  61. {
  62. CharsRead += len_rcv;
  63. // dirty thing - if it has \n on the end - remove it
  64. if( buf[len_rcv-1] == '\n' )
  65. buf[len_rcv-1] = '\0';
  66. cout << buf << endl;
  67. }
  68. else
  69. {
  70. cout << "Closing connection " << _handler << endl;
  71. ::close(_handler);
  72. }
  73. }
  74. void Client::connect()
  75. {
  76. lock_guard<mutex> lock(WriteReadMutex);
  77. struct sockaddr_in echoserver;
  78. int sock = socket(AF_INET, SOCK_STREAM, 0);
  79. memset(&echoserver, 0, sizeof(echoserver));
  80. echoserver.sin_family = AF_INET;
  81. echoserver.sin_addr.s_addr = inet_addr(IP);
  82. echoserver.sin_port = htons(PORT);
  83. /* Establish connection */
  84. if ( 0 > ::connect(sock, (struct sockaddr *) &echoserver, sizeof(echoserver)) )
  85. {
  86. throw runtime_error("Can't connect to the server");
  87. }
  88. Handler = sock;
  89. SSLHandler = SSL_new(_ctx);
  90. SSL_set_fd(SSLHandler, Handler);
  91. if( SSL_connect(SSLHandler) <= 0)
  92. {
  93. cerr << "Can't setup SSL session" << endl;
  94. exit(1);
  95. }
  96. fcntl(sock, F_SETFL, O_NONBLOCK);
  97. }
  98. void Client::start()
  99. {
  100. // start sender thread first
  101. _sender =new thread( Sender );
  102. struct timeval tv;
  103. // go to select loop
  104. while(1)
  105. {
  106. // wait timer for select
  107. tv.tv_sec = 0;
  108. tv.tv_usec = 10;
  109. fd_set fd_read;
  110. FD_ZERO(&fd_read);
  111. FD_SET(_handler, &fd_read);
  112. select(_handler+1, &fd_read, NULL, NULL, (struct timeval *)&tv);
  113. if( FD_ISSET(_handler, &fd_read ) )
  114. {
  115. // this should be in other thread but... it works
  116. if( CharsRead > RENEG_INIT_LEN )
  117. {
  118. CharsRead = 0;
  119. renegotiate();
  120. }
  121. receive();
  122. }
  123. }
  124. }
  125. void Client::renegotiate()
  126. {
  127. lock_guard<mutex> lock_reads(WriteReadMutex);
  128. cout << "B" << endl;
  129. cout << "Starting SSL renegotiation on SSL"
  130. << "client (initiating by SSL client)" << endl;
  131. cout << "SSL State: " << SSL_state_string(SSLHandler) << endl;
  132. if(SSL_renegotiate(SSLHandler) <= 0){
  133. cerr << "SSL_renegotiate() failed. STATE: "
  134. << SSL_state_string(SSLHandler) << endl;
  135. ERR_print_errors_fp(stderr);
  136. exit(1);
  137. }
  138. cout << "SSL State: " << SSL_state_string(SSLHandler) << endl;
  139. if(SSL_do_handshake(SSLHandler) <= 0){
  140. cerr << "SSL_do_handshake() failed. STATE: "
  141. << SSL_state_string(SSLHandler) << endl;
  142. ERR_print_errors_fp(stderr);
  143. exit(1);
  144. }
  145. }
  146. void Client::init()
  147. {
  148. sslInit();
  149. }
  150. // --- MAIN --- //
  151. int main()
  152. {
  153. try
  154. {
  155. Client client;
  156. client.init();
  157. client.connect();
  158. client.start();
  159. }
  160. catch(std::runtime_error& e)
  161. {
  162. cerr << "ERROR " << e.what() << endl;
  163. }
  164. catch(...)
  165. {
  166. cerr << "Unknown exception" << endl;
  167. }
  168. return 0;
  169. }