00001
00002
00003
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
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
00121
00122
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
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
00187
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
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
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
00225
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
00286
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
00329 asm_SendEncryptionData
00330 (
00331 mc_platform->security_manager,
00332 message->to_address
00333 );
00334
00335 asm_RequestInitFromAddr
00336 (
00337 mc_platform,
00338 message->to_address
00339 );
00340
00341
00342
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