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