cmtutils.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:16k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* 
  3.  * The contents of this file are subject to the Mozilla Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/MPL/
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  * 
  13.  * The Original Code is the Netscape security libraries.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are 
  17.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  18.  * Rights Reserved.
  19.  * 
  20.  * Contributor(s):
  21.  * 
  22.  * Alternatively, the contents of this file may be used under the
  23.  * terms of the GNU General Public License Version 2 or later (the
  24.  * "GPL"), in which case the provisions of the GPL are applicable 
  25.  * instead of those above.  If you wish to allow use of your 
  26.  * version of this file only under the terms of the GPL and not to
  27.  * allow others to use your version of this file under the MPL,
  28.  * indicate your decision by deleting the provisions above and
  29.  * replace them with the notice and other provisions required by
  30.  * the GPL.  If you do not delete the provisions above, a recipient
  31.  * may use your version of this file under either the MPL or the
  32.  * GPL.
  33.  */
  34. #if defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2)
  35. #include <sys/types.h>
  36. #include <sys/socket.h>
  37. #include <netinet/in.h>
  38. #else
  39. #ifdef XP_MAC
  40. #include "macsocket.h"
  41. #else /* Windows */
  42. #include <windows.h>
  43. #include <winsock.h>
  44. #endif
  45. #endif
  46. #include "cmtcmn.h"
  47. #include "cmtutils.h"
  48. #include "newproto.h"
  49. #include <string.h>
  50. /* Local defines */
  51. #if 0
  52. #define PSM_WAIT_BEFORE_SLEEP           (CM_TicksPerSecond() * 60)
  53. #define PSM_SPINTIME                    PSM_WAIT_BEFORE_SLEEP
  54. #define PSM_KEEP_CONNECTION_ALIVE       (PSM_WAIT_BEFORE_SLEEP * 900)
  55. #endif
  56. /* If you want to dump the messages sent between the plug-in and the PSM 
  57.  * server, then remove the comment for the appropriate define.
  58.  */
  59. #if 0
  60. #define PRINT_SEND_MESSAGES
  61. #define PRINT_RECEIVE_MESSAGES
  62. #endif
  63. #ifdef PRINT_SEND_MESSAGES
  64. #ifndef DEBUG_MESSAGES
  65. #define DEBUG_MESSAGES
  66. #endif /*DEBUG_MESSAGES*/
  67. #endif /*PRINT_SEND_MESSAGES*/
  68. #ifdef PRINT_RECEIVE_MESSAGES
  69. #ifndef DEBUG_MESSAGES
  70. #define DEBUG_MESSAGES
  71. #endif /*DEBUG_MESSAGES*/
  72. #endif /*PRINT_RECEIVE_MESSAGES*/
  73. #ifdef DEBUG_MESSAGES
  74. #define LOG(x) do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { 
  75.    fprintf(f, x); fclose(f); } } while(0);
  76. #define LOG_S(x) do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { 
  77.    fprintf(f, "%s", x); fclose(f); } } while(0);
  78. #define ASSERT(x) if (!(x)) { LOG("ASSERT:"); LOG(#x); LOG("n"); exit(-1); }
  79. #else
  80. #define LOG(x)
  81. #define LOG_S(x)
  82. #define ASSERT(x)
  83. #endif
  84. CMUint32
  85. cmt_Strlen(char *str)
  86. {
  87.     CMUint32 len = strlen(str);
  88.     return sizeof(CMInt32) + (((len + 3)/4)*4);
  89. }
  90. CMUint32
  91. cmt_Bloblen(CMTItem *blob)
  92. {
  93.     return sizeof(CMInt32) + (((blob->len +3)/4)*4);
  94. }
  95. char *
  96. cmt_PackString(char *buf, char *str)
  97. {
  98.     CMUint32 len = strlen(str);
  99.     CMUint32 networkLen = htonl(len);
  100.     CMUint32 padlen = ((len + 3)/4)*4;
  101.     memcpy(buf, &networkLen, sizeof(CMUint32));
  102.     memcpy(buf + sizeof(CMUint32), str, len);
  103.     memset(buf + sizeof(CMUint32) + len, 0, padlen - len);
  104.     return buf+sizeof(CMUint32)+padlen;
  105. }
  106. char *
  107. cmt_PackBlob(char *buf, CMTItem *blob)
  108. {
  109.     CMUint32 len = blob->len;
  110.     CMUint32 networkLen = htonl(len);
  111.     CMUint32 padlen = (((blob->len + 3)/4)*4);
  112.     *((CMUint32*)buf) = networkLen;
  113.     memcpy(buf + sizeof(CMUint32), blob->data, len);
  114.     memset(buf + sizeof(CMUint32) + len, 0, padlen - len);
  115.     return buf + sizeof(CMUint32) + padlen;
  116. }
  117. char *
  118. cmt_UnpackString(char *buf, char **str)
  119. {
  120.     char *p = NULL;
  121.     CMUint32 len, padlen;
  122.     /* Get the string length */
  123.     len = ntohl(*(CMUint32*)buf);
  124.     /* Get the padded length */
  125.     padlen = ((len + 3)/4)*4;
  126.     /* Allocate the string and copy the data */
  127.     p = (char *) malloc(len + 1);
  128.     if (!p) {
  129.         goto loser;
  130.     }
  131.     /* Copy the data and NULL terminate */
  132.     memcpy(p, buf+sizeof(CMUint32), len);
  133.     p[len] = 0;
  134.     *str = p;
  135.     return buf+sizeof(CMUint32)+padlen;
  136. loser:
  137.     *str = NULL;
  138.     if (p) {
  139.         free(p);
  140.     }
  141.     return buf+sizeof(CMUint32)+padlen;
  142. }
  143. char *
  144. cmt_UnpackBlob(char *buf, CMTItem **blob)
  145. {
  146.     CMTItem *p = NULL;
  147.     CMUint32 len, padlen;
  148.     /* Get the blob length */
  149.     len = ntohl(*(CMUint32*)buf);
  150.     
  151.     /* Get the padded length */
  152.     padlen = ((len + 3)/4)*4;
  153.     /* Allocate the CMTItem for the blob */
  154.     p = (CMTItem*)malloc(sizeof(CMTItem));
  155.     if (!p) {
  156.         goto loser;
  157.     }
  158.     p->len = len;
  159.     p->data = (unsigned char *) malloc(len);
  160.     if (!p->data) {
  161.         goto loser;
  162.     }
  163.     /* Copy that data across */
  164.     memcpy(p->data, buf+sizeof(CMUint32), len);
  165.     *blob = p;
  166.     return buf+sizeof(CMUint32)+padlen;
  167. loser:
  168.     *blob = NULL;
  169.     CMT_FreeMessage(p);
  170.     return buf+sizeof(CMUint32)+padlen;
  171. }
  172. #ifdef DEBUG_MESSAGES
  173. void prettyPrintMessage(CMTItem *msg)
  174. {
  175.   int numLines = ((msg->len+7)/8);
  176.   char curBuffer[9], *cursor, string[2], hexVal[8];
  177.   char hexArray[25];
  178.   int i, j, numToCopy;
  179.   /*Try printing out 8 bytes at a time. */
  180.   LOG("n**********************************************************n");
  181.   LOG("About to pretty Print Messagenn");
  182.   curBuffer[9] = '';
  183.   hexArray[24] = '';
  184.   hexVal[2] = '';
  185.   string[1] = '';
  186.   LOG("Header Infon");
  187.   LOG("Message Type: ");
  188.   sprintf(hexArray, "%lxn", msg->type);
  189.   LOG(hexArray);
  190.   LOG("Message Length: ");
  191.   sprintf (hexArray, "%ldnn", msg->len);
  192.   LOG(hexArray);
  193.   LOG("Body of Messagen");
  194.   for (i=0, cursor=msg->data; i<numLines; i++, cursor+=8) {
  195.     /* First copy over the buffer to our local array */
  196.     numToCopy = ((msg->len - (unsigned int)((unsigned long)cursor-(unsigned long)msg->data)) < 8) ?
  197.                 msg->len - (unsigned int)((unsigned long)cursor-(unsigned long)msg->data) : 8;
  198.     memcpy(curBuffer, cursor, 8);
  199.     for (j=0;j<numToCopy;j++) {
  200.       string[0] = curBuffer[j];
  201.       if (isprint(curBuffer[j])) {
  202. string[0] = curBuffer[j];
  203.       } else {
  204. string[0] = ' ';
  205.       }
  206.       LOG(string);
  207.     }
  208.     string[0] = ' ';
  209.     for (;j<8;j++) {
  210.       LOG(string);
  211.     }
  212.     LOG("t");
  213.     for (j=0; j<numToCopy; j++) {
  214.       sprintf (hexVal,"%.2x", 0x0ff & (unsigned short)curBuffer[j]);
  215.       LOG(hexVal);
  216.       LOG(" ");
  217.     }
  218.     LOG("n");
  219.   }
  220.   LOG("Done Pretty Printing Messagen");
  221.   LOG("**********************************************************nn");
  222. }
  223. #endif
  224. CMTStatus CMT_ReadMessageDispatchEvents(PCMT_CONTROL control, CMTItem* message)
  225. {
  226.     CMTStatus status;
  227.     CMBool done = CM_FALSE;
  228.     CMUint32 msgCategory;
  229.     
  230.     /* We have to deal with other types of data on the socket and */
  231.     /* handle them accordingly */
  232.     while (!done) {
  233.      status = CMT_ReceiveMessage(control, message);
  234.         if (status != CMTSuccess) {
  235.             goto loser;
  236.         }
  237.         msgCategory = (message->type & SSM_CATEGORY_MASK);
  238.         switch (msgCategory) {
  239.             case SSM_REPLY_OK_MESSAGE:
  240.                 done = CM_TRUE;
  241.                 break;
  242.             case SSM_REPLY_ERR_MESSAGE:
  243.                 done = CM_TRUE;
  244.                 break;
  245.             case SSM_EVENT_MESSAGE:
  246.                 CMT_DispatchEvent(control, message);
  247.                 break;
  248.             /* XXX FIX THIS!!! For the moment I'm ignoring all other types */
  249.             default:
  250.                 break;
  251.         }
  252.     }
  253.     return CMTSuccess;
  254.  loser:
  255.     return CMTFailure;
  256. }
  257. CMTStatus CMT_SendMessage(PCMT_CONTROL control, CMTItem* message)
  258. {
  259. CMTStatus status;
  260. #ifdef PRINT_SEND_MESSAGES
  261.     LOG("About to print message sent to PSMn");
  262.     prettyPrintMessage(message);
  263. #endif
  264.     /* Acquire lock on the control connection */
  265.     CMT_LOCK(control->mutex);
  266.     /* Try to send pending random data */
  267.     if (message->type != (SSM_REQUEST_MESSAGE | SSM_HELLO_MESSAGE))
  268.     {
  269.         /* If we've already said hello, then flush random data
  270.            just before sending the request. */
  271.         status = CMT_FlushPendingRandomData(control);
  272.         if (status != CMTSuccess)
  273.             goto loser;
  274.     }
  275.     
  276. status = CMT_TransmitMessage(control, message);
  277. if (status != CMTSuccess) {
  278. goto loser;
  279. }
  280.     if (CMT_ReadMessageDispatchEvents(control, message) != CMTSuccess) {
  281.         goto loser;
  282.     }
  283.     /* Release the control connection lock */
  284.     CMT_UNLOCK(control->mutex);
  285. return CMTSuccess;
  286. loser:
  287.     /* Release the control connection lock */
  288.     CMT_UNLOCK(control->mutex);
  289. return CMTFailure;
  290. }
  291. CMTStatus CMT_TransmitMessage(PCMT_CONTROL control, CMTItem * message)
  292. {
  293.     CMTMessageHeader header;
  294. CMUint32 sent;
  295.     /* Set up the message header */
  296.     header.type = htonl(message->type);
  297.     header.len = htonl(message->len);
  298. /* Send the message header */
  299. sent = CMT_WriteThisMany(control, control->sock, 
  300.                              (void *)&header, sizeof(CMTMessageHeader));
  301. if (sent != sizeof(CMTMessageHeader)) {
  302. goto loser;
  303. }
  304. /* Send the message body */
  305. sent = CMT_WriteThisMany(control, control->sock, (void *)message->data, 
  306.                              message->len);
  307. if (sent != message->len) {
  308. goto loser;
  309. }
  310.     /* Free the buffer */
  311.     free(message->data);
  312.     message->data = NULL;
  313. return CMTSuccess;
  314. loser:
  315. return CMTFailure;
  316. }
  317. CMTStatus CMT_ReceiveMessage(PCMT_CONTROL control, CMTItem * response)
  318. {
  319.     CMTMessageHeader header;
  320.     CMUint32 numread;
  321.     /* Get the message header */
  322.     numread = CMT_ReadThisMany(control, control->sock, 
  323.                             (void *)&header, sizeof(CMTMessageHeader));
  324.     if (numread != sizeof(CMTMessageHeader)) {
  325.         goto loser;
  326.     }
  327.     response->type = ntohl(header.type);
  328.     response->len = ntohl(header.len);
  329.     response->data = (unsigned char *) malloc(response->len);
  330.     if (response->data == NULL) {
  331.         goto loser;
  332.     }
  333.     numread = CMT_ReadThisMany(control, control->sock, 
  334.                             (void *)(response->data), response->len); 
  335.     if (numread != response->len) {
  336.         goto loser;
  337.     }
  338. #ifdef PRINT_RECEIVE_MESSAGES
  339.     LOG("About to print message received from PSM.n");
  340.     prettyPrintMessage(response);
  341. #endif /*PRINT_RECEIVE_MESSAGES*/
  342.     return CMTSuccess;
  343. loser:
  344.     if (response->data) {
  345.         free(response->data);
  346.     }
  347.     return CMTFailure;
  348. }
  349. CMUint32 CMT_ReadThisMany(PCMT_CONTROL control, CMTSocket sock, 
  350.                           void * buffer, CMUint32 thisMany)
  351. {
  352. CMUint32 total = 0;
  353.   
  354. while (total < thisMany) {
  355. int got;
  356. got = control->sockFuncs.recv(sock, (void*)((char*)buffer + total),
  357.                                       thisMany-total);
  358. if (got < 0 ) {
  359. break;
  360. total += got;
  361. return total;
  362. }
  363.  
  364. CMUint32 CMT_WriteThisMany(PCMT_CONTROL control, CMTSocket sock, 
  365.                            void * buffer, CMUint32 thisMany)
  366. {
  367. CMUint32 total = 0;
  368.   
  369. while (total < thisMany) {
  370. CMInt32 got;
  371. got = control->sockFuncs.send(sock, (void*)((char*)buffer+total), 
  372.                                       thisMany-total);
  373. if (got < 0) {
  374. break;
  375. }
  376. total += got;
  377. }
  378. return total;
  379. }
  380. CMTItem* CMT_ConstructMessage(CMUint32 type, CMUint32 length)
  381. {
  382.     CMTItem * p;
  383.     p = (CMTItem*)malloc(sizeof(CMTItem));
  384.     if (!p) {
  385. goto loser;
  386.     }
  387.     p->type = type;
  388.     p->len = length;
  389.     p->data = (unsigned char *) malloc(length);
  390.     if (!p->data) {
  391. goto loser;
  392.     }
  393.     return p;
  394. loser:
  395.     CMT_FreeMessage(p);
  396.     return NULL;
  397. }
  398. void CMT_FreeMessage(CMTItem * p)
  399. {
  400.     if (p != NULL) {
  401. if (p->data != NULL) {
  402.     free(p->data);
  403. }
  404. free(p);
  405.     }
  406. }
  407. CMTStatus CMT_AddDataConnection(PCMT_CONTROL control, CMTSocket sock, 
  408.                                 CMUint32 connectionID)
  409. {
  410. PCMT_DATA ptr;
  411. /* This is the first connection */
  412. if (control->cmtDataConnections == NULL) {
  413. control->cmtDataConnections = ptr = 
  414.             (PCMT_DATA)calloc(sizeof(CMT_DATA), 1);
  415. if (!ptr) {
  416. goto loser;
  417. }
  418. } else {
  419.     /* Position at the last entry */
  420.     for (ptr = control->cmtDataConnections; (ptr != NULL && ptr->next 
  421.                                                  != NULL); ptr = ptr->next);
  422. ptr->next = (PCMT_DATA)calloc(sizeof(CMT_DATA), 1);
  423. if (!ptr->next) {
  424. goto loser;
  425. /* Fix up the pointers */
  426. ptr->next->previous = ptr;
  427. ptr = ptr->next;
  428. }
  429. /* Fill in the data */
  430. ptr->sock = sock;
  431. ptr->connectionID = connectionID;
  432. return CMTSuccess;
  433. loser:
  434. return CMTFailure;
  435. }
  436. int
  437. CMT_DestroyDataConnection(PCMT_CONTROL control, CMTSocket sock)
  438. {
  439.     PCMT_DATA ptr, pptr = NULL;
  440.     int rv=CMTSuccess;
  441.     if (!control) return rv;
  442.     control->sockFuncs.close(sock);
  443.     for (ptr = control->cmtDataConnections; ptr != NULL;
  444.  pptr = ptr, ptr = ptr->next) {
  445. if (ptr->sock == sock) {
  446.     if (pptr == NULL) {
  447. /* node is at head */
  448. control->cmtDataConnections = ptr->next;
  449. if (ptr->priv != NULL)
  450.     ptr->priv->dest(ptr->priv);
  451. free(ptr);
  452. return rv;
  453.     }
  454.     /* node is elsewhere */
  455.     pptr->next = ptr->next;
  456.     if (ptr->priv != NULL)
  457.         ptr->priv->dest(ptr->priv);
  458.     free(ptr);
  459.     return rv;
  460. }
  461.     }
  462.     return rv;
  463. }
  464. CMTStatus CMT_CloseDataConnection(PCMT_CONTROL control, CMUint32 connectionID)
  465. {
  466.     /* PCMT_DATA ptr, pptr = NULL; */
  467.     CMTSocket sock;
  468.     /* int rv;*/
  469.     /* Get the socket for this connection */
  470.     if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
  471.         goto loser;
  472.     }
  473.     /* Free data connection associated with this socket */
  474.     if (CMT_DestroyDataConnection(control, sock) == CMTFailure) {
  475.         goto loser;
  476.     }
  477.     return CMTSuccess;
  478. loser:
  479.     return CMTFailure;
  480. }
  481. CMTStatus CMT_GetDataConnectionID(PCMT_CONTROL control, CMTSocket sock, CMUint32 * connectionID)
  482. {
  483. PCMT_DATA ptr;
  484. for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
  485. if (ptr->sock == sock) {
  486. *connectionID = ptr->connectionID;
  487. return CMTSuccess;
  488. }
  489. }
  490. return CMTFailure;
  491. }
  492. CMTStatus CMT_GetDataSocket(PCMT_CONTROL control, CMUint32 connectionID, CMTSocket * sock)
  493. {
  494. PCMT_DATA ptr;
  495. for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
  496. if (ptr->connectionID == connectionID) {
  497. *sock = ptr->sock;
  498. return CMTSuccess;
  499. }
  500. }
  501. return CMTFailure;
  502. }
  503. CMTStatus CMT_SetPrivate(PCMT_CONTROL control, CMUint32 connectionID,
  504.  CMTPrivate *cmtpriv)
  505. {
  506.   PCMT_DATA ptr;
  507.   for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
  508.     if (ptr->connectionID == connectionID) {
  509.       ptr->priv = cmtpriv;
  510.       return CMTSuccess;
  511.     }
  512.   }
  513.   return CMTFailure;
  514. }
  515. CMTPrivate *CMT_GetPrivate(PCMT_CONTROL control, CMUint32 connectionID)
  516. {
  517.   PCMT_DATA ptr;
  518.   for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
  519.     if (ptr->connectionID == connectionID) {
  520.       return ptr->priv;
  521.     }
  522.   }
  523.   return NULL;
  524. }
  525. void CMT_FreeItem(CMTItem *p)
  526. {
  527.   CMT_FreeMessage(p);
  528. }
  529. CMTItem CMT_CopyPtrToItem(void* p)
  530. {
  531.     CMTItem value = {0, NULL, 0};
  532.     if (!p) {
  533.         return value;
  534.     }
  535.     value.len = sizeof(p);
  536.     value.data = (unsigned char *) malloc(value.len);
  537.     memcpy(value.data, &p, value.len);
  538.     return value;
  539. }
  540. void * CMT_CopyItemToPtr(CMTItem value)
  541. {
  542.     void * p = NULL;
  543.     if (value.len == sizeof(void*)) {
  544.         memcpy(&p, value.data, value.len);
  545.     }
  546.     return p;
  547. }
  548. CMTStatus CMT_ReferenceControlConnection(PCMT_CONTROL control)
  549. {    CMT_LOCK(control->mutex);
  550.     control->refCount++;
  551.     CMT_UNLOCK(control->mutex);
  552.     return CMTSuccess;
  553. }
  554. void
  555. CMT_LockConnection(PCMT_CONTROL control)
  556. {
  557.     CMT_LOCK(control->mutex);
  558. }
  559. void
  560. CMT_UnlockConnection(PCMT_CONTROL control)
  561. {
  562.     CMT_UNLOCK(control->mutex);
  563. }