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 "PPTException.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 PPTException( err, __FILE__, __LINE__ ) ;
00067 }
00068 if( !listener )
00069 {
00070 string err( "Null listener passed to PPTServer" ) ;
00071 throw PPTException( 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 PPTException( 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 PPTException( "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 PPTException( "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 PPTException( "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 PPTException( 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 return -1 ;
00171 }
00172
00173 string status( inBuff, bytesRead ) ;
00174 delete [] inBuff ;
00175 if( status != PPTProtocol::PPTCLIENT_TESTING_CONNECTION )
00176 {
00177
00178
00179
00180
00181 string err( "PPT Can not negotiate, " ) ;
00182 err += " client started the connection with " + status ;
00183 BESDEBUG( err )
00184
00185 _mySock->send( err, 0, err.length() ) ;
00186 _mySock->close() ;
00187 return -1 ;
00188 }
00189
00190 if( !_secure )
00191 {
00192 int len = PPTProtocol::PPTSERVER_CONNECTION_OK.length() ;
00193 _mySock->send( PPTProtocol::PPTSERVER_CONNECTION_OK, 0, len ) ;
00194 }
00195 else
00196 {
00197 authenticateClient() ;
00198 }
00199
00200 return 0 ;
00201 }
00202
00203 void
00204 PPTServer::authenticateClient()
00205 {
00206 #ifdef HAVE_OPENSSL
00207 BESDEBUG( "requiring secure connection: port = " << _securePort << endl )
00208
00209 int len = PPTProtocol::PPTSERVER_AUTHENTICATE.length() ;
00210 _mySock->send( PPTProtocol::PPTSERVER_AUTHENTICATE, 0, len ) ;
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 PPTException( err, __FILE__, __LINE__ ) ;
00222 }
00223
00224
00225 ostringstream portResponse ;
00226 portResponse << _securePort << PPTProtocol::PPT_COMPLETE_DATA_TRANSMITION ;
00227 len = portResponse.str().length() ;
00228 _mySock->send( portResponse.str(), 0, len ) ;
00229
00230
00231 SSLServer server( _securePort, _cfile, _kfile ) ;
00232 server.initConnection() ;
00233 server.closeConnection() ;
00234
00235
00236
00237 #else
00238 throw PPTException( "Authentication requrested for this server but OpenSSL is not built into the server", __FILE__, __LINE__ ) ;
00239 #endif
00240 }
00241
00248 void
00249 PPTServer::dump( ostream &strm ) const
00250 {
00251 strm << BESIndent::LMarg << "PPTServer::dump - ("
00252 << (void *)this << ")" << endl ;
00253 BESIndent::Indent() ;
00254 if( _handler )
00255 {
00256 strm << BESIndent::LMarg << "server handler:" << endl ;
00257 BESIndent::Indent() ;
00258 _handler->dump( strm ) ;
00259 BESIndent::UnIndent() ;
00260 }
00261 else
00262 {
00263 strm << BESIndent::LMarg << "server handler: null" << endl ;
00264 }
00265 ServerHandler * _handler ;
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