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