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

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/time.h>
  36. #include <sys/types.h>
  37. #include <sys/socket.h>
  38. #include <netinet/in.h>
  39. #include <sys/stat.h>
  40. #ifndef XP_BEOS
  41. #include <netinet/tcp.h>
  42. #endif
  43. #else
  44. #ifdef XP_MAC
  45. #include <Events.h> // for WaitNextEvent
  46. #else /* Windows */
  47. #include <windows.h>
  48. #include <winsock.h>
  49. #include <direct.h>
  50. #include <sys/stat.h>
  51. #endif
  52. #endif
  53. #include "messages.h"
  54. #include "cmtcmn.h"
  55. #include "cmtutils.h"
  56. #include <string.h>
  57. #if defined(XP_UNIX) || defined(XP_BEOS)
  58. #define DIRECTORY_SEPARATOR '/'
  59. #elif defined(WIN32) || defined(XP_OS2)
  60. #define DIRECTORY_SEPARATOR '\'
  61. #elif defined XP_MAC
  62. #define DIRECTORY_SEPARATOR ':'
  63. #endif
  64. /* Local defines */
  65. #define CARTMAN_PORT 11111
  66. #define MAX_PATH_LEN    256
  67. /* write to the cmnav.log */
  68. #if 0
  69. #define LOG(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { 
  70.    fprintf(f, x); fclose(f); } } while(0);
  71. #define LOG_S(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { 
  72.    fprintf(f, "%s", x); fclose(f); } } while(0);
  73. #define ASSERT(x); if (!(x)) { LOG("ASSERT:"); LOG(#x); LOG("n"); exit(-1); }
  74. #else
  75. #define LOG(x); ;
  76. #define LOG_S(x); ;
  77. #define ASSERT(x); ;
  78. #endif
  79. static char*
  80. getCurrWorkDir(char *buf, int maxLen)
  81. {
  82. #if defined WIN32
  83.     return _getcwd(buf, maxLen);
  84. #elif defined(XP_UNIX) || defined(XP_BEOS)
  85.     return getcwd(buf, maxLen);
  86. #else
  87.     return NULL;
  88. #endif
  89. }
  90. static void
  91. setWorkingDir(char *path)
  92. {
  93. #if defined WIN32
  94.     _chdir(path);
  95. #elif defined(XP_UNIX) || defined(XP_BEOS)
  96.     chdir(path);
  97. #else
  98.     return;
  99. #endif
  100. }
  101. static CMTStatus
  102. launch_psm(char *executable)
  103. {
  104. #ifndef XP_MAC
  105.     char command[MAX_PATH_LEN];
  106. #endif
  107. #ifdef WIN32
  108.     STARTUPINFO sui;
  109.     PROCESS_INFORMATION pi;
  110.     UNALIGNED long *posfhnd;
  111.     int i;
  112.     char *posfile;
  113.     sprintf(command,"%s > psmlog", executable);
  114.     ZeroMemory( &sui, sizeof(sui) );
  115.     sui.cb = sizeof(sui);
  116.     sui.cbReserved2 = (WORD)(sizeof( int ) + (3 * (sizeof( char ) + 
  117.                                                    sizeof( long ))));
  118.     sui.lpReserved2 = calloc( sui.cbReserved2, 1 );
  119.     *((UNALIGNED int *)(sui.lpReserved2)) = 3;
  120.     posfile = (char *)(sui.lpReserved2 + sizeof( int ));
  121.     posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) + 
  122.                                  (3 * sizeof( char )));
  123.     
  124.     for ( i = 0, posfile = (char *)(sui.lpReserved2 + sizeof( int )),
  125.               posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) + (3 * sizeof( char ))) ;
  126.           i < 3 ; i++, posfile++, posfhnd++ ) {
  127.         
  128.         *posfile = 0;
  129.         *posfhnd = (long)INVALID_HANDLE_VALUE;
  130.     }
  131.     /* Now, fire up PSM */
  132.     if (!CreateProcess(NULL, command, NULL, NULL, TRUE, DETACHED_PROCESS, 
  133.                        NULL, NULL, &sui, &pi)) {
  134.         goto loser;
  135.     }
  136.     return CMTSuccess;
  137.  loser:
  138.     return CMTFailure;
  139. #elif defined(XP_UNIX) || defined(XP_BEOS)
  140.     sprintf(command,"./%s &", executable);
  141.     if (system(command) == -1) {
  142.         goto loser;
  143.     }
  144.     return CMTSuccess;
  145.  loser:
  146.     return CMTFailure;
  147. #else
  148.     return CMTFailure;
  149. #endif
  150. }
  151. PCMT_CONTROL CMT_EstablishControlConnection(char            *inPath, 
  152.                                             CMT_SocketFuncs *sockFuncs,
  153.                                             CMT_MUTEX       *mutex)
  154. {
  155.     PCMT_CONTROL control;
  156. #ifndef XP_MAC
  157.     char *executable;
  158.     char *newWorkingDir;
  159.     char oldWorkingDir[MAX_PATH_LEN];
  160.     size_t stringLen;
  161. #endif    
  162.     int i;
  163.     char *path = NULL;
  164.     /* On the Mac, we do special magic in the Seamonkey PSM component, so
  165.      if PSM isn't launched by the time we reach this point, we're not doing well. */
  166. #ifndef XP_MAC
  167.     struct stat stbuf;
  168.     
  169.     /*
  170.      * Create our own copy of path.
  171.      * I'd like to do a straight strdup here, but that caused problems
  172.      * for https.
  173.      */
  174.     stringLen = strlen(inPath);
  175.     path = (char*) malloc(stringLen+1);
  176.     memcpy(path, inPath, stringLen);
  177.     path[stringLen] = '';
  178.     control = CMT_ControlConnect(mutex, sockFuncs);
  179.     if (control != NULL) {
  180.         return control;
  181.     }
  182.     /*
  183.      * We have to try to launch it now, so it better be a valid 
  184.      * path.
  185.      */
  186.     if (stat(path, &stbuf) == -1) {
  187.         goto loser;
  188.     }
  189.     /*
  190.      * Now we have to parse the path and launch the psm server.
  191.      */
  192.     executable = strrchr(path, DIRECTORY_SEPARATOR);
  193.     if (executable != NULL) {
  194.         *executable = '';
  195.         executable ++;
  196.         newWorkingDir = path;
  197.     } else {
  198.         executable = path;
  199.         newWorkingDir = NULL;
  200.     }
  201.     if (getCurrWorkDir(oldWorkingDir, MAX_PATH_LEN) == NULL) {
  202.         goto loser;
  203.     }
  204.     setWorkingDir(newWorkingDir);
  205.     if (launch_psm(executable) != CMTSuccess) {
  206.         goto loser;
  207.     }
  208.     setWorkingDir(oldWorkingDir);
  209. #endif
  210.     /*
  211.      * Now try to connect to the psm server.  We will try to connect
  212.      * a maximum of 30 times and then give up.
  213.      */
  214. #ifdef WIN32
  215.     for (i=0; i<30; i++) {
  216.         Sleep(1000);
  217.         control = CMT_ControlConnect(mutex, sockFuncs);
  218.         if (control != NULL) {
  219.             break;
  220.         }
  221.     }
  222. #elif defined(XP_UNIX) || defined(XP_BEOS)
  223.     i = 0;
  224.     while (i<1000) {
  225.         i += sleep(10);
  226. control = CMT_ControlConnect(mutex, sockFuncs);
  227. if (control != NULL) {
  228.   break;
  229. }
  230.     }
  231. #elif defined(XP_MAC)
  232. for (i=0; i<30; i++) 
  233. {
  234. EventRecord theEvent;
  235. WaitNextEvent(0, &theEvent, 30, NULL);
  236. control = CMT_ControlConnect(mutex, sockFuncs);
  237. if (control != NULL) 
  238. break;
  239. }
  240. #else
  241.     /*
  242.      * Figure out how to sleep for a while first
  243.      */
  244.     for (i=0; i<30; i++) {
  245.       control = CMT_ControlConnect(mutex, sockFuncs);
  246.       if (control!= NULL) {
  247. break;
  248.       }
  249.     }
  250. #endif
  251.     if (control == NULL) {
  252.         goto loser;
  253.     }
  254.     if (path) {
  255.         free (path);
  256.     }
  257.     return control;
  258.  loser:
  259.     if (control != NULL) {
  260.         CMT_CloseControlConnection(control);
  261.     }
  262.     if (path) {
  263.         free(path);
  264.     }
  265.     return NULL;
  266. }
  267. PCMT_CONTROL CMT_ControlConnect(CMT_MUTEX *mutex, CMT_SocketFuncs *sockFuncs)
  268. {
  269.     PCMT_CONTROL control = NULL; 
  270.     CMTSocket sock=NULL;
  271. #ifdef XP_UNIX
  272.     int unixSock = 1;
  273.     char path[20];
  274. #else
  275.     int unixSock = 0;
  276.     char *path=NULL;
  277. #endif
  278.     if (sockFuncs == NULL) {
  279.         return NULL;
  280.     }
  281. #ifdef XP_UNIX
  282.     sprintf(path, "/tmp/.nsmc-%d", (int)geteuid());
  283. #endif    
  284.     sock = sockFuncs->socket(unixSock);
  285.     if (sock == NULL) {
  286.         LOG("Could not create a socket to connect to Control Connection.n");
  287.         goto loser;
  288.     }
  289.     /* Connect to the psm process */
  290.     if (sockFuncs->connect(sock, CARTMAN_PORT, path)) {
  291.   LOG("Could not connect to Cartmann");
  292.   goto loser;
  293.     }
  294. #ifdef XP_UNIX
  295.     if (sockFuncs->verify(sock) != CMTSuccess) {
  296.         goto loser;
  297.     }
  298. #endif
  299. LOG("Connected to Cartmann");
  300. /* fill in the CMTControl struct */
  301. control = (PCMT_CONTROL)calloc(sizeof(CMT_CONTROL), 1);
  302. if (control == NULL ) {
  303. goto loser;
  304. }
  305. control->sock = sock;
  306.     if (mutex != NULL) {
  307.         control->mutex = (CMT_MUTEX*)calloc(sizeof(CMT_MUTEX),1);
  308.         if (control->mutex == NULL) {
  309.             goto loser;
  310.         }
  311.         *control->mutex = *mutex;
  312.     }
  313.     memcpy(&control->sockFuncs, sockFuncs, sizeof(CMT_SocketFuncs));
  314.     control->refCount = 1;
  315. goto done;
  316.     
  317.  loser:
  318. if (control != NULL) {
  319. free(control);
  320.     }
  321.     if (sock != NULL) {
  322.         sockFuncs->close(sock);
  323.     }
  324. control = NULL;
  325.     
  326.  done:
  327. return control;
  328. }
  329. CMTStatus CMT_CloseControlConnection(PCMT_CONTROL control)
  330. {
  331. /* XXX Don't know what to do here yet */
  332.     if (control != NULL) {
  333.         CMInt32 refCount;
  334.         CMT_LOCK(control->mutex);
  335.         control->refCount--;
  336.         refCount = control->refCount;
  337.         CMT_UNLOCK(control->mutex);
  338.         if (refCount <= 0) {
  339.             if (control->mutex != NULL) {
  340.                 free (control->mutex);
  341.             }
  342.             control->sockFuncs.close(control->sock);
  343.             free(control);
  344.         }
  345.     }
  346.     
  347. return CMTSuccess;
  348. }
  349. CMTStatus CMT_Hello(PCMT_CONTROL control, CMUint32 version, char* profile, 
  350.                     char* profileDir)
  351. {
  352. CMTItem message;
  353.     PCMT_EVENT eventHandler;
  354.     CMBool doesUI;
  355.     HelloRequest request;
  356.     HelloReply reply;
  357. /* Check the passed parameters */
  358. if (!control) {
  359. return CMTFailure;
  360. }
  361. if (!profile) {
  362. return CMTFailure;
  363. }
  364.     if (!profileDir) {
  365.         return CMTFailure;
  366.     }
  367.     
  368. /* Create the hello message */
  369.     eventHandler = CMT_GetEventHandler(control, SSM_UI_EVENT, 0);
  370.     doesUI = (eventHandler == NULL) ? CM_FALSE : CM_TRUE;
  371.     /* Setup the request struct */
  372.     request.version = version;
  373.     request.policy = 0; /* no more policy */
  374.     request.doesUI = doesUI;
  375.     request.profile = profile;
  376.     request.profileDir = profileDir;
  377.     message.type = SSM_REQUEST_MESSAGE | SSM_HELLO_MESSAGE;
  378.     if (CMT_EncodeMessage(HelloRequestTemplate, &message, &request) != CMTSuccess) {
  379.         goto loser;
  380.     }
  381. /* Send the message and get the response */
  382. if (CMT_SendMessage(control, &message) != CMTSuccess) {
  383.         goto loser;
  384. }
  385.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_HELLO_MESSAGE)) {
  386.         goto loser;
  387.     }
  388.     /* Decode the message */
  389.     if (CMT_DecodeMessage(HelloReplyTemplate, &reply, &message) != CMTSuccess) {
  390.         goto loser;
  391.     }
  392. /* Successful response */
  393. if (reply.result == 0) {
  394.             /* Save the nonce value */
  395.             control->sessionID = reply.sessionID;
  396.             control->protocolVersion = reply.version;
  397.             control->port = reply.httpPort;
  398.             control->nonce = reply.nonce;
  399.             control->policy = reply.policy;
  400.             control->serverStringVersion = reply.stringVersion;
  401.             /* XXX Free the messages */
  402.             return CMTSuccess;
  403. }
  404. loser:
  405. /* XXX Free the messages */
  406. return CMTFailure;
  407. }
  408. CMTStatus CMT_PassAllPrefs(PCMT_CONTROL control, int num,
  409.                            CMTSetPrefElement* list)
  410. {
  411.     SetPrefListMessage request;
  412.     SingleNumMessage reply;
  413.     CMTItem message;
  414.     if ((control == NULL) || (list == NULL)) {
  415.         return CMTFailure;
  416.     }
  417.     /* pack the request */
  418.     request.length = num;
  419.     request.list = (SetPrefElement*)list;
  420.     if (CMT_EncodeMessage(SetPrefListMessageTemplate, &message, &request) !=
  421.         CMTSuccess) {
  422.         goto loser;
  423.     }
  424.     message.type = SSM_REQUEST_MESSAGE | SSM_PREF_ACTION;
  425.     /* send the message */
  426.     if (CMT_SendMessage(control, &message) != CMTSuccess) {
  427.         goto loser;
  428.     }
  429.     if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PREF_ACTION)) {
  430.         goto loser;
  431.     }
  432.     if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
  433.         CMTSuccess) {
  434.         goto loser;
  435.     }
  436.     /* don't really need to check the return value */
  437.     return CMTSuccess;
  438. loser:
  439.     return CMTFailure;
  440. }
  441. char* CMT_GetServerStringVersion(PCMT_CONTROL control)
  442. {
  443.     if (control == NULL) {
  444.         return NULL;
  445.     }
  446.     return control->serverStringVersion;
  447. }