/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/security/asm.c

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

Generated on Fri Jul 11 17:59:45 2008 for Mobile-C by  doxygen 1.5.4