# SecureTCPSocket.cc

Go to the documentation of this file.

    00001 // ----------------------------------------------------------------------------
    00002 // CERTI - HLA RunTime Infrastructure
    00003 // Copyright (C) 2002-2005  ONERA
    00004 //
    00005 // This program is free software ; you can redistribute it and/or
    00006 // modify it under the terms of the GNU Lesser General Public License
    00007 // as published by the Free Software Foundation ; either version 2 of
    00008 // the License, or (at your option) any later version.
    00009 //
    00010 // This program is distributed in the hope that it will be useful, but
    00011 // WITHOUT ANY WARRANTY ; without even the implied warranty of
    00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    00013 // Lesser General Public License for more details.
    00014 //
    00015 // You should have received a copy of the GNU Lesser General Public
    00016 // License along with this program ; if not, write to the Free Software
    00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    00018 // USA
    00019 //
    00020 // $Id: SecureTCPSocket.cc,v 3.11 2008/10/13 11:27:51 gotthardp Exp $
    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 //#include <pwd.h>
    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     // If the GSSAPI session is not Initialized, start the HandShake.
    00078     if (!SessionInitialized)
    00079         sendInitialToken();
    00080
    00081     // Send Message
    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     // Wait for an incoming message(GSS Handler will decrypt it).
    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     // Check available size
    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     // Copy Message to Buffer
    00126     memcpy((char *) Buffer,
    00127            (char *) IncomingBuffer.value + CurrentOffset,
    00128            Size);
    00129
    00130     // Change current offset
    00131     CurrentOffset += Size ;
    00132
    00133     // Discard completely read buffers
    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     // If the GSSAPI session is not Initialized, start the HandShake.
    00169
    00170     if (!SessionInitialized)
    00171         receiveInitialToken();
    00172
    00173     getMessagePart(Buffer, Size);
    00174
    00175 #else
    00176
    00177     // Non secure communications
    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     // Initialize Local Principal Name with Server Default Name
    00192
    00193     GSSHandler->setLocalName(HLA_SERVER_PRINCIPAL_NAME);
    00194
    00195     // Accept Initial Handshake(started by client)
    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     // Initialize Local Principal Name with Login Name
    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     // Initialize Remote Principal Name with Constant
    00224
    00225     GSSHandler->setRemoteName(HLA_SERVER_PRINCIPAL_NAME);
    00226
    00227     // Start Initial Handshake
    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 // $Id: SecureTCPSocket.cc,v 3.11 2008/10/13 11:27:51 gotthardp Exp $