Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
networkcomm.cpp
Go to the documentation of this file.
1 #include "config.h"
2 #include "cmd/unit_generic.h"
4 #include "vsfilesystem.h"
5 #include "vs_globals.h"
6 #ifdef CRYPTO
7 #include <crypto++/filters.h>
8 #include <crypto++/hex.h>
9 #include <crypto++/randpool.h>
10 #include <crypto++/files.h>
11 
12 #include <crypto++/rsa.h>
13 #include <crypto++/des.h>
14 #include <crypto++/sha.h>
15 
16 using namespace CryptoPP;
17 #endif /* CRYPTO */
18 
19 //#ifdef NETCOMM
20 
21 #include <config.h>
22 
23 #include "universe_util.h"
25 #ifdef NETCOMM_WEBCAM
27 #endif /* NETCOMM_NOWEBCAM */
28 #ifdef NETCOMM_JVOIP
29 #include <jvoiplib/jvoipsession.h>
30 #include <jvoiplib/jvoiprtptransmission.h>
31 #endif /* NETCOMM_JVOIP */
32 
33 #define VOIP_PORT 5000
34 extern bool cleanexit;
35 
36 bool use_pa;
38 
40 #include <assert.h>
41 #include "xml_support.h"
42 
43 using namespace VSFileSystem;
44 
45 #ifdef NETCOMM_JVOIP
46 void CheckVOIPError( int val )
47 {
48  if (val >= 0)
49  return;
50  string error = JVOIPGetErrorString( val );
51  cerr<<"!!! JVOIP ERROR : "<<error<<endl;
52  cleanexit = true;
53  VSExit( 1 );
54 }
55 #endif /* NETCOMM_JVOIP */
56 #ifdef NETCOMM_PORTAUDIO
57 void CheckPAError( PaError err, const char *fun )
58 {
59  if (use_pa) {
60  if (err == paNoError)
61  return;
62  cerr<<"!!! PORTAUDIO ERROR in "<<fun<<": "<<Pa_GetErrorText( err )<<endl;
63  if (err == paHostError)
64  cerr<<"!!! PA HOST ERROR : "<<Pa_GetHostError()<<" - "<<Pa_GetErrorText( Pa_GetHostError() )<<endl;
65  cleanexit = true;
66  VSExit( 1 );
67  }
68 }
69 
70 void Pa_DisplayInfo( PaDeviceID id )
71 {
72  const PaDeviceInfo *info = Pa_GetDeviceInfo( id );
73 
74  cout<<"PORTAUDIO Device "<<id<<"---------------"<<endl;
75  cout<<"\tName : "<<info->name<<endl;
76  cout<<"\tStructure version : "<<info->structVersion<<endl;
77  cout<<"\tmaxInputChannels : "<<info->maxInputChannels<<endl;
78  cout<<"\tmaxOutputChannels : "<<info->maxOutputChannels<<endl;
79  cout<<"\tnativeSampleFormats : ";
80  switch (info->nativeSampleFormats)
81  {
82  case (paFloat32):
83  cout<<"paFloat32"<<endl;
84  break;
85  case (paInt16):
86  cout<<"paInt16"<<endl;
87  break;
88  case (paInt32):
89  cout<<"paInt32"<<endl;
90  break;
91  case (paInt24):
92  cout<<"paInt24"<<endl;
93  break;
94  case (paPackedInt24):
95  cout<<"paPackedInt24"<<endl;
96  break;
97  case (paInt8):
98  cout<<"paInt8"<<endl;
99  break;
100  case (paUInt8):
101  cout<<"paUInt8"<<endl;
102  break;
103  case (paCustomFormat):
104  cout<<"paCustomFormat"<<endl;
105  break;
106  }
107  cout<<"\tnumSampleRates : "<<info->numSampleRates<<endl;
108  for (int i = 0; i < info->numSampleRates; i++)
109  cout<<"\t\tRate "<<i<<" = "<<info->sampleRates[i];
110 }
111 
112 int Pa_RecordCallback( void *inputBuffer,
113  void *outputBuffer,
114  unsigned long framesPerBuffer,
115  PaTimestamp outTime,
116  void *userdata )
117 {
118  NetworkCommunication *netcomm = (NetworkCommunication*) userdata;
119  unsigned short *in = (unsigned short*) inputBuffer;
120  //Only act if PA CPU Load is low enough and if we have data in the input buffer
121  if (Pa_GetCPULoad( netcomm->instream ) < MAX_PA_CPU_LOAD && in) {
122  netcomm->audio_inlength = sizeof (unsigned short)*framesPerBuffer;
123  cerr<<"Input BUFFER SIZE = "<<netcomm->audio_inlength<<endl;
124  memset( netcomm->audio_inbuffer, 0, MAXBUFFER );
125  //Maybe put ushort by ushort in the buffer and prepare them for network (htons)
126  memcpy( netcomm->audio_inbuffer, in, netcomm->audio_inlength );
127  }
128  return 0;
129 }
130 
131 int Pa_PlayCallback( void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userdata )
132 {
133  NetworkCommunication *netcomm = (NetworkCommunication*) userdata;
134  unsigned short *out = (unsigned short*) outputBuffer;
135  //Copy the last received sound buffer if not yet played (would be NULL) and if PA CPU load is low enough
136  if (Pa_GetCPULoad( netcomm->outstream ) < MAX_PA_CPU_LOAD && netcomm->audio_outbuffer)
137  memcpy( out, netcomm->audio_outbuffer, sizeof (unsigned short)*framesPerBuffer );
138  return 0;
139 }
140 
141 #endif /* NETCOMM_PORTAUDIO */
142 
143 void NetworkCommunication::private_init()
144 {
145  this->active = false;
146  this->max_messages = 25;
147  this->method = ClientBroadcast;
148  use_pa = XMLSupport::parse_bool( vs_config->getVariable( "network", "use_portaudio", "false" ) );
149  use_secured = 0;
150 
151 #ifdef NETCOMM_JVOIP
152  this->session = NULL;
153  this->params = NULL;
154  this->rtpparams = NULL;
155 #endif /* NETCOMM_JVOIP */
156 
157 #ifdef NETCOMM_PORTAUDIO
158  this->indev = paNoDevice;
159  this->outdev = paNoDevice;
160  this->devinfo = NULL;
161 #endif /* NETCOMM_PORTAUDIO */
162 
163 #ifdef NETCOMM_WEBCAM
164  this->Webcam = NULL;
165 #endif
166 }
167 
169 {
170  private_init();
171 }
172 
173 NetworkCommunication::NetworkCommunication( float minfreq, float maxfreq, bool video, bool secured, string cryptomethod )
174 {
175  min_freq = minfreq;
176  max_freq = maxfreq;
177  private_init();
178 #ifdef NETCOMM_WEBCAM
179  if (video) {
180  //Init the webcam part
181  Webcam = new WebcamSupport();
182  if (Webcam->Init() == -1) {
183  delete Webcam;
184  this->Webcam = NULL;
185  cerr<<"!!! NO WEBCAM SUPPORT !!!"<<endl;
186  }
187  _downloader.reset( new VsnetDownload::Client::Manager( _sock_set ) );
188  _sock_set.addDownloadManager( _downloader );
189  _downloadServer.reset( new VsnetDownload::Server::Manager( _sock_set ) );
190  _sock_set.addDownloadManager( _downloadServer );
191  }
192 #endif /* NETCOMM_NOWEBCAM */
193 
194 #ifdef NETCOMM_PORTAUDIO
195  //Initialize PortAudio lib
196  if (use_pa)
197  CheckPAError( Pa_Initialize(), "Pa_Initialize" );
198  //Testing purpose : list devices and display info about them
199  if (use_pa) {
200  int nbdev = Pa_CountDevices();
201  for (int i = 0; i < nbdev; i++)
202  Pa_DisplayInfo( i );
203  }
204  //Get the default devices for input and output streams
205  if (use_pa) {
206  this->indev = Pa_GetDefaultInputDeviceID();
207  this->outdev = Pa_GetDefaultOutputDeviceID();
208  }
209  this->sample_rate = 11025;
210  this->audio_inlength = 0;
211 #endif /* NETCOMM_PORTAUDIO */
212 
213 #ifdef CRYPTO
214  crypto_method = cryptomethod;
215  pubKeyFilename = VSFileSystem::datadir+"vsnet_public_"+crypto_method+".key";
216  privKeyFilename = VSFileSystem::datadir+"vsnet_private_"+crypto_method+".key";
217  seed = vs_config->getVariable( "network", "encryption_seed", "I love VegaStrike" ); //;)
218  //Key length is only used when we need to generate a key
219  this->key_length = XMLSupport::parse_int( vs_config->getVariable( "network", "encryption_keylength", "40" ) );
220  bool create_keys = false;
221  VSFile f1, f2;
222  VSError err1 = f1.OpenReadOnly( pubKeyFilename, VSFileSystem::UnknownFile );
223  VSError err2 = f2.OpenReadOnly( privKeyFilename, VSFileSystem::UnknownFile );
224  if (err1 > Ok || err2 > Ok) {
225  //There is a file we cannot open so we create keys
226  create_keys = true;
227  } else {
228  //Read the keys in their buffers
229  this->pubkey = f1.ReadFull();
230  this->privkey = f2.ReadFull();
231  }
232  if (err1 <= Ok)
233  f1.Close();
234  if (err2 <= Ok)
235  f2.Close();
236  if (create_keys)
237  this->GenerateKey();
238 #endif
239 }
240 
242 {
243 #ifdef NETCOMM_WEBCAM
244  if (this->Webcam)
245  return 1;
246  return 0;
247 
248 #else
249  return 0;
250 #endif
251 }
252 
254 {
255 #ifdef NETCOMM_PORTAUDIO
256  return 1;
257 
258 #else
259  return 0;
260 #endif
261 }
262 
264 {
265  private_init();
266  assert( nb < 65536 );
267  this->max_messages = nb;
268 }
269 
271 {
272  this->commClients.push_back( clt );
273  //If the client has a webcam enabled and we don't have one selected yet
274  //FIND A FIX FOR THAT TEST
275  if (*(this->webcamClient) && clt->webcam) {
276  CltPtrIterator cltit = commClients.end();
277  assert( (*cltit) == clt );
278  this->webcamClient = cltit;
279  }
280 #ifdef NETCOMM_JVOIP
281  CheckVOIPError( this->session->AddDestination( ntohl( clt->cltadr.inaddr() ), VOIP_PORT ) );
282 #endif /* NETCOMM_JVOIP */
283 }
284 
286 {
287  this->commClients.remove( clt );
288 #ifdef NETCOMM_JVOIP
289  CheckVOIPError( this->session->AddDestination( ntohl( clt->cltadr.inaddr() ), VOIP_PORT ) );
290 #endif /* NETCOMM_JVOIP */
291 }
292 
293 /*
294  **************************************************************************************
295  **** Send text message ***
296  **** Broadcast string function param as a text message to the current frequency ***
297  **************************************************************************************
298  */
299 void NetworkCommunication::SendMessage( SOCKETALT &send_sock, ObjSerial serial, string message )
300 {
301  Packet p;
302  string encrypted;
303  //If max log size is reached we remove the oldest message
304  if (this->message_history.size() == this->max_messages)
305  this->message_history.pop_front();
306  this->message_history.push_back( message );
307  //Send the text message according to the chosen method
308  if (method == ServerUnicast) {
309  //SEND STRNIG PARAMETER TO SERVER SO THAT HE BROADCASTS IT TO CONCERNED PLAYERS
310 #ifdef CRYPTO
311  if (this->secured && use_secured) {
312  encrypted = this->EncryptBuffer( message.c_str(), message.length() );
313  p.send( CMD_TXTMESSAGE, serial, encrypted.c_str(), message.length(), SENDRELIABLE, NULL, send_sock,
314  __FILE__, PSEUDO__LINE__( 244 ) );
315  } else
316 #endif
317  {
318  p.send( CMD_SECMESSAGE, serial, message.c_str(), message.length(), SENDRELIABLE, NULL, send_sock,
319  __FILE__, PSEUDO__LINE__( 244 ) );
320  }
321  } else if (method == ClientBroadcast) {
322  //SEND STRING PARAMETER TO EACH PLAYER COMMUNICATING ON THAT FREQUENCY
323  CltPtrIterator it;
324  for (it = commClients.begin(); it != commClients.end(); it++) {
325 #ifdef CRYPTO
326  if (this->secured && use_secured) {
327  encrypted = this->EncryptBuffer( message.c_str(), message.length() );
328  p.send( CMD_TXTMESSAGE, serial, encrypted.c_str(), message.length(), SENDRELIABLE, NULL, (*it)->tcp_sock,
329  __FILE__, PSEUDO__LINE__( 244 ) );
330  } else
331 #endif
332  {
333  p.send( CMD_SECMESSAGE, serial, message.c_str(), message.length(), SENDRELIABLE, NULL, (*it)->tcp_sock,
334  __FILE__, PSEUDO__LINE__( 244 ) );
335  }
336  }
337  }
338 }
339 
340 /*
341  **************************************************************************************
342  **** Send sound sample in PortAudio mode ***
343  **** Send audio_inbuffer over the network according to the chosen method ***
344  **************************************************************************************
345  */
347 {
348 #ifdef USE_PORTAUDIO
349  string encrypted;
350  if (use_pa) {
351  Packet p;
352  if (method == ServerUnicast) {
353  //SEND INPUT AUDIO BUFFER TO SERVER SO THAT HE BROADCASTS IT TO CONCERNED PLAYERS
354  Packet p;
355  //We don't need that to be reliable in UDP mode
356 #ifdef CRYPTO
357  if (this->secured && use_secured) {
358  encrypted = this->EncryptBufer( this->audio_inbuffer, this->audio_inlength );
359  p.send( CMD_SOUNDSAMPLE, serial, encrypted.c_str(), encrypted.length(), SENDANDFORGET, NULL, sock,
360  __FILE__, PSEUDO__LINE__( 244 ) );
361  } else
362 #endif
363  {
364  p.send( CMD_SECSNDSAMPLE, serial, this->audio_inbuffer, this->audio_inlength, SENDANDFORGET, NULL, sock,
365  __FILE__, PSEUDO__LINE__( 244 ) );
366  }
367  } else if (method == ClientBroadcast) {
368  //SEND INPUT AUDIO BUFFER TO EACH PLAYER COMMUNICATING ON THAT FREQUENCY
369  CltPtrIterator it;
370  for (it = commClients.begin(); it != commClients.end(); it++) {
371  if ( (*it)->portaudio ) {
372 #ifdef CRYPTO
373  if (this->secured && use_secured) {
374  encrypted = this->EncryptBufer( this->audio_inbuffer, this->audio_inlength );
375  p.send( CMD_SOUNDSAMPLE, serial, encrypted.c_str(),
376  encrypted.length(), SENDANDFORGET, NULL, (*it)->sock,
377  __FILE__, PSEUDO__LINE__( 244 ) );
378  } else
379 #endif
380  {
381  p.send( CMD_SECSNDSAMPLE, serial, this->audio_inbuffer, this->audio_inlength, SENDANDFORGET, NULL,
382  (*it)->sock,
383  __FILE__, PSEUDO__LINE__(
384  244 ) );
385  }
386  }
387  }
388  }
389  memset( audio_inbuffer, 0, MAXBUFFER );
390  }
391 #endif /* USE_PORTAUDIO */
392 //Do not do anything when using JVoIP lib
393 }
394 
395 void NetworkCommunication::RecvSound( const char *sndbuffer, int length, bool encrypted )
396 {
397 #ifdef NETCOMM_PORTAUDIO
398  if (use_pa) {
399  string decrypted;
400  assert( length < MAXBUFFER );
401  memset( audio_outbuffer, 0, MAXBUFFER );
402 #ifdef CRYPTO
403  if (encrypted) {
404  decrypted = DecryptBuffer( sndbuffer, length );
405  memcpy( audio_outbuffer, decrypted.c_str(), decrypted.length() );
406  } else
407 #endif
408  memcpy( audio_outbuffer, sndbuffer, length );
409  }
410 #endif
411 }
412 
413 void NetworkCommunication::RecvMessage( string message, bool encrypted )
414 {
415  //If max log size is reached we remove the oldest message
416  if (this->message_history.size() == this->max_messages)
417  this->message_history.pop_front();
418  string decrypted;
419 #ifdef CRYPTO
420  if (encrypted) {
421  decrypted = DecryptBuffer( message.c_str(), message.length() );
422  message = decrypted;
423  }
424 #endif
425 
426  this->message_history.push_back( message );
427  //Display message
428  string color;
429  if (secured)
430  color = "#DD0000";
431  else
432  color = "#99CCFF";
433  UniverseUtil::IOmessage( 0, "game", "all", color+message+"#000000" );
434 }
435 
436 /*
437  **************************************************************************************
438  **** Send a webcam capture ***
439  **** Send jpeg_buffer over the network according to the chosen method ***
440  **************************************************************************************
441  */
442 /*
443  * void NetworkCommunication::SendImage( SOCKETALT & send_sock)
444  * {
445  * string jpeg_str( "");
446  * #ifdef NETCOMM_WEBCAM
447  * if( Webcam && Webcam->isReady())
448  * {
449  * //cerr<<"--- Trying to grab an image..."<<endl;
450  * //cerr<<"\t";
451  * jpeg_str = Webcam->CaptureImage();
452  * //cerr<<"--- grabbing finished"<<endl;
453  * }
454  * if( method==ServerUnicast)
455  * {
456  * // SEND GRABBED IMAGE TO SERVER SO THAT HE BROADCASTS IT TO CONCERNED PLAYERS
457  * }
458  * else if( method==ClientBroadcast)
459  * {
460  * // SEND GRABBED IMAGE TO EACH PLAYER COMMUNICATING ON THAT FREQUENCY
461  * }
462  * #endif
463  * }
464  */
465 
466 int NetworkCommunication::InitSession( float frequency )
467 {
468  //Init the VoIP session
469 #ifdef NETCOMM_JVOIP
470  this->session = new JVOIPSession;
471  this->session->SetSampleInterval( 100 );
472 
473  this->params = new JVOIPSessionParams;
474  this->rtpparams = new JVOIPRTPTransmissionParams;
475 
476  CheckVOIPError( this->session->Create( *(this->params) ) );
477 #endif /* NETCOMM_JVOIP */
478 
479 #ifdef NETCOMM_PORTAUDIO
480  if (use_pa) {
481  //Create the input stream with indev and 1 channel with paInt16 samples
482  CheckPAError( Pa_OpenStream( &this->instream,
483  this->indev, 1, paInt16, NULL,
484  paNoDevice, 0, paInt16, NULL,
485  this->sample_rate, 256, 0, paNoFlag,
486  Pa_RecordCallback, (void*) this ), "Pa_OpenStream(instream)" );
487 
488  //Create the output stream with outdev and 1 channel with paInt16 samples
489  CheckPAError( Pa_OpenStream( &this->outstream,
490  paNoDevice, 0, paInt16, NULL,
491  this->outdev, 1, paInt16, NULL,
492  this->sample_rate, 256, 0, paNoFlag,
493  Pa_PlayCallback, (void*) this ), "Pa_OpenStream(outstream)" );
494  if (this->instream)
495  CheckPAError( Pa_StartStream( this->instream ), "Pa_StartStream(instream)" );
496  if (this->outstream)
497  CheckPAError( Pa_StartStream( this->outstream ), "Pa_StartStream(outstream)" );
498  }
499 #endif /* NETCOMM_PORTAUDIO */
500 
501 #ifdef NETCOMM_WEBCAM
502  if (Webcam)
503  this->Webcam->StartCapture();
504 #endif /* NETCOMM_NOWEBCAM */
505 
506  this->active = true;
507  this->freq = frequency;
508  return 0;
509 }
510 
512 {
513  this->active = false;
514 #ifdef NETCOMM_PORTAUDIO
515  if (use_pa) {
516  CheckPAError( Pa_StopStream( this->instream ), "Pa_StopStream(instream)" );
517  CheckPAError( Pa_StopStream( this->outstream ), "Pa_StopStream(outstream)" );
518 
519  CheckPAError( Pa_CloseStream( this->instream ), "Pa_CloseStream(instream)" );
520  CheckPAError( Pa_CloseStream( this->outstream ), "Pa_CloseStream(outstream)" );
521  }
522 #endif
523 #ifdef NETCOMM_JVOIP
524  CheckVOIPError( this->session->Destroy() );
525  if (this->session)
526  delete this->session;
527  if (this->params)
528  delete this->params;
529  if (this->rtpparams)
530  delete this->rtpparams;
531 #endif /* NETCOMM_JVOIP */
532 #ifdef NETCOMM_WEBCAM
533  if (this->Webcam)
534  this->Webcam->EndCapture();
535  if (bufitem) {
536  delete bufitem;
537  bufitem == NULL;
538  }
539 #endif /* NETCOMM_NOWEBCAM */
540 
541  return 0;
542 }
543 
545 {
546 #ifdef NETCOMM_JVOIP
547  if (this->session)
548  delete this->session;
549  if (this->params)
550  delete this->params;
551  if (this->rtpparams)
552  delete this->rtpparams;
553 #endif /* NETCOMM_JVOIP */
554 #ifdef NETCOMM_PORTAUDIO
555  if (use_pa)
556  CheckPAError( Pa_Terminate(), "Pa_Terminate" );
557 #endif /* NETCOMM_PORTAUDIO */
558 #ifdef NETCOMM_WEBCAM
559  if (this->Webcam) {
560  this->Webcam->Shutdown();
561  delete this->Webcam;
562  this->Webcam = NULL;
563  }
564  if (bufitem)
565  delete bufitem;
566 #endif /* NETCOMM_NOWEBCAM */
567 #ifdef CRYPTO
568 #endif
569 }
570 
572 {
573 #ifdef NETCOMM_WEBCAM
574  if (Webcam != NULL)
575  return Webcam->jpeg_buffer;
576 #endif
577  return NULL; //We have no choice :-/
578 }
579 
581 {
582  char *wshot = NULL;
583 #ifdef NETCOMM_WEBCAM
584  if ( (*webcamClient) && bufitem ) {
585  if ( !bufitem->done() ) {
586  return NULL;
587  } else {
588  //Re add the buf to get another webcam shot
589  length = bufitem->getSize();
590  wshot = new char[bufitem->getSize()+1];
591  memcpy( wshot, bufitem->getBuffer().get(), bufitem->getSize() );
592  wshot[bufitem->getSize()] = 0;
593  _downloader->addItem( bufitem );
594  }
595  }
596 #endif
597  return wshot;
598 }
599 
601 {
602 #ifdef NETCOMM_WEBCAM
603  if (bufitem)
604  //Abort current transfer
605  //- remove from dloadmgr
606  //- delete it
607  bufitem = NULL;
608 #endif
609 }
610 
612 {
613 #ifdef NETCOMM_WEBCAM
614  //To select the first webcam to display and begin transfers
615  this->SwitchWebcam();
616 #endif
617 }
618 
620 {
621 #ifdef NETCOMM_WEBCAM
622  bool found = false;
623  CltPtrIterator it;
624  if (bufitem)
625  delete bufitem;
626  //Go through listClients from current client to the end in order to find the next webcam client
627  if ( (*this->webcamClient) )
628  it = ++webcamClient;
629  else
630  it = commClients.begin();
631  for (; it != commClients.end() && !found; it++)
632  if ( (*it)->webcam )
633  found = true;
634  //If a client with webcam support was not found before the end we go through listClients from te beginning
635  if (!found) {
636  for (it = commClients.begin(), found = false; it != webcamClient && !found; it++)
637  if ( (*it)->webcam )
638  found = true;
639  //If we found another client supporting webcam
640  if (found)
641  webcamClient = it;
642  }
643  if (found)
644  //Should init transfer and buf with right values
645  //1. Create a socket to the interested client
646  //2. Init the bufitem
647  //bufitem = new VsnetDownload::Client::Buffer(...);
648  _downloader->addItem( bufitem );
649 #endif
650 }
651 
653 {
654 #ifdef CRYPTO
655  if (secured)
656  secured = 0;
657  else if (use_secured && crypt_key[0] != 0)
658  secured = 1;
659 #else
660  //If compiled without crypto++ support secured comms are not available
661  secured = 0;
662 #endif
663 }
664 
665 void NetworkCommunication::GenerateKey()
666 {
667 #ifdef CRYPTO
668  if (crypto_method == "rsa") {
669  use_secured = true;
670  RandomPool randPool;
671  randPool.Put( (byte*) this->seed.c_str(), this->seed.length() );
672 
673  RSAES_OAEP_SHA_Decryptor priv( randPool, this->key_length );
674  HexEncoder privFile( new FileSink( privKeyFilename.c_str() ) );
675  HexEncoder privstr( new StringSink( privkey ) );
676  priv.DEREncode( privFile );
677  privFile.MessageEnd();
678 
679  RSAES_OAEP_SHA_Encryptor pub( priv );
680  HexEncoder pubFile( new FileSink( pubKeyFilename.c_str() ) );
681  HexEncoder pubstr( new StringSink( pubkey ) );
682  pub.DEREncode( pubFile );
683  pubFile.MessageEnd();
684  } else if (crypto_method == "3des") {
685  use_secured = true;
686  /* initialize a DES-EDE3 encryption filter with a 192 bit (24 bytes) key */
687  static DES_EDE3_Encryption des_encryptor( (byte*) privkey.c_str(), 24 );
688  static DES_EDE3_Decryption des_decryptor( (byte*) privkey.c_str(), 24 );
689  } else {
690  use_secured = false;
691  }
692 #endif
693 }
694 
695 string NetworkCommunication::EncryptBuffer( const char *buffer, unsigned int length )
696 {
697  string result;
698 #ifdef CRYPTO
699  if (crypto_method == "rsa") {
700  StringSource pubstr( pubkey, true, new HexDecoder );
701  RSAES_OAEP_SHA_Encryptor pub( pubstr );
702 
703  randPool.Put( (byte*) seed.c_str(), seed.length() );
704 
705  StringSource( buffer, true, new PK_EncryptorFilter( randPool, pub, new HexEncoder( new StringSink( result ) ) ) );
706  } else if (crypto_method == "3des") {
707  /* calculate how many blocks (each block is 8 bytes) the input consists of, add
708  * padding if needed */
709  /*
710  * int nBlocks = length / 8;
711  * if (length % 8 != 0)
712  * nBlocks ++;
713  * // allocate the output buffer
714  * byte* pResult = new byte[nBlocks * 8];
715  * byte plainByte [8];
716  * // encrypt the blocks one by one
717  * for (int block_num = 0; block_num < nBlocks; block_num ++)
718  * {
719  * // build the 8 byte block plain text, add padding if needed
720  * for (int i = 0 ; i < 8; i++)
721  * {
722  * // this is a full block
723  * if (block_num * 8 + i < length)
724  * {
725  * plainByte[i] = buffer[block_num * 8 + i];
726  * }
727  * // this is the last block that needs padding
728  * else
729  * {
730  * plainByte[i] = 0x00; // pad with a random byte
731  * }
732  * }
733  * // encrypt the 8 byte block and store in output buffer
734  * if (encrypting_mode)
735  * des_encryptor.ProcessBlock(plainByte, pResult + block_num * 8);
736  * else
737  * des_decryptor.ProcessBlock(plainByte, pResult + block_num * 8);
738  * }
739  * *output_length= nBlocks * 8;
740  * return pResult;
741  */
742  } else {}
743 #endif /* CRYPTO */
744  return result;
745 }
746 
747 string NetworkCommunication::DecryptBuffer( const char *buffer, unsigned int length )
748 {
749  string result;
750 #ifdef CRYPTO
751  if (crypto_method == "rsa") {
752  StringSource privstr( privkey, true, new HexDecoder );
753  RSAES_OAEP_SHA_Decryptor priv( privstr );
754 
755 #if CRYPTO == 50
756  StringSource( buffer, true, new HexDecoder( new PK_DecryptorFilter( priv, new StringSink( result ) ) ) );
757 #else
758  StringSource( buffer, true, new HexDecoder( new PK_DecryptorFilter( randPool, priv, new StringSink( result ) ) ) );
759 #endif
760  } else if (crypto_method == "3des") {} else {}
761 #endif /* CRYPTO */
762  return result;
763 }
764