00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "SecureTCPSocket.hh"
00025
00026 #include "PrettyDebug.hh"
00027
00028 #include <sys/types.h>
00029 #include <unistd.h>
00030 #include <cstdlib>
00031
00032
00033 namespace certi {
00034
00035 static pdCDebug D("STCPSOCK", __FILE__);
00036
00037
00038 SecureTCPSocket::SecureTCPSocket()
00039 : SocketTCP()
00040 {
00041 #ifdef WITH_GSSAPI
00042 SessionInitialized = false ;
00043 DecryptedMessageReady = false ;
00044
00045 GSSHandler = new GSSAPIHandler();
00046
00047 IncomingBuffer.length = 0 ;
00048 IncomingBuffer.value = NULL ;
00049
00050 CurrentOffset = 0 ;
00051 #endif // WITH_GSSAPI
00052 PeerName = NULL ;
00053 }
00054
00055
00056 SecureTCPSocket::~SecureTCPSocket()
00057 {
00058 if (PeerName != NULL) {
00059 free(PeerName);
00060 PeerName = NULL ;
00061 }
00062
00063 #ifdef WITH_GSSAPI
00064 delete GSSHandler ;
00065 GSSHandler = NULL ;
00066 #endif // WITH_GSSAPI
00067 }
00068
00069
00070 void
00071 SecureTCPSocket::send(const unsigned char *buffer, size_t size)
00072 throw (NetworkError, NetworkSignal)
00073 {
00074 D.Out(pdTrace, "SSocket: Sending.");
00075
00076 #ifdef HLA_USES_GSSAPI
00077
00078 if (!SessionInitialized)
00079 sendInitialToken();
00080
00081
00082 sendMessage(buffer, size);
00083 #else
00084 SocketTCP::send(buffer, size);
00085 #endif
00086 }
00087
00088 #ifdef WITH_GSSAPI
00089
00090 void
00091 SecureTCPSocket::getMessage()
00092 {
00093 if (DecryptedMessageReady) {
00094 D.Out(pdExcept, "Decrypted message already exists.");
00095 return ;
00096 }
00097
00098
00099
00100 IncomingBuffer.length = 0 ;
00101 IncomingBuffer.value = NULL ;
00102
00103 CurrentOffset = 0 ;
00104
00105 GSSHandler->getMessage((SocketTCP *)this, &IncomingBuffer);
00106
00107 DecryptedMessageReady = true ;
00108 }
00109 #endif // WITH_GSSAPI
00110
00111 #ifdef WITH_GSSAPI
00112
00113 void
00114 SecureTCPSocket::getMessagePart(void *Buffer, unsigned long Size)
00115 {
00116 if (!DecryptedMessageReady)
00117 getMessage();
00118
00119
00120 if (Size > IncomingBuffer.length - CurrentOffset) {
00121 D.Out(pdExcept, "Size too big for data in buffer.");
00122 throw NetworkError("Not enough data in STCPSocket buffer.");
00123 }
00124
00125
00126 memcpy((char *) Buffer,
00127 (char *) IncomingBuffer.value + CurrentOffset,
00128 Size);
00129
00130
00131 CurrentOffset += Size ;
00132
00133
00134 if (CurrentOffset >= IncomingBuffer.length) {
00135 GSSHandler->releaseBuffer(&IncomingBuffer);
00136 CurrentOffset = 0 ;
00137 DecryptedMessageReady = false ;
00138 }
00139 }
00140 #endif // WITH_GSSAPI
00141
00142
00143 const char *
00144 SecureTCPSocket::getPeerName()
00145 {
00146 if (PeerName != NULL)
00147 return PeerName ;
00148 #ifdef WITH_GSSAPI
00149 PeerName = GSSHandler->getRemoteName();
00150 #endif // WITH_GSSAPI
00151 if (PeerName == NULL)
00152 throw RTIinternalError("Could not retrieve Peer's principal name.");
00153 #ifdef WITH_GSSAPI
00154 return PeerName ;
00155 #endif // WITH_GSSAPI
00156 throw RTIinternalError("No peer's principal name.");
00157 }
00158
00159
00160 void
00161 SecureTCPSocket::receive(void *Buffer, unsigned long Size)
00162 throw (NetworkError, NetworkSignal)
00163 {
00164 D.Out(pdTrace, "SSocket: Receiving.");
00165
00166 #ifdef HLA_USES_GSSAPI
00167
00168
00169
00170 if (!SessionInitialized)
00171 receiveInitialToken();
00172
00173 getMessagePart(Buffer, Size);
00174
00175 #else
00176
00177
00178 SocketTCP::receive(Buffer, Size);
00179
00180 #endif // HLA_USES_GSSAPI
00181
00182 }
00183
00184 #ifdef WITH_GSSAPI
00185
00186 void
00187 SecureTCPSocket::receiveInitialToken()
00188 {
00189 D.Out(pdInit, "Receiving Initial Token.");
00190
00191
00192
00193 GSSHandler->setLocalName(HLA_SERVER_PRINCIPAL_NAME);
00194
00195
00196
00197 GSSHandler->acceptSecContext((SocketTCP *) this);
00198
00199 D.Out(pdInit, "GSSAPI session initialized.");
00200
00201 SessionInitialized = true ;
00202 }
00203
00204
00205 void
00206 SecureTCPSocket::sendInitialToken()
00207 {
00208 uid_t CurrentUID ;
00209 struct passwd *PasswdEntry ;
00210
00211 D.Out(pdInit, "Sending Initial Token.");
00212
00213
00214
00215 CurrentUID = getuid();
00216 PasswdEntry = getpwuid(CurrentUID);
00217
00218 if (PasswdEntry == NULL)
00219 throw NetworkError("S/TCP: Unable to get Local Principal Name.");
00220
00221 GSSHandler->setLocalName(PasswdEntry->pw_name);
00222
00223
00224
00225 GSSHandler->setRemoteName(HLA_SERVER_PRINCIPAL_NAME);
00226
00227
00228
00229 GSSHandler->initSecContext((SocketTCP *) this);
00230
00231 D.Out(pdInit, "GSSAPI session initialized.");
00232
00233 SessionInitialized = true ;
00234 }
00235
00236
00237 void
00238 SecureTCPSocket::sendMessage(void *Buffer, unsigned long Size)
00239 {
00240 gss_buffer_desc OutputToken ;
00241
00242 OutputToken.value = Buffer ;
00243 OutputToken.length = Size ;
00244
00245 GSSHandler->sendMessage((SocketTCP *)this, &OutputToken);
00246 }
00247 #endif // WITH_GSSAPI
00248
00249 }
00250
00251