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 message->xml_root = mxmlLoadString
00601 (
00602 NULL,
00603 message->message_body,
00604 MXML_NO_CALLBACK
00605 );
00606 if (message_xml_parse(message)) {
00607 fprintf(stderr, "Error parsing message at %s:%d.\n",
00608 __FILE__, __LINE__);
00609 message_Destroy(message);
00610 return MC_ERR_PARSE;
00611 }
00612
00613 return MC_SUCCESS;
00614 }
00615
00616 int
00617 message_Destroy(message_p message)
00618 {
00619 if (message == NULL) {
00620 return MC_SUCCESS;
00621 }
00622
00623
00624 if(message->xml_root != NULL && message->agent_xml_flag == 0) {
00625 mxmlDelete(message->xml_root);
00626 }
00627
00628 if(message->addr) {
00629 free(message->addr);
00630 message->addr = NULL;
00631 }
00632 if(message->message_body != NULL) {
00633 free(message->message_body);
00634 message->message_body = NULL;
00635 }
00636 if(message->update_name != NULL) {
00637 free(message->update_name);
00638 }
00639 if(message->from_address != NULL) {
00640 free(message->from_address);
00641 }
00642 if(message->to_address != NULL) {
00643 free(message->to_address);
00644 }
00645 if(message->target != NULL) {
00646 free(message->target);
00647 }
00648
00649 free(message);
00650 message = NULL;
00651 return MC_SUCCESS;
00652 }
00653
00654 int
00655 message_Send(message_p message)
00656 {
00657 char *buffer;
00658 mtp_http_t* mtp_http;
00659 int n;
00660 #ifndef _WIN32
00661 int skt;
00662 struct sockaddr_in sktin;
00663 #else
00664 SOCKET skt;
00665 SOCKADDR_IN sktin;
00666 #endif
00667 struct hostent *host;
00668 char *buf;
00669 char *hostname;
00670 #ifndef _WIN32
00671 char *saveptr;
00672 #endif
00673 int port;
00674
00675
00676 if (
00677 mtp_http_ComposeMessage(
00678 message
00679 )
00680 )
00681 {
00682 return MC_ERR;
00683 }
00684
00685
00686 buf = (char*)malloc(sizeof(char)*(strlen(message->to_address)+1));
00687 strcpy(buf, message->to_address);
00688 hostname = strtok_r(buf, ":", &saveptr);
00689 sscanf( strtok_r(NULL, ":", &saveptr), "%d", &port );
00690
00691 if((skt = socket(PF_INET, SOCK_STREAM, 0)) < 0)
00692 {
00693 fprintf(stderr, "Error - can't create socket\n");
00694 return -1;
00695 }
00696
00697 memset(&sktin, 0, sizeof(sktin));
00698 sktin.sin_family = PF_INET;
00699 sktin.sin_port = htons(port);
00700
00701 if((host = gethostbyname(hostname)))
00702 {
00703 memcpy(&sktin.sin_addr, host->h_addr, host->h_length);
00704 }
00705 else if((sktin.sin_addr.s_addr = inet_addr(hostname)) < 0)
00706 {
00707 fprintf(stderr, "Error - can't get host entry for %s\n", hostname);
00708 free(buf);
00709 return -1;
00710 }
00711
00712 if(connect(skt, (struct sockaddr *) &sktin, sizeof(sktin)) < 0) {
00713 fprintf(stderr, "Error - can't connect to %s:%d\n",
00714 hostname,
00715 port
00716 );
00717 free(buf);
00718 return MC_ERR_CONNECT;
00719 }
00720
00721 if(send(skt, message->message_body, strlen(message->message_body), 0) < 0)
00722 {
00723 fprintf(stderr, "cannot write to socket %s:%d\n",
00724 __FILE__, __LINE__);
00725 #ifndef _WIN32
00726 close(skt);
00727 #else
00728 closesocket(skt);
00729 #endif
00730 free(buf);
00731 return MC_ERR_SEND;
00732 }
00733
00734 buffer = (char*) malloc(sizeof(char) * (SOCKET_INPUT_SIZE + 1));
00735 CHECK_NULL(buffer, exit(0););
00736 mtp_http = mtp_http_New();
00737 #ifndef _WIN32
00738 n = recvfrom(skt,
00739 (void *) buffer,
00740 (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00741 0,
00742 (struct sockaddr *) 0,
00743 (socklen_t *) 0);
00744 #else
00745 n = recvfrom(skt,
00746 (void *) buffer,
00747 (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00748 0,
00749 (struct sockaddr *) 0,
00750 0);
00751 #endif
00752 if( mtp_http_Parse(mtp_http, buffer) ) {
00753 fprintf(stderr, "http parsing error: Response expected. %s:%d\n",
00754 __FILE__, __LINE__);
00755 fprintf(stderr, "Received message was:\n%s\n", buffer);
00756 }
00757 if (mtp_http->response_code != 200) {
00758 fprintf(stderr, "Warning: remote http server responded: %d %s\n",
00759 mtp_http->response_code, mtp_http->response_string );
00760 }
00761
00762 mtp_http_Destroy(mtp_http);
00763
00764 #ifndef _WIN32
00765 close(skt);
00766 #else
00767 closesocket(skt);
00768 #endif
00769 free(buf);
00770 free(buffer);
00771 return 0;
00772 }
00773
00774