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