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 $

Generated on Thu Apr 30 15:53:50 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5