📄 servutil.c
字号:
if (tmp2) PR_smprintf_free(tmp2); if (timeStamp) PR_smprintf_free(timeStamp); PR_ExitMonitor(logSocketLock);#endif}#ifdef DEBUGvoidSSM_InitLogging(void){ char *suppressConsole = NULL; char *debugFile = NULL; /* Create the condition variable we use to control logging. */ if (!(logSocketLock = PR_NewMonitor())) goto loser; if (!(logSockets = SSM_NewCollection())) goto loser; suppressConsole = PR_GetEnv(SSM_ENV_SUPPRESS_CONSOLE); debugFile = PR_GetEnv(SSM_ENV_LOG_FILE); if (!suppressConsole) { PRFileDesc *stdfd = PR_GetSpecialFD(PR_StandardOutput); if (!stdfd) stdfd = PR_GetSpecialFD(PR_StandardError); if (stdfd) SSM_AddLogSocket(stdfd); } if (debugFile) { PRFileDesc *fd = PR_Open(debugFile, PR_WRONLY | PR_APPEND | PR_CREATE_FILE | PR_SYNC, 0644); if (fd) SSM_AddLogSocket(fd); } SSM_DEBUG("Started logging.\n"); return; loser: fprintf(stderr, "Can't initialize logging! Exiting.\n"); exit(1);}#endifSSMStatus SSM_SendQMessage(SSMCollection *q, PRIntn priority, PRIntn type, PRIntn length, char *data, PRBool doBlock){ SECItem *n = NULL; unsigned char *c = NULL; SSMStatus rv = PR_FAILURE; PR_ASSERT(priority != SSM_PRIORITY_ANY);#ifdef DEBUG_QUEUES SSM_DEBUG("SendQMessage on %lx: prio %d, type %lx, len %d\n", (unsigned long) q, priority, (unsigned long) type, length);#endif /* Create a new message. */ n = (SECItem *) PORT_ZAlloc(sizeof(SECItem)); if (!n) goto loser; if (data && length > 0) { c = (unsigned char *) PORT_ZAlloc(length); if (!c) goto loser; memcpy(c, data, length); } n->type = (SECItemType) type; n->len = length; n->data = c; /* ### mwelch We'll want to put a throttle here when we start really securing PSM. It's currently possible for someone to make us run out of memory very quickly by flooding us with data. */ /* Put the msg in the queue. */ SSM_Enqueue(q, priority, n); return PR_SUCCESS;loser: if (n) PORT_Free(n); if (c) PORT_Free(c); return rv;}SSMStatus SSM_RecvQMessage(SSMCollection *q, PRIntn priority, PRIntn *type, PRIntn *length, char **data, PRBool doBlock){ SECItem *p; void *v;#ifdef DEBUG_QUEUES SSM_DEBUG("RecvQMessage on %lx: %s read at prio %d\n", (unsigned long) q, (doBlock ? "blocking" : "nonblocking"), priority);#endif /* Remove the item at the head of the queue. */ SSM_Dequeue(q, priority, &v, doBlock); p = (SECItem *) v; if (!p) return PR_FAILURE; /* Strip out the items. */ *data = (char *)p->data; *length = p->len; *type = p->type; #ifdef DEBUG_QUEUES SSM_DEBUG("RecvQMessage on %lx: type %lx, len %d\n", (unsigned long) q, (unsigned long) *type, *length);#endif /* Free the containing SECItem. */ PORT_Free(p); return PR_SUCCESS;}SSMStatusSSM_SECItemToSSMString(void ** ssmstring, SECItem * data){ SSMString * result = NULL; if (!ssmstring || !data || data->len <= 0 ) goto loser; *ssmstring = NULL; /* in case we fail */ result = (SSMString *) SSMPORT_ZAlloc(sizeof(data->len) + SSMSTRING_PADDED_LENGTH(data->len)); if (!result) goto loser; memcpy((char *)(&(result->m_data)), data->data, data->len); result->m_length = data->len; *ssmstring = result; return PR_SUCCESS;loser: if (result) PR_Free(result); return PR_FAILURE;}SSMStatusSSM_CopyCMTItem(CMTItem * dest, CMTItem * source){ SSMStatus rv = SSM_FAILURE; if (!dest || !source) goto loser; dest->len = source->len; if (!dest->len) goto done; dest->data = (unsigned char *) PR_Malloc(dest->len); if (!dest->data) goto loser; memcpy(dest->data, source->data, dest->len); done: rv = SSM_SUCCESS; loser: return rv;}PRFileDesc * SSM_OpenControlPort(void){ PRFileDesc * datasocket = NULL; PRNetAddr servaddr; SSMStatus status; PRSocketOptionData sockOpData;#ifdef XP_UNIX char lock_name_buf[32];#endif /* disable Nagle algorithm delay for control sockets */ sockOpData.option = PR_SockOpt_NoDelay; sockOpData.value.no_delay = PR_TRUE;#ifdef XP_UNIX GET_LOCK_FILE_PATH(lock_name_buf); lockfile = PR_Open(lock_name_buf, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 0600); if (!lockfile) goto loser; status = PR_TLockFile(lockfile); if (status != PR_SUCCESS) goto loser; datasocket = PR_Socket(AF_UNIX, SOCK_STREAM, 0); if (!datasocket) goto loser; servaddr.local.family = AF_UNIX; GET_CONTROL_SOCK_PATH(servaddr.local.path); PR_Delete(servaddr.local.path);#else datasocket = PR_NewTCPSocket(); if (!datasocket) goto loser; status = PR_SetSocketOption(datasocket, &sockOpData); if (status != PR_SUCCESS) { goto loser; } /* Bind to local port */ status = PR_InitializeNetAddr(PR_IpAddrAny, (PRUint16) PSM_PORT, &servaddr); if (status != PR_SUCCESS) goto loser;#endif status = PR_Bind(datasocket, &servaddr); if (status != PR_SUCCESS) goto loser; status = PR_Listen(datasocket, MAX_CONNECTIONS); if (status != PR_SUCCESS) goto loser;#ifdef XP_UNIX SSM_DEBUG("Ready for client connection on port %s.\n", servaddr.local.path);#else SSM_DEBUG("Ready for client connection on port %d.\n", PSM_PORT);#endif return datasocket; loser: return NULL;}/* Make sure that the peer is on the same machine that we are */PRBoolSSM_SocketPeerCheck(PRFileDesc *sock, PRBool isCtrl){ PRBool rv = PR_FALSE; SSMStatus st = PR_SUCCESS; PRNetAddr theirAddr; char localaddr[] = {0x7F,0x00,0x00,0x01};/* 127.0.0.1 in network order */#if defined(XP_UNIX) || defined(XP_MAC)#ifdef XP_UNIX if (isCtrl) { /* unix domain socket == same machine */ /* ### mwelch Well, the only time this isn't true is when one wants to join many unix machines in a cluster, but even in that case the cluster should be treated as a single machine anyway. */#endif /* GetPeerName isn't implemented on the Mac, so say yes and hope for now ### mwelch - Need to implement GetPeerName in Mac NSPR before Mac PSM RTM */ rv = PR_TRUE; goto done;#ifdef XP_UNIX }#endif#endif st = PR_GetPeerName(sock, &theirAddr); if (st != PR_SUCCESS) goto done; /* default is to fail */ /* Compare against localhost IP */ if (!memcmp(&(theirAddr.inet.ip), localaddr, 4)) rv = PR_TRUE; if (rv != PR_TRUE) SSM_DEBUG("Failed IP address check!\n"); done: return rv;}PRFileDesc * SSM_OpenPort(void){ PRFileDesc * datasocket = NULL; PRNetAddr servaddr; SSMStatus status; PRSocketOptionData sockOpData; /* disable Nagle algorithm delay for data sockets */ sockOpData.option = PR_SockOpt_NoDelay; sockOpData.value.no_delay = PR_TRUE; datasocket = PR_NewTCPSocket(); if (!datasocket) goto loser; status = PR_SetSocketOption(datasocket, &sockOpData); if (status != PR_SUCCESS) { goto loser; } /* Bind to local port */ status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &servaddr); if (status != PR_SUCCESS) goto loser; status = PR_Bind(datasocket, &servaddr); if (status != PR_SUCCESS) goto loser; status = PR_Listen(datasocket, MAX_CONNECTIONS); if (status != PR_SUCCESS) goto loser; return datasocket; loser: return NULL;}#if 0/* Whee. Base 64 decoding. Have to do it for basic authentication. */#define XX 127/* * Table for decoding base64. We have this everywhere else, why not here. */static char index64[256] = { XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63, 52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,XX,XX,XX, XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX, XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,};#ifdef XP_OS2_HACK/* DSR102196 - there are problems when optimizing the macro (/O+ on CSD4) with the OS/2 Visual Age compiler*/char CHAR64(int c){ unsigned char index; char rc; index = (unsigned char) c; rc = index64[index]; return rc;} #else /*normal code...*/#define CHAR64(c) (index64[(unsigned char)(c)])#endif/* Decode a base 64 string in place. */void decode_base64_string(char *str){ char *s = str; char *d = str; char c[4]; PRIntn i; PRBool done = PR_FALSE; while((!done) && (*s)) { /* Process 4 bytes at a time. */ for(i=0;i<4;i++) c[i] = 0; for(i=0;i<4;i++) { if ((IS_WHITESPACE(*s)) || (IS_EOL(*s))) { /* End here, because we're out of bytes. */ done = PR_TRUE; } else c[i] = *s++; } /* Make sure we can at least decode one character. */ if ((!done) && ((c[0] == '=') || (c[1] == '='))) done = PR_TRUE; /* don't even have enough for one character, leave */ if (!done) { /* Decode the first character. */ c[0] = CHAR64(c[0]); c[1] = CHAR64(c[1]); *d++ = ((c[0]<<2) | ((c[1] & 0x30)>>4)); /* If we have data for a second character, decode that. */ if (c[2] != '=') { c[2] = CHAR64(c[2]); *d++ = (((c[1] & 0x0F) << 4) | ((c[2] & 0x3C) >> 2)); /* If we have data for a third character, decode that. */ if (c[3] != '=') { c[3] = CHAR64(c[3]); *d++ = (((c[2] & 0x03) << 6) | c[3]); } else done = PR_TRUE; } else done = PR_TRUE; } } /* Terminate the string. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -