Main Page   Class Hierarchy   Compound List   File List   Compound Members  

C_SecureSocket.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  * (c)Copyright 2006 Hewlett-Packard Development Company, LP.
00017  *
00018  */
00019 
00020 #include "Utils.hpp"
00021 #include "C_SecureSocket.hpp"
00022 
00023 
00024 
00025 #define SOCKET_ERROR(l,m) iostream_error << m << iostream_endl << iostream_flush
00026 #ifdef DEBUG_MODE
00027 #define SOCKET_DEBUG(l,m) iostream_error << m << iostream_endl << iostream_flush
00028 #else
00029 #define SOCKET_DEBUG(l,m)
00030 #endif
00031 
00032 C_SecureSocket::C_SecureSocket(SSL_CTX * P_ssl_ctx){
00033   m_ssl_ctx = P_ssl_ctx ;
00034   m_bio = NULL ;
00035   m_ssl = NULL ;
00036 }
00037 
00038 
00039 C_SecureSocket::~C_SecureSocket(){
00040   int   L_ret ;
00041 
00042   m_ssl_ctx = NULL ;
00043 
00044   if (m_ssl) {
00045     L_ret = SSL_shutdown(m_ssl);
00046     switch(L_ret) {
00047     case 1:
00048       break; 
00049     case 0:
00050     case -1:
00051       break; 
00052     default:
00053       SOCKET_ERROR(0, "SSL connect error");
00054       break; 
00055     }
00056     SSL_free(m_ssl);
00057     m_ssl = NULL ;
00058   }
00059 }
00060 
00061 
00062 
00063 static char* m_ssl_error_string[] = {
00064   "SSL_ERROR_NONE",
00065   "SSL_ERROR_SSL",
00066   "SSL_ERROR_WANT_READ",
00067   "SSL_ERROR_WANT_WRITE",
00068   "SSL_ERROR_WANT_X509_LOOKUP",
00069   "SSL_ERROR_SYSCALL",
00070   "SSL_ERROR_ZERO_RETURN",
00071   "SSL_ERROR_WANT_CONNECT"
00072 } ;
00073 
00074 void C_SecureSocket::ssl_error(int P_returnCode) {
00075   
00076   int L_ret ;
00077   L_ret = SSL_get_error(m_ssl, P_returnCode) ;
00078 
00079   if (P_returnCode <= SSL_ERROR_WANT_CONNECT) {
00080     SOCKET_ERROR(0, m_ssl_error_string[L_ret]);
00081   } else {
00082      SOCKET_ERROR(0, "SSL error " << L_ret);
00083   }
00084 }
00085 
00086 
00087 C_SecureSocketListen::C_SecureSocketListen(SSL_CTX * P_ssl_ctx,
00088                                            T_SocketType  P_type, 
00089                                            T_pIpAddr     P_addr, 
00090                                            int           P_channel_id,
00091                                            size_t        P_read_buf_size,
00092                                            size_t        P_segm_buf_size)
00093  : C_SocketListen(P_type, 
00094                   P_addr, 
00095                   P_channel_id,
00096                   P_read_buf_size,
00097                   P_segm_buf_size) ,
00098   C_SecureSocket (P_ssl_ctx) {
00099 }
00100 
00101 C_SecureSocketListen::~C_SecureSocketListen() {
00102 }
00103 
00104 C_Socket* C_SecureSocketListen::create_socket_server(int *P_ret) {
00105   C_SecureSocketServer* L_socket ;
00106   NEW_VAR(L_socket, C_SecureSocketServer(m_ssl_ctx, this, m_channel_id, 
00107                                          m_read_buf_size, m_segm_buf_size));
00108   (*P_ret) = L_socket->_open(m_buffer_size, m_protocol) ;
00109   return (L_socket);
00110 }
00111 
00112 
00113 C_SecureSocketServer::C_SecureSocketServer(SSL_CTX * P_ssl_ctx,
00114                                            C_SocketListen *P_listen, 
00115                                            int P_channel_id,
00116                                            size_t P_read_buf_size,
00117                                            size_t P_segm_buf_size)
00118   : C_SocketServer(P_listen, 
00119                    P_channel_id,
00120                    P_read_buf_size,
00121                    P_segm_buf_size),
00122   C_SecureSocket (P_ssl_ctx) {
00123 
00124 }
00125   
00126 C_SecureSocketServer::C_SecureSocketServer(SSL_CTX * P_ssl_ctx,
00127                                            T_SocketType  P_type, 
00128                                            T_pIpAddr     P_addr, 
00129                                            int           P_channel_id,
00130                                            size_t        P_read_buf_size,
00131                                            size_t        P_segm_buf_size)
00132 : C_SocketServer(P_type, 
00133                  P_addr, 
00134                  P_channel_id,
00135                  P_read_buf_size,
00136                  P_segm_buf_size),
00137   C_SecureSocket (P_ssl_ctx) {
00138 }
00139   
00140   
00141 C_SecureSocketServer::~C_SecureSocketServer() {
00142 }
00143 
00144 int C_SecureSocketServer::_call_read() { 
00145   int L_result = 0 ;
00146     L_result = SSL_read(m_ssl, m_read_buf, m_read_buf_size);
00147     if (L_result < 0) ssl_error(L_result) ;
00148   return (L_result) ;
00149 }
00150 
00151 int C_SecureSocketServer::_secure_mode () {
00152  
00153   int L_result ;
00154   int L_ret = 0 ;
00155 
00156   m_ssl = SSL_new(m_ssl_ctx);
00157   SSL_set_accept_state(m_ssl);
00158   if ((m_bio = BIO_new_socket(m_socket_id, BIO_CLOSE)) == NULL ) {
00159     SOCKET_ERROR(0, "Unable to create the BIO- in New TLS connection");
00160   } 
00161   
00162   SSL_set_bio(m_ssl,m_bio,m_bio);
00163   
00164   L_result = SSL_accept(m_ssl) ;
00165 
00166   if (L_result < 0 ) {
00167     if (SSL_get_error(m_ssl, L_result) == SSL_ERROR_WANT_READ) {
00168       m_state = E_SOCKET_STATE_INPROGESS ;
00169       L_ret = 0 ;
00170     } else {
00171       ssl_error(L_result);
00172       L_ret = -1 ;
00173     }
00174   } 
00175 
00176   return (L_ret);
00177   
00178 }
00179 
00180 int C_SecureSocketServer::_open(size_t P_buffer_size, 
00181                           C_ProtocolBinaryFrame *P_protocol) {
00182   int L_ret ;
00183   L_ret = C_SocketServer::_open(P_buffer_size, P_protocol);
00184 
00185   if (L_ret == 0) {
00186     L_ret = _secure_mode () ;
00187   }
00188   
00189   return (L_ret);
00190 }
00191 
00192 int C_SecureSocketServer::_call_write(unsigned char* P_data,
00193                                       size_t P_size) {
00194   
00195   int L_result = 0 ;
00196   L_result = SSL_write(m_ssl,P_data,P_size);
00197   if (L_result < 0) ssl_error(L_result) ;
00198   return (L_result) ;
00199 
00200 }
00201 
00202 C_SecureSocketClient::C_SecureSocketClient(SSL_CTX * P_ssl_ctx,
00203                                            T_SocketType  P_type, 
00204                                            T_pIpAddr     P_addr, 
00205                                            int           P_channel_id,
00206                                            size_t        P_read_buf_size,
00207                                            size_t        P_segm_buf_size)
00208 : C_SocketClient(P_type, 
00209                  P_addr, 
00210                  P_channel_id,
00211                  P_read_buf_size,
00212                  P_segm_buf_size),
00213   C_SecureSocket (P_ssl_ctx) {
00214 
00215 }
00216 
00217 C_SecureSocketClient::~C_SecureSocketClient() {
00218 
00219   
00220 }
00221 
00222 int C_SecureSocketClient::_call_read() { 
00223 
00224   int L_result = 0 ;
00225 
00226   L_result = SSL_read(m_ssl, m_read_buf, m_read_buf_size);
00227   if (L_result < 0) ssl_error(L_result) ;
00228 
00229   return (L_result) ;
00230 }
00231 
00232 int C_SecureSocketClient::_call_write(unsigned char* P_data,
00233                                       size_t P_size) {
00234   int L_result = 0 ;
00235   L_result = SSL_write(m_ssl,P_data,P_size);
00236   if (L_result < 0) ssl_error(L_result) ;
00237   
00238   return (L_result) ;
00239 }
00240 
00241 int C_SecureSocketClient::_secure_mode() {
00242   int L_result, L_ret ;
00243 
00244   m_ssl = SSL_new(m_ssl_ctx);
00245   SSL_set_connect_state(m_ssl) ;
00246   
00247   if ((m_bio = BIO_new_socket(m_socket_id, BIO_CLOSE)) == NULL ) {
00248     SOCKET_ERROR(0, "Unable to create the BIO- client in New TLS connection");
00249   } 
00250  
00251   
00252   SSL_set_bio(m_ssl,m_bio,m_bio);
00253   
00254   L_result = SSL_connect(m_ssl) ;
00255   if ( L_result < 0 ) {
00256     if (SSL_get_error(m_ssl, L_result) == SSL_ERROR_WANT_READ) {
00257       m_state = E_SOCKET_STATE_INPROGESS ;
00258       L_ret = 0 ;
00259     } else {
00260       ssl_error(L_result);
00261       L_ret = -1 ;
00262     }
00263   } else {
00264     L_ret = 0 ;
00265   }
00266   return (L_ret);
00267   
00268 }
00269 
00270 int C_SecureSocketClient::_open (T_pOpenStatus P_status,
00271                                  size_t        P_buffer_size,
00272                                  C_ProtocolBinaryFrame *P_protocol) {
00273   int L_ret ;
00274 
00275   L_ret = C_SocketClient::_open(P_status, P_buffer_size, P_protocol);
00276 
00277   if (L_ret == 0) {
00278     L_ret = _secure_mode () ;
00279   }
00280 
00281   return (L_ret);
00282 }
00283 
00284 C_Socket* C_SecureSocketClient::process_fd_in_progess (fd_set* P_rSet,
00285                                                        fd_set* P_wSet,
00286                                                        C_TransportEvent *P_event) {
00287   C_Socket* L_socket = NULL ;
00288   int       L_result        ;
00289 
00290   if (FD_ISSET(m_socket_id, P_rSet)) {
00291     L_result = SSL_connect(m_ssl) ;
00292     if ( L_result < 0 ) {
00293       if (SSL_get_error(m_ssl, L_result) == SSL_ERROR_WANT_READ) {
00294         P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ;
00295       } else {
00296         P_event->m_type = C_TransportEvent::E_TRANS_OPEN_FAILED ;
00297       }
00298     } else {
00299       m_state = E_SOCKET_STATE_READY ;
00300       m_ssl->rwstate = SSL_NOTHING ;
00301       P_event->m_type = C_TransportEvent::E_TRANS_OPEN ;
00302     }
00303     P_event->m_channel_id = m_channel_id ;
00304     P_event->m_id = m_socket_id ;
00305   }
00306   return (L_socket);
00307 }
00308 
00309 C_Socket* C_SecureSocketServer::process_fd_in_progess (fd_set* P_rSet,
00310                                                        fd_set* P_wSet,
00311                                                        C_TransportEvent *P_event) {
00312   C_Socket* L_socket = NULL ;
00313   int       L_result        ;
00314 
00315   if (FD_ISSET(m_socket_id, P_rSet)) {
00316     L_result = SSL_accept(m_ssl) ;
00317     if ( L_result < 0 ) {
00318       if (SSL_get_error(m_ssl, L_result) == SSL_ERROR_WANT_READ) {
00319         P_event->m_type = C_TransportEvent::E_TRANS_NO_EVENT ;
00320       } else {
00321         P_event->m_type = C_TransportEvent::E_TRANS_OPEN_FAILED ;
00322       }
00323     } else {
00324       m_state = E_SOCKET_STATE_READY ;
00325       P_event->m_type = C_TransportEvent::E_TRANS_OPEN ;
00326     }
00327     P_event->m_channel_id = m_channel_id ;
00328     P_event->m_id = m_socket_id ;
00329   }
00330   return (L_socket);
00331 }
00332 
00333 C_SecureSocketClient::C_SecureSocketClient
00334 (SSL_CTX * P_ssl_ctx, C_SocketClient& P_Socket)
00335   : C_SocketClient(P_Socket), C_SecureSocket(P_ssl_ctx) {
00336   (void) _secure_mode();
00337 }
00338 
00339 C_SecureSocketServer::C_SecureSocketServer
00340 (SSL_CTX * P_ssl_ctx, C_SocketServer& P_Socket)
00341   : C_SocketServer(P_Socket), C_SecureSocket(P_ssl_ctx) {
00342   (void) _secure_mode();
00343 }
00344 
00345 C_SecureSocketListen::C_SecureSocketListen
00346 (SSL_CTX * P_ssl_ctx, C_SocketListen& P_Socket) 
00347   : C_SocketListen(P_Socket),
00348     C_SecureSocket (P_ssl_ctx) {
00349 }
00350 
00351 
00352 
00353 

Generated on Wed Mar 7 14:44:58 2007 for Seagull by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002