00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <string.h>
00033 #ifndef _WIN32
00034 #include <sys/types.h>
00035 #include <sys/socket.h>
00036 #include <netinet/in.h>
00037 #include <arpa/inet.h>
00038 #include <unistd.h>
00039 #include <netdb.h>
00040 #else
00041 #include "winconfig.h"
00042 #endif
00043 #include <mxml.h>
00044 #include "include/agent.h"
00045 #include "include/mc_platform.h"
00046 #include "include/message.h"
00047 #include "include/mtp_http.h"
00048 #include "include/xml_compose.h"
00049 #include "include/xml_helper.h"
00050 #include "include/xml_parser.h"
00051
00052 #include "security/asm_node.h"
00053
00054 #define SOCKET_INPUT_SIZE 4096
00055
00056 #ifdef MC_SECURITY
00057 int message_Decrypt(message_p message, asm_node_p asm_node)
00058 {
00059 int i;
00060 mxml_node_t* message_node;
00061 mxml_node_t* encrypted_data_node;
00062 mxml_node_t* gaf_message_node;
00063 char* encrypted_hex_string;
00064 unsigned char* message_string;
00065 char buf[3];
00066 unsigned char iv[32];
00067 int tmp = 0;
00068 int decrypt_len;
00069
00070 gaf_message_node = mxmlFindElement
00071 (
00072 message->xml_root,
00073 message->xml_root,
00074 "GAF_MESSAGE",
00075 NULL,
00076 NULL,
00077 MXML_DESCEND
00078 );
00079
00080 message_node = mxmlFindElement
00081 (
00082 message->xml_root,
00083 message->xml_root,
00084 "MESSAGE",
00085 NULL,
00086 NULL,
00087 MXML_DESCEND
00088 );
00089 if (message_node == NULL) return MC_ERR_PARSE;
00090 encrypted_data_node = mxmlFindElement
00091 (
00092 message->xml_root,
00093 message_node,
00094 "ENCRYPTED_DATA",
00095 NULL,
00096 NULL,
00097 MXML_DESCEND
00098 );
00099 if (encrypted_data_node == NULL) return MC_ERR_PARSE;
00100 encrypted_hex_string = xml_get_text(encrypted_data_node);
00101
00102
00103 message_string = (unsigned char*)malloc
00104 (
00105 sizeof(char) *
00106 ((strlen(encrypted_hex_string)/2) + 32)
00107 );
00108 CHECK_NULL(message_string, exit(0););
00109 buf[2] = '\0';
00110 for(i = 0; i < (int)strlen(encrypted_hex_string); i += 2)
00111 {
00112 buf[0] = encrypted_hex_string[i];
00113 buf[1] = encrypted_hex_string[i+1];
00114 sscanf(buf, "%x", &tmp);
00115 message_string[i/2] = (unsigned char) tmp;
00116 }
00117
00118 decrypt_len =
00119 strlen(encrypted_hex_string)/2;
00120 memset(iv, 0, sizeof(iv));
00121 aes_cbc_decrypt
00122 (
00123 &(asm_node->data.dh_data->aes),
00124 iv,
00125 (unsigned char*)message_string,
00126 (unsigned char*)message_string,
00127 decrypt_len
00128 );
00129
00130 mxmlDelete(message_node);
00131
00132 mxmlLoadString
00133 (
00134 gaf_message_node,
00135 (char*)message_string,
00136 MXML_NO_CALLBACK
00137 );
00138
00139
00140 free(encrypted_hex_string);
00141 free(message_string);
00142
00143
00144 return message_xml_parse(message);
00145 }
00146
00147 int
00148 message_Encrypt(message_p message, asm_node_p asm_node)
00149 {
00150 int i;
00151 int encrypt_len;
00152 mxml_node_t* message_node;
00153 mxml_node_t* gaf_message_node;
00154 mxml_node_t* encrypted_data_node;
00155 char* message_str;
00156 int message_len;
00157 char* encrypted_message_str;
00158 unsigned char iv[32];
00159 char buf[4];
00160
00161
00162 if (message->xml_root == NULL) {
00163 message->xml_root = mxmlLoadString
00164 (
00165 NULL,
00166 message->message_body,
00167 MXML_NO_CALLBACK
00168 );
00169 }
00170
00171
00172 if(message->message_body) {
00173 free(message->message_body);
00174 message->message_body = NULL;
00175 }
00176
00177 message_node = mxmlFindElement
00178 (
00179 message->xml_root,
00180 message->xml_root,
00181 "MESSAGE",
00182 NULL,
00183 NULL,
00184 MXML_DESCEND
00185 );
00186 if (message_node == NULL) {
00187 return MC_ERR_PARSE;
00188 }
00189 message_str = mxmlSaveAllocString
00190 (
00191 message_node,
00192 MXML_NO_CALLBACK
00193 );
00194 message_len = strlen(message_str);
00195 message_str = realloc(message_str, message_len + 16);
00196 CHECK_NULL(message_str, exit(0););
00197
00198 encrypt_len = message_len + (16 - message_len%16);
00199 memset(iv, 0, sizeof(iv));
00200 aes_cbc_encrypt
00201 (
00202 &(asm_node->data.dh_data->aes),
00203 iv,
00204 (unsigned char*) message_str,
00205 (unsigned char*) message_str,
00206 encrypt_len
00207 );
00208 encrypted_message_str = (char*) malloc
00209 (
00210 sizeof(char) *
00211 (encrypt_len*2)+1
00212 );
00213 CHECK_NULL(encrypted_message_str, exit(0););
00214
00215
00216 encrypted_message_str[0] = '\0';
00217 buf[2] = '\0';
00218 for (i = 0; i < encrypt_len ; i++)
00219 {
00220 sprintf(buf, "%02x", (unsigned char)message_str[i]);
00221 strcat(encrypted_message_str, buf);
00222 }
00223
00224
00225 mxmlDelete(message_node);
00226 gaf_message_node = mxmlFindElement
00227 (
00228 message->xml_root,
00229 message->xml_root,
00230 "GAF_MESSAGE",
00231 NULL,
00232 NULL,
00233 MXML_DESCEND
00234 );
00235
00236 message_node = mxmlNewElement
00237 (
00238 gaf_message_node,
00239 "MESSAGE"
00240 );
00241 mxmlElementSetAttr
00242 (
00243 message_node,
00244 "message",
00245 "ENCRYPTED_DATA"
00246 );
00247 mxmlElementSetAttr
00248 (
00249 message_node,
00250 "from",
00251 message->from_address
00252 );
00253
00254 encrypted_data_node = mxmlNewElement
00255 (
00256 message_node,
00257 "ENCRYPTED_DATA"
00258 );
00259
00260 xml_new_cdata
00261 (
00262 encrypted_data_node,
00263 encrypted_message_str
00264 );
00265
00266 message->message_body = mxmlSaveAllocString
00267 (
00268 message->xml_root,
00269 MXML_NO_CALLBACK
00270 );
00271
00272 free(message_str);
00273 free(encrypted_message_str);
00274
00275 message->message_type = ENCRYPTED_DATA;
00276
00277 return MC_SUCCESS;
00278 }
00279 #endif
00280
00281 message_p
00282 message_New(void)
00283 {
00284 message_p message;
00285 message = (message_p)malloc(sizeof(message_t));
00286 CHECK_NULL(message, exit(0););
00287 message->addr = NULL;
00288 message->connect_id = 0;
00289 message->message_id = 0;
00290 message->isHTTP = 0;
00291 message->message_type = 0;
00292 message->http_type = 0;
00293 message->xml_root = NULL;
00294 message->xml_payload = NULL;
00295 message->message_body = NULL;
00296 message->update_name = NULL;
00297 message->update_num = 0;
00298 message->from_address = NULL;
00299 message->to_address = NULL;
00300 message->target = NULL;
00301 message->agent_xml_flag = 0;
00302 return message;
00303 }
00304
00305 int
00306 message_InitializeFromAgent(
00307 mc_platform_p mc_platform,
00308 message_p message,
00309 agent_p agent)
00310 {
00311 struct hostent* host;
00312
00313 char* buf;
00314 char* destination_host;
00315 char* destination_port_str;
00316 #ifndef _WIN32
00317 char* save_ptr;
00318 #endif
00319 int destination_port;
00320
00321 message->message_id = rand();
00322 message->message_type = MOBILE_AGENT;
00323
00324 message->xml_root = agent_xml_compose(agent);
00325
00326
00327 CHECK_NULL(message->xml_root, exit(0););
00328 message->message_body = mxmlSaveAllocString(
00329 message->xml_root,
00330 MXML_NO_CALLBACK );
00331
00332 message->update_name = NULL;
00333
00334 message->from_address =
00335 (char*)malloc(sizeof(char) * (strlen(mc_platform->hostname) + 10));
00336 sprintf(
00337 message->from_address,
00338 "%s:%d",
00339 mc_platform->hostname,
00340 mc_platform->port );
00341 if (
00342 agent->datastate->task_progress >=
00343 agent->datastate->number_of_tasks
00344 )
00345 {
00346 message->to_address =
00347 (char*)malloc
00348 (
00349 sizeof(char) *
00350 (
00351 strlen(agent->home) + 1
00352 )
00353 );
00354 CHECK_NULL(message->to_address, exit(0););
00355 strcpy
00356 (
00357 message->to_address,
00358 agent->home
00359 );
00360 } else {
00361 message->to_address =
00362 (char*) malloc
00363 (
00364 sizeof(char) *
00365 (
00366 strlen
00367 (
00368 agent->datastate->tasks[ agent->datastate->task_progress ]
00369 ->server_name
00370 )
00371 +1
00372 )
00373 );
00374 CHECK_NULL( message->to_address, mc_platform->err = MC_ERR_MEMORY; return MC_ERR_MEMORY;);
00375 strcpy(
00376 message->to_address,
00377 agent->datastate->tasks[ agent->datastate->task_progress ]->server_name
00378 );
00379 }
00380 message->agent_xml_flag = 0;
00381 message->target = strdup("ams");
00382
00383 buf = (char*)malloc
00384 (
00385 sizeof(char) *
00386 (strlen(message->to_address)+1)
00387 );
00388 CHECK_NULL(buf, exit(0););
00389 strcpy(buf, message->to_address);
00390 destination_host = strtok_r(buf, ":", &save_ptr);
00391 destination_port_str = strtok_r(NULL, ":", &save_ptr);
00392 destination_port = atoi(destination_port_str);
00393 message->addr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
00394 if ((host = gethostbyname(destination_host))) {
00395 memcpy(&(message->addr->sin_addr), host->h_addr, host->h_length);
00396 message->addr->sin_port = htons(destination_port);
00397 } else {
00398 WARN("Host not found.");
00399 }
00400 free(buf);
00401 return MC_SUCCESS;
00402 }
00403
00404 int
00405 message_InitializeFromConnection(
00406 mc_platform_p mc_platform,
00407 message_p message,
00408 connection_p connection)
00409 {
00410 int i = 1;
00411 int n;
00412 char *message_string;
00413 char *buffer;
00414
00415 message->addr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
00416 CHECK_NULL(message->addr, exit(0););
00417 *(message->addr) = connection->addr;
00418
00419 message->connect_id = connection->connect_id;
00420
00421 message->message_id = rand();
00422
00423 message->to_address = NULL;
00424 message->from_address = NULL;
00425 message->target = NULL;
00426
00427 buffer = (char*) malloc(sizeof(char) * (SOCKET_INPUT_SIZE + 1));
00428 CHECK_NULL(buffer, exit(0););
00429 message_string = (char*) malloc(sizeof(char) * (SOCKET_INPUT_SIZE + 1));
00430 CHECK_NULL(message_string, exit(0););
00431 message_string[0] = '\0';
00432 buffer[0] = '\0';
00433
00434
00435 while(1) {
00436 #ifndef _WIN32
00437 n = recvfrom(connection->clientfd,
00438 (void *) buffer,
00439 (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00440 0,
00441 (struct sockaddr *) 0,
00442 (socklen_t *) 0);
00443 #else
00444 n = recvfrom(connection->clientfd,
00445 (void *) buffer,
00446 (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00447 0,
00448 (struct sockaddr *) 0,
00449 0);
00450 #endif
00451 if (n < 0) {
00452 free(buffer);
00453 return MC_ERR_CONNECT;
00454 }
00455 else if (n == 0) {
00456 free(buffer);
00457 break;
00458 } else {
00459 buffer[n] = '\0';
00460 i++;
00461 strcat(message_string, buffer);
00462 message_string = realloc
00463 (
00464 message_string,
00465 sizeof(char) * (SOCKET_INPUT_SIZE+1) * i
00466 );
00467 CHECK_NULL(message_string, exit(0););
00468 buffer[0] = '\0';
00469 }
00470 }
00471 message->message_body = (char*)malloc
00472 (
00473 sizeof(char) *
00474 (strlen(message_string) + 1)
00475 );
00476 CHECK_NULL(message->message_body, exit(0););
00477 strcpy(message->message_body, message_string);
00478 free(message_string);
00479 message->xml_root = mxmlLoadString
00480 (
00481 NULL,
00482 message->message_body,
00483 MXML_NO_CALLBACK
00484 );
00485 if (message_xml_parse(message)) {
00486 fprintf(stderr, "Error parsing message at %s:%d.\n",
00487 __FILE__, __LINE__);
00488 message_Destroy(message);
00489 return MC_ERR_PARSE;
00490 }
00491 return MC_SUCCESS;
00492 }
00493
00494 int http_to_hostport(const char* http_str, char** host, int* port, char** target)
00495 {
00496
00497
00498
00499
00500 char* tmp;
00501 if(strncmp(http_str, "http://", 7)) {
00502 return MC_ERR_PARSE;
00503 }
00504 http_str += 7;
00505 tmp = strchr(http_str, (int)':');
00506 if (tmp == NULL) return MC_ERR_PARSE;
00507
00508
00509 *host = (char*)malloc(sizeof(char) *
00510 (tmp - http_str + 1) );
00511 strncpy(*host, http_str, tmp - http_str);
00512 (*host)[tmp-http_str] = '\0';
00513
00514
00515 tmp++;
00516 sscanf(tmp, "%d", port);
00517
00518
00519 tmp = strchr(tmp, (int)'/');
00520 tmp++;
00521 *target = (char*)malloc(sizeof(char) *
00522 (strlen(tmp)+1) );
00523 strcpy(*target, tmp);
00524
00525 return 0;
00526 }
00527
00528 int
00529 message_InitializeFromString(
00530 mc_platform_p mc_platform,
00531 message_p message,
00532 const char* string,
00533 const char* destination_host,
00534 int destination_port,
00535 const char* target)
00536 {
00537 char* destination;
00538 struct hostent* host;
00539
00540 message->connect_id = 0;
00541 message->message_id = rand();
00542
00543 message->message_type = MOBILE_AGENT;
00544
00545 message->xml_root = NULL;
00546
00547 message->message_body =
00548 (char*)malloc( sizeof(char) * (strlen(string)+1));
00549 CHECK_NULL(message->message_body,
00550 mc_platform->err = MC_ERR_MEMORY;
00551 return MC_ERR_MEMORY; );
00552 strcpy(message->message_body, string);
00553
00554 message->update_name = NULL;
00555
00556 destination = malloc(sizeof(char)*(strlen(destination_host) + 10));
00557 CHECK_NULL(destination,
00558 mc_platform->err = MC_ERR_MEMORY;
00559 return MC_ERR_MEMORY; );
00560 sprintf(destination, "%s:%d",
00561 destination_host,
00562 destination_port
00563 );
00564
00565 message->to_address = destination;
00566 message->from_address = (char*)malloc(
00567 sizeof(char) * (strlen(mc_platform->hostname)+10));
00568 sprintf(message->from_address,
00569 "%s:%d",
00570 mc_platform->hostname,
00571 mc_platform->port );
00572 message->target = (char*)malloc(sizeof(char) *
00573 (strlen(target)+1));
00574 strcpy(message->target, target);
00575
00576
00577 message->addr = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
00578 if((host = gethostbyname(destination_host)))
00579 {
00580 memcpy(&(message->addr->sin_addr), host->h_addr, host->h_length);
00581 message->addr->sin_port = htons(destination_port);
00582 } else {
00583 fprintf(stderr, "Warning: Host not found: %s:%d %s:%d",
00584 destination_host, destination_port, __FILE__, __LINE__ );
00585 }
00586
00587 return MC_SUCCESS;
00588 }
00589
00590 int
00591 message_Destroy(message_p message)
00592 {
00593 int i;
00594 if (message == NULL) {
00595 return MC_SUCCESS;
00596 }
00597
00598
00599 if(message->xml_root != NULL && message->agent_xml_flag == 0) {
00600 mxmlDelete(message->xml_root);
00601 }
00602
00603 if(message->addr) {
00604 free(message->addr);
00605 message->addr = NULL;
00606 }
00607 if(message->message_body != NULL) {
00608 free(message->message_body);
00609 message->message_body = NULL;
00610 }
00611 if(message->update_name != NULL) {
00612 free(message->update_name);
00613 }
00614 if(message->from_address != NULL) {
00615 free(message->from_address);
00616 }
00617 if(message->to_address != NULL) {
00618 free(message->to_address);
00619 }
00620 if(message->target != NULL) {
00621 free(message->target);
00622 }
00623
00624 free(message);
00625 message = NULL;
00626 return MC_SUCCESS;
00627 }
00628
00629 int
00630 message_Send(message_p message)
00631 {
00632 #ifndef _WIN32
00633 int skt;
00634 struct sockaddr_in sktin;
00635 #else
00636 SOCKET skt;
00637 SOCKADDR_IN sktin;
00638 #endif
00639 struct hostent *host;
00640 char *buf;
00641 char *hostname;
00642 #ifndef _WIN32
00643 char *saveptr;
00644 #endif
00645 int port;
00646
00647
00648 if (
00649 mtp_http_ComposeMessage(
00650 message
00651 )
00652 )
00653 {
00654 return MC_ERR;
00655 }
00656
00657
00658 buf = (char*)malloc(sizeof(char)*(strlen(message->to_address)+1));
00659 strcpy(buf, message->to_address);
00660 hostname = strtok_r(buf, ":", &saveptr);
00661 sscanf( strtok_r(NULL, ":", &saveptr), "%d", &port );
00662
00663 if((skt = socket(PF_INET, SOCK_STREAM, 0)) < 0)
00664 {
00665 fprintf(stderr, "Error - can't create socket\n");
00666 return -1;
00667 }
00668
00669 memset(&sktin, 0, sizeof(sktin));
00670 sktin.sin_family = PF_INET;
00671 sktin.sin_port = htons(port);
00672
00673 if((host = gethostbyname(hostname)))
00674 {
00675 memcpy(&sktin.sin_addr, host->h_addr, host->h_length);
00676 }
00677 else if((sktin.sin_addr.s_addr = inet_addr(hostname)) < 0)
00678 {
00679 fprintf(stderr, "Error - can't get host entry for %s\n", hostname);
00680 free(buf);
00681 return -1;
00682 }
00683
00684 if(connect(skt, (struct sockaddr *) &sktin, sizeof(sktin)) < 0) {
00685 fprintf(stderr, "Error - can't connect to %s:%d\n",
00686 hostname,
00687 port
00688 );
00689 free(buf);
00690 return MC_ERR_CONNECT;
00691 }
00692
00693 if(send(skt, message->message_body, strlen(message->message_body)+1, 0) < 0)
00694 {
00695 fprintf(stderr, "cannot write to socket %s:%d\n",
00696 __FILE__, __LINE__);
00697 #ifndef _WIN32
00698 close(skt);
00699 #else
00700 closesocket(skt);
00701 #endif
00702 free(buf);
00703 return MC_ERR_SEND;
00704 }
00705 #ifndef _WIN32
00706 close(skt);
00707 #else
00708 closesocket(skt);
00709 #endif
00710 free(buf);
00711 return 0;
00712 }
00713
00714