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
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
00118
00119
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
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
00184
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
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
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
00222
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
00283
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
00326 asm_SendEncryptionData
00327 (
00328 mc_platform->security_manager,
00329 message->to_address
00330 );
00331
00332 asm_RequestInitFromAddr
00333 (
00334 mc_platform,
00335 message->to_address
00336 );
00337
00338
00339
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