35 #include <openssl/ssl.h> 36 #include <openssl/err.h> 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 #include <netinet/in.h> 40 #include <arpa/inet.h> 46 #ifndef HAVE_SYS_ERRLIST 60 const string &cert_file,
61 const string &cert_auth_file,
62 const string &key_file )
66 _cafile( cert_auth_file ),
78 BESDEBUG(
"ppt",
"Loading SSL error strings ... " << endl ) ;
79 SSL_load_error_strings() ;
82 BESDEBUG(
"ppt",
"Initializing SSL library ... " << endl ) ;
86 #if OPENSSL_VERSION_NUMBER < 0x10000000L 87 SSL_METHOD *method = NULL ;
89 const SSL_METHOD *method = NULL ;
91 SSL_CTX *context = NULL ;
92 BESDEBUG(
"ppt",
"Creating method and context ... " << endl ) ;
93 method = SSLv3_server_method() ;
96 context = SSL_CTX_new( method ) ;
100 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
101 string msg =
"Failed to create SSL context\n" ;
102 msg += ERR_error_string( ERR_get_error(), NULL ) ;
110 bool ok_2_continue = false ;
113 BESDEBUG(
"ppt",
"Setting certificate and key ... " << endl ) ;
114 if( SSL_CTX_use_certificate_file( context, _cfile.c_str(), SSL_FILETYPE_PEM ) <= 0 )
116 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
117 err_msg =
"FAILED to use certificate file " + _cfile +
"\n" ;
118 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
120 else if( SSL_CTX_use_PrivateKey_file( context, _kfile.c_str(), SSL_FILETYPE_PEM ) <= 0 )
122 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
123 err_msg =
"FAILED to use private key file " + _kfile +
"\n" ;
124 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
126 else if( !SSL_CTX_check_private_key( context ) )
128 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
129 err_msg =
"FAILED to authenticate private key\n" ;
130 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
134 ok_2_continue = true ;
140 BESDEBUG(
"ppt",
"Certificate setup ... " << endl ) ;
141 SSL_CTX_set_verify( context, SSL_VERIFY_PEER, verify_client ) ;
142 SSL_CTX_set_client_CA_list( context, SSL_load_client_CA_file( _cafile.c_str() ));
143 if( ( !SSL_CTX_load_verify_locations( context, _cafile.c_str(), NULL )) ||
144 ( !SSL_CTX_set_default_verify_paths( context ) ) )
146 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
147 err_msg =
"Certificate setup failed\n" ;
148 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
149 ok_2_continue = false ;
158 BESDEBUG(
"ppt",
"Opening port " << _port <<
"... " << endl ) ;
159 port_fd = open_port( ) ;
162 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
163 err_msg =
"Failed to open port: " ;
164 #ifdef HAVE_SYS_ERRLIST 165 err_msg += sys_errlist[errno] ;
167 err_msg += strerror( errno ) ;
169 ok_2_continue = false ;
178 BESDEBUG(
"ppt",
"Waiting for client connection ... " << endl ) ;
179 sock_fd = accept( port_fd, NULL, NULL ) ;
182 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
183 err_msg =
"Failed to accept connection: " ;
184 #ifdef HAVE_SYS_ERRLIST 185 err_msg += sys_errlist[errno] ;
187 err_msg += strerror( errno ) ;
189 ok_2_continue = false ;
197 BESDEBUG(
"ppt",
"Establishing secure connection ... " << endl ) ;
202 err_msg =
"FAILED to create new connection\n" ;
203 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
204 ok_2_continue = false ;
208 err_msg =
"FAILED to set the socket descriptor\n" ;
209 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
210 ok_2_continue = false ;
212 else if( ( ssl_ret = SSL_accept(
_connection ) ) < 0 )
214 err_msg =
"FAILED to create SSL connection\n" ;
215 err_msg += ERR_error_string( SSL_get_error(
_connection, ssl_ret ), NULL ) ;
216 ok_2_continue = false ;
218 else if( verify_connection( ) < 0 )
220 err_msg =
"FAILED to verify SSL connection\n" ;
221 err_msg += ERR_error_string( ERR_get_error(), NULL ) ;
222 ok_2_continue = false ;
232 BESDEBUG(
"ppt",
"FAILED" << endl ) ;
241 SSLServer::open_port( )
244 struct sockaddr_in addr ;
247 fd = socket( PF_INET, SOCK_STREAM, 0 ) ;
248 if( fd < 0 )
return fd ;
250 setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (
char *)&on,
sizeof( on ) ) ;
252 memset( &addr, 0,
sizeof( addr ) ) ;
253 addr.sin_family = AF_INET ;
254 addr.sin_addr.s_addr = INADDR_ANY ;
255 addr.sin_port = htons( _port ) ;
257 if( bind( fd, (
struct sockaddr *)&addr,
sizeof( addr ) ) < 0 )
262 if( listen( fd, SOMAXCONN ) < 0 )
272 SSLServer::verify_connection( )
274 X509 *server_cert = NULL ;
289 SSLServer::verify_client(
int ok, X509_STORE_CTX *ctx )
293 BESDEBUG(
"ppt",
"VERIFIED " << endl ) ;
294 X509 *user_cert = X509_STORE_CTX_get_current_cert( ctx ) ;
303 err_cert = X509_STORE_CTX_get_current_cert( ctx ) ;
304 err = X509_STORE_CTX_get_error( ctx ) ;
305 X509_NAME_oneline( X509_get_subject_name( err_cert ), mybuf, 256 ) ;
306 BESDEBUG(
"ppt",
"FAILED for " << mybuf << endl ) ;
307 BESDEBUG(
"ppt",
" " << X509_verify_cert_error_string( err )
311 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
313 X509_NAME_oneline( X509_get_issuer_name( err_cert ), mybuf, 256 ) ;
314 BESDEBUG(
"ppt",
" issuer = " << mybuf << endl ) ;
318 case X509_V_ERR_CERT_NOT_YET_VALID:
319 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
321 BESDEBUG(
"ppt",
" not yet valid!" << endl ) ;
325 case X509_V_ERR_CERT_HAS_EXPIRED:
326 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
328 BESDEBUG(
"ppt",
" expired!" << endl ) ;
333 BESDEBUG(
"ppt",
" unknown!" << endl ) ;
352 << (
void *)
this <<
")" << endl ;
virtual void dump(ostream &strm) const
dumps information about this object
exception thrown if inernal error encountered
virtual void dump(ostream &strm) const
dumps information about this object
static ostream & LMarg(ostream &strm)
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
virtual void initConnection()
SSLServer(int portVal, const string &cert_file, const string &cert_auth_file, const string &key_file)