/home/dko/projects/mobilec/trunk/src/security/asm.c

Go to the documentation of this file.
00001 #include "../include/mc_platform.h"
00002 #include "../include/message.h"
00003 #include "asm.h"
00004 #include "asm_message_composer.h"
00005 #include "config.h"
00006 #include "mc_dh.h"
00007 
00008 #ifdef MC_SECURITY
00009 
00010 AP_QUEUE_STD_DEFN_TEMPLATE
00011 (
00012  asm_queue,
00013  asm_node
00014  )
00015 
00016 AP_QUEUE_SEARCH_TEMPLATE
00017 (
00018  asm_queue,
00019  SearchAddr,
00020  asm_node,
00021  struct sockaddr_in*,
00022  (
00023   (key->sin_addr.s_addr == node->remote_addr->sin_addr.s_addr) &&
00024   (key->sin_port == node->remote_addr->sin_port)
00025  )
00026  )
00027 
00028 AP_QUEUE_REMOVE_TEMPLATE
00029 (
00030  asm_queue,
00031  RemoveAddr,
00032  asm_node,
00033  struct sockaddr_in*,
00034  (
00035   (key->sin_addr.s_addr == node->remote_addr->sin_addr.s_addr) &&
00036   (key->sin_port == node->remote_addr->sin_port)
00037  )
00038  )
00039 
00040 int
00041 asm_Destroy(mc_asm_p mc_asm)
00042 {
00043   if (mc_asm == NULL) return 0;
00044   message_queue_Destroy(mc_asm->lost_message_queue);
00045   asm_node_Destroy(mc_asm->home_encryption_info);
00046   free(mc_asm);
00047   return 0;
00048 }
00049 
00050 mc_asm_p
00051 asm_Initialize(mc_platform_p mc_platform)
00052 {
00053   mc_asm_p mc_asm;
00054   mc_asm = (mc_asm_p)malloc(sizeof(mc_asm_t));
00055   CHECK_NULL(mc_asm, exit(0););
00056 
00057   mc_asm->waiting = 0;
00058   mc_asm->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00059   MUTEX_INIT(mc_asm->waiting_lock);
00060   mc_asm->waiting_cond = (COND_T*)malloc(sizeof(COND_T));
00061   COND_INIT(mc_ams->waiting_cond);
00062 
00063   mc_asm->mc_platform = mc_platform;
00064   mc_asm->home_encryption_info = (asm_node_p)malloc(sizeof(asm_node_t));
00065   
00066   /* Initialize the home encryption node */
00067   mc_asm->home_encryption_info->id = 0;
00068   mc_asm->home_encryption_info->type = DH;
00069   mc_asm->home_encryption_info->data.dh_data = dh_data_Initialize();
00070   
00071   mc_asm->lost_message_queue = message_queue_Initialize();
00072   return mc_asm;
00073 }
00074 
00075   void
00076 asm_RequestInitFromAddr(mc_platform_p mc_platform, char* addr)
00077 {
00078   message_p message = message_Initialize();
00079 
00080   message->to_address = (char*)malloc
00081     (
00082      sizeof(char) * 
00083      (strlen(addr)+1)
00084     );
00085   CHECK_NULL(message->to_address, exit(0); );
00086 
00087   strcpy(message->to_address, addr);
00088 
00089   message->message_type = REQUEST_ENCRYPTION_INITIALIZE;
00090 
00091   message->xml_root = message_xml_compose__RequestEncryptionInit(mc_platform);
00092 
00093   message->message_body = mxmlSaveAllocString
00094     (
00095      message->xml_root,
00096      MXML_NO_CALLBACK
00097     );
00098 
00099   message_queue_Add(mc_platform->message_queue, message);
00100 }
00101 
00102 int
00103 asm_SendEncryptionData(
00104     mc_asm_p security_manager,
00105     const char* address
00106     )
00107 {
00108   message_p message = message_Initialize();
00109 
00110   message->to_address = (char*)malloc
00111     (
00112      sizeof(char) * (strlen(address)+1)
00113     );
00114   CHECK_NULL(message->to_address, exit(0););
00115   strcpy(message->to_address, address);
00116 
00117 /*  if(_message->addr != NULL) {
00118     message->addr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
00119     *(message->addr) = *(_message->addr);
00120   } */
00121 
00122   message->message_type = ENCRYPTION_INITIALIZE;
00123 
00124   message->xml_root = 
00125     message_xml_compose__EncryptionInitialize
00126     (
00127      security_manager
00128     );
00129 
00130   message->message_body = mxmlSaveAllocString
00131     (
00132      message->xml_root,
00133      MXML_NO_CALLBACK
00134     );
00135 
00136   message_queue_Add
00137     (
00138      security_manager->mc_platform->message_queue,
00139      message
00140     );
00141   return MC_SUCCESS;
00142 }
00143 
00144   void
00145 asm_Start(mc_platform_p mc_platform)
00146 {
00147   mc_asm_p security_manager = mc_platform->security_manager;
00148 #ifndef _WIN32
00149   pthread_attr_t attr;
00150   pthread_attr_init(&attr);
00151   if(mc_platform->stack_size[MC_THREAD_ASM] != -1) {
00152     pthread_attr_setstacksize
00153       (
00154        &attr,
00155        mc_platform->stack_size[MC_THREAD_ASM]
00156       );
00157   }
00158 #else
00159   int stack_size;
00160   if (mc_platform->stack_size[MC_THREAD_ASM] < 1) {
00161     /* In windows, 0 is default, not min */
00162     stack_size = mc_platform->stack_size[MC_THREAD_ASM]+1; 
00163   } else {
00164     stack_size = mc_platform->stack_size[MC_THREAD_ASM];
00165   }
00166 #endif
00167   THREAD_CREATE
00168     (
00169      &security_manager->thread,
00170      asm_Thread,
00171      mc_platform
00172     );
00173 }
00174 
00175 #ifndef _WIN32
00176   void*
00177 asm_Thread(void* arg)
00178 #else
00179   DWORD WINAPI
00180 asm_Thread(LPVOID arg)
00181 #endif
00182 {
00183   /* This thread will encrypt any unencrypted messages added to its
00184    * queue and decrypt encrypted messages. */
00185   mc_platform_p mc_platform = (mc_platform_p)arg;
00186   message_p message;
00187   asm_node_p asm_node;
00188   int old_asm_queue_size;
00189   int i;
00190 
00191   MUTEX_LOCK(mc_platform->asm_queue->lock);
00192   old_asm_queue_size = mc_platform->asm_queue->size;
00193   MUTEX_UNLOCK(mc_platform->asm_queue->lock);
00194   while(1) 
00195   {
00196     MUTEX_LOCK(mc_platform->asm_message_queue->lock);
00197     while
00198       (
00199        (mc_platform->asm_message_queue->size == 0) &&
00200        (mc_platform->asm_queue->size == old_asm_queue_size)
00201       ) 
00202       {
00203         /* Set waiting flag */
00204         MUTEX_LOCK(mc_platform->security_manager->waiting_lock);
00205         mc_platform->security_manager->waiting = 1;
00206         COND_BROADCAST(mc_platform->security_manager->waiting_cond);
00207         MUTEX_UNLOCK(mc_platform->security_manager->waiting_lock);
00208         /* Wait for activity */
00209         COND_WAIT
00210           (
00211            mc_platform->asm_message_queue->cond,
00212            mc_platform->asm_message_queue->lock
00213           );
00214       }
00215     MUTEX_UNLOCK(mc_platform->asm_message_queue->lock);
00216     MUTEX_LOCK(mc_platform->asm_queue->lock);
00217     while (old_asm_queue_size != mc_platform->asm_queue->size)
00218     {
00219       old_asm_queue_size = mc_platform->asm_queue->size;
00220       MUTEX_UNLOCK(mc_platform->asm_queue->lock);
00221       /* Go through each of the lost messages and see if they can be
00222        * decrypted/encrypted. */
00223       for
00224         (
00225          i = 0;
00226          i < mc_platform->security_manager->lost_message_queue->size;
00227          i++
00228         )
00229         {
00230           message = message_queue_Pop
00231             (
00232              mc_platform->security_manager->lost_message_queue
00233             );
00234           if (message == NULL) {
00235             message_queue_Add
00236               (
00237                mc_platform->security_manager->lost_message_queue,
00238                message
00239               );
00240             break;
00241           }
00242           if (message->addr == NULL) {
00243             message_queue_Add
00244               (
00245                mc_platform->security_manager->lost_message_queue,
00246                message
00247               );
00248             break;
00249           }
00250           if 
00251             (
00252              asm_queue_SearchAddr(mc_platform->asm_queue, message->addr)
00253             ) 
00254             {
00255               message_queue_Add
00256                 (
00257                  mc_platform->message_queue,
00258                  message
00259                 );
00260             } else {
00261             message_queue_Add
00262               (
00263                mc_platform->security_manager->lost_message_queue,
00264                message
00265               );
00266           }
00267         }
00268     }
00269     MUTEX_UNLOCK(mc_platform->asm_queue->lock);
00270     message = message_queue_Pop(mc_platform->asm_message_queue);
00271     if (message != NULL) 
00272     {
00273       asm_node = asm_queue_SearchAddr
00274         (
00275          mc_platform->asm_queue,
00276          message->addr
00277         );
00278       switch(message->message_type)
00279       {
00280         case ENCRYPTED_DATA:
00281           if (asm_node == NULL) {
00282             /* The encryption session was never initialized with this host,
00283              * according to this agency. Let us initialize it now. */
00284             asm_RequestInitFromAddr
00285               (
00286                mc_platform,
00287                message->from_address
00288               );
00289             message_queue_Add
00290               (
00291                mc_platform->security_manager->lost_message_queue,
00292                message
00293               );
00294             continue;
00295           }
00296           if (
00297               message_Decrypt(message, asm_node)
00298           ) 
00299           { 
00300             fprintf(stderr, "Decrypt error. %s:%d\n", __FILE__, __LINE__);
00301             message_Destroy(message); 
00302           } else {
00303             message_queue_Add
00304               (
00305                mc_platform->message_queue,
00306                message
00307               );
00308           }
00309           break;
00310         case ENCRYPTION_INITIALIZE:
00311           asm_queue_RemoveAddr
00312             (
00313              mc_platform->asm_queue,
00314              message->addr
00315             );
00316           asm_queue_Add
00317             (
00318              mc_platform->asm_queue,
00319              asm_node_Initialize(message, mc_platform->security_manager)
00320             );
00321           message_Destroy(message);
00322           break;
00323         default:
00324           if (asm_node == NULL) {
00325             /* Send our encryption data to other host */
00326             asm_SendEncryptionData
00327               (
00328                mc_platform->security_manager,
00329                message->to_address
00330               );
00331             /* Request an initialization from the other host */
00332             asm_RequestInitFromAddr
00333               (
00334                mc_platform,
00335                message->to_address
00336               );
00337             /* Add message to queue of lost message. We must wait until
00338              * we receive encryption data back from the other host
00339              * before we can proceed. */
00340             message_queue_Add
00341               (
00342                mc_platform->security_manager->lost_message_queue,
00343                message
00344               );
00345           } else {
00346             message_Encrypt(message, asm_node);
00347             message_queue_Add
00348               (
00349                mc_platform->message_queue,
00350                message
00351               );
00352           }
00353           break;
00354       }
00355     }
00356   }
00357 }
00358 
00359 #endif /* MC_SECURITY */

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4