00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <string>
00034 #include <sstream>
00035
00036 using std::string ;
00037 using std::ostringstream ;
00038
00039 #include "PPTServer.h"
00040 #include "BESInternalError.h"
00041 #include "PPTProtocol.h"
00042 #include "SocketListener.h"
00043 #include "ServerHandler.h"
00044 #include "Socket.h"
00045 #include "TheBESKeys.h"
00046 #include "BESDebug.h"
00047
00048 #include "config.h"
00049 #ifdef HAVE_OPENSSL
00050 #include "SSLServer.h"
00051 #endif
00052
00053 #define PPT_SERVER_DEFAULT_TIMEOUT 1
00054
00055 PPTServer::PPTServer( ServerHandler *handler,
00056 SocketListener *listener,
00057 bool isSecure )
00058 : PPTConnection( PPT_SERVER_DEFAULT_TIMEOUT),
00059 _handler( handler ),
00060 _listener( listener ),
00061 _secure( isSecure )
00062 {
00063 if( !handler )
00064 {
00065 string err( "Null handler passed to PPTServer" ) ;
00066 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00067 }
00068 if( !listener )
00069 {
00070 string err( "Null listener passed to PPTServer" ) ;
00071 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00072 }
00073 #ifndef HAVE_OPENSSL
00074 if( _secure )
00075 {
00076 string err("Server requested to be secure but OpenSSL is not built in");
00077 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00078 }
00079 #endif
00080
00081
00082 if( _secure )
00083 {
00084 get_secure_files() ;
00085 }
00086 }
00087
00088 PPTServer::~PPTServer()
00089 {
00090 }
00091
00092 void
00093 PPTServer::get_secure_files()
00094 {
00095 bool found = false ;
00096 _cfile = TheBESKeys::TheKeys()->get_key( "BES.ServerCertFile", found ) ;
00097 if( !found || _cfile.empty() )
00098 {
00099 throw BESInternalError( "Unable to determine server certificate file.",
00100 __FILE__, __LINE__ ) ;
00101 }
00102
00103 _kfile = TheBESKeys::TheKeys()->get_key( "BES.ServerKeyFile", found ) ;
00104 if( !found || _kfile.empty() )
00105 {
00106 throw BESInternalError( "Unable to determine server key file.",
00107 __FILE__, __LINE__ ) ;
00108 }
00109
00110 string portstr = TheBESKeys::TheKeys()->get_key( "BES.ServerSecurePort",
00111 found ) ;
00112 if( !found || portstr.empty() )
00113 {
00114 throw BESInternalError( "Unable to determine secure connection port.",
00115 __FILE__, __LINE__ ) ;
00116 }
00117 _securePort = atoi( portstr.c_str() ) ;
00118 if( !_securePort )
00119 {
00120 string err = (string)"Unable to determine secure connection port "
00121 + "from string " + portstr ;
00122 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00123 }
00124 }
00125
00126
00132 void
00133 PPTServer::initConnection()
00134 {
00135 for(;;)
00136 {
00137 _mySock = _listener->accept() ;
00138 if( _mySock )
00139 {
00140
00141 if( welcomeClient( ) != -1 )
00142 {
00143
00144 _handler->handle( this ) ;
00145 }
00146 }
00147 }
00148 }
00149
00150 void
00151 PPTServer::closeConnection()
00152 {
00153 if( _mySock ) _mySock->close() ;
00154 }
00155
00156 int
00157 PPTServer::welcomeClient()
00158 {
00159 char *inBuff = new char[PPT_PROTOCOL_BUFFER_SIZE] ;
00160
00161
00162
00163
00164 int bytesRead = readBufferNonBlocking( inBuff ) ;
00165
00166
00167 if( bytesRead == -1 )
00168 {
00169 _mySock->close() ;
00170 delete [] inBuff ;
00171 return -1 ;
00172 }
00173
00174 string status( inBuff, bytesRead ) ;
00175 delete [] inBuff ;
00176
00177 if( status != PPTProtocol::PPTCLIENT_TESTING_CONNECTION )
00178 {
00179
00180
00181
00182
00183 string err( "PPT Can not negotiate, " ) ;
00184 err += " client started the connection with " + status ;
00185 BESDEBUG( "ppt", err )
00186
00187 send( err ) ;
00188 _mySock->close() ;
00189 return -1 ;
00190 }
00191
00192 if( !_secure )
00193 {
00194 send( PPTProtocol::PPTSERVER_CONNECTION_OK ) ;
00195 }
00196 else
00197 {
00198 authenticateClient() ;
00199 }
00200
00201 return 0 ;
00202 }
00203
00204 void
00205 PPTServer::authenticateClient()
00206 {
00207 #ifdef HAVE_OPENSSL
00208 BESDEBUG( "ppt", "requiring secure connection: port = " << _securePort << endl )
00209
00210 send( PPTProtocol::PPTSERVER_AUTHENTICATE ) ;
00211
00212
00213 char *inBuff = new char[PPT_PROTOCOL_BUFFER_SIZE] ;
00214 int bytesRead = _mySock->receive( inBuff, PPT_PROTOCOL_BUFFER_SIZE ) ;
00215 string portRequest( inBuff, bytesRead ) ;
00216 delete [] inBuff ;
00217 if( portRequest != PPTProtocol::PPTCLIENT_REQUEST_AUTHPORT )
00218 {
00219 string err( "Secure connection ... expecting request for port" ) ;
00220 err += " client requested " + portRequest ;
00221 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00222 }
00223
00224
00225 ostringstream portResponse ;
00226 portResponse << _securePort << PPTProtocol::PPT_COMPLETE_DATA_TRANSMITION ;
00227 send( portResponse.str() ) ;
00228
00229
00230 SSLServer server( _securePort, _cfile, _kfile ) ;
00231 server.initConnection() ;
00232 server.closeConnection() ;
00233
00234
00235
00236 #else
00237 string err = "Authentication requested for this server "
00238 + "but OpenSSL is not built into the server" ;
00239 throw BESInternalError( err, __FILE__, __LINE__ ) ;
00240 #endif
00241 }
00242
00249 void
00250 PPTServer::dump( ostream &strm ) const
00251 {
00252 strm << BESIndent::LMarg << "PPTServer::dump - ("
00253 << (void *)this << ")" << endl ;
00254 BESIndent::Indent() ;
00255 if( _handler )
00256 {
00257 strm << BESIndent::LMarg << "server handler:" << endl ;
00258 BESIndent::Indent() ;
00259 _handler->dump( strm ) ;
00260 BESIndent::UnIndent() ;
00261 }
00262 else
00263 {
00264 strm << BESIndent::LMarg << "server handler: null" << endl ;
00265 }
00266 if( _listener )
00267 {
00268 strm << BESIndent::LMarg << "listener:" << endl ;
00269 BESIndent::Indent() ;
00270 _listener->dump( strm ) ;
00271 BESIndent::UnIndent() ;
00272 }
00273 else
00274 {
00275 strm << BESIndent::LMarg << "listener: null" << endl ;
00276 }
00277 strm << BESIndent::LMarg << "secure? " << _secure << endl ;
00278 PPTConnection::dump( strm ) ;
00279 BESIndent::UnIndent() ;
00280 }
00281