sslsock.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,856 行 · 第 1/4 页
C
1,856 行
for (policy = ssl_ciphers; policy->cipher != 0; ++policy) { status = SSL_SetPolicy(policy->cipher, policy->export); if (status != SECSuccess) break; } return status;}SECStatusNSS_SetFrancePolicy(void){ SECStatus status = SECSuccess; cipherPolicy * policy; for (policy = ssl_ciphers; policy->cipher != 0; ++policy) { status = SSL_SetPolicy(policy->cipher, policy->france); if (status != SECSuccess) break; } return status;}/* LOCKS ??? XXX */PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd){ sslSocket * ns = NULL; PRStatus rv; if (model == NULL) { /* Just create a default socket if we're given NULL for the model */ ns = ssl_NewSocket(); } else { sslSocket * ss = ssl_FindSocket(model); if (ss == NULL) { SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD", SSL_GETPID(), model)); SET_ERROR_CODE return NULL; } ns = ssl_DupSocket(ss); } if (ns == NULL) return NULL; rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER); if (rv != PR_SUCCESS) { ssl_FreeSocket(ns); SET_ERROR_CODE return NULL; }#ifdef _WIN32 PR_Sleep(PR_INTERVAL_NO_WAIT); /* workaround NT winsock connect bug. */#endif return fd;}/************************************************************************//* The following functions are the TOP LEVEL SSL functions.** They all get called through the NSPRIOMethods table below.*/static PRFileDesc * PR_CALLBACKssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout){ sslSocket *ss; sslSocket *ns = NULL; PRFileDesc *newfd = NULL; PRFileDesc *osfd; PRStatus status; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in accept", SSL_GETPID(), fd)); return NULL; } /* IF this is a listen socket, there shouldn't be any I/O going on */ SSL_LOCK_READER(ss); SSL_LOCK_WRITER(ss); ssl_Get1stHandshakeLock(ss); ssl_GetSSL3HandshakeLock(ss); ss->cTimeout = timeout; osfd = ss->fd->lower; /* First accept connection */ newfd = osfd->methods->accept(osfd, sockaddr, timeout); if (newfd == NULL) { SSL_DBG(("%d: SSL[%d]: accept failed, errno=%d", SSL_GETPID(), ss->fd, PORT_GetError())); } else { /* Create ssl module */ ns = ssl_DupSocket(ss); } ssl_ReleaseSSL3HandshakeLock(ss); ssl_Release1stHandshakeLock(ss); SSL_UNLOCK_WRITER(ss); SSL_UNLOCK_READER(ss); /* ss isn't used below here. */ if (ns == NULL) goto loser; /* push ssl module onto the new socket */ status = ssl_PushIOLayer(ns, newfd, PR_TOP_IO_LAYER); if (status != PR_SUCCESS) goto loser; /* Now start server connection handshake with client. ** Don't need locks here because nobody else has a reference to ns yet. */ if ( ns->useSecurity ) { if ( ns->handshakeAsClient ) { ns->handshake = ssl2_BeginClientHandshake; } else { ns->handshake = ssl2_BeginServerHandshake; } } return newfd;loser: if (ns != NULL) ssl_FreeSocket(ns); if (newfd != NULL) PR_Close(newfd); return NULL;}static PRStatus PR_CALLBACKssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout){ sslSocket *ss; PRStatus rv; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in connect", SSL_GETPID(), fd)); return PR_FAILURE; } /* IF this is a listen socket, there shouldn't be any I/O going on */ SSL_LOCK_READER(ss); SSL_LOCK_WRITER(ss); ss->cTimeout = timeout; rv = (PRStatus)(*ss->ops->connect)(ss, sockaddr);#ifdef _WIN32 PR_Sleep(PR_INTERVAL_NO_WAIT); /* workaround NT winsock connect bug. */#endif SSL_UNLOCK_WRITER(ss); SSL_UNLOCK_READER(ss); return rv;}static PRStatus PR_CALLBACKssl_Bind(PRFileDesc *fd, const PRNetAddr *addr){ sslSocket * ss = ssl_GetPrivate(fd); PRStatus rv; if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd)); return PR_FAILURE; } SSL_LOCK_READER(ss); SSL_LOCK_WRITER(ss); rv = (PRStatus)(*ss->ops->bind)(ss, addr); SSL_UNLOCK_WRITER(ss); SSL_UNLOCK_READER(ss); return rv;}static PRStatus PR_CALLBACKssl_Listen(PRFileDesc *fd, PRIntn backlog){ sslSocket * ss = ssl_GetPrivate(fd); PRStatus rv; if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd)); return PR_FAILURE; } SSL_LOCK_READER(ss); SSL_LOCK_WRITER(ss); rv = (PRStatus)(*ss->ops->listen)(ss, backlog); SSL_UNLOCK_WRITER(ss); SSL_UNLOCK_READER(ss); return rv;}static PRStatus PR_CALLBACKssl_Shutdown(PRFileDesc *fd, PRIntn how){ sslSocket * ss = ssl_GetPrivate(fd); PRStatus rv; if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd)); return PR_FAILURE; } if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) { SSL_LOCK_READER(ss); } if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) { SSL_LOCK_WRITER(ss); } rv = (PRStatus)(*ss->ops->shutdown)(ss, how); if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) { SSL_UNLOCK_WRITER(ss); } if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) { SSL_UNLOCK_READER(ss); } return rv;}static PRStatus PR_CALLBACKssl_Close(PRFileDesc *fd){ sslSocket *ss; PRStatus rv; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in close", SSL_GETPID(), fd)); return PR_FAILURE; } /* There must not be any I/O going on */ SSL_LOCK_READER(ss); SSL_LOCK_WRITER(ss); /* By the time this function returns, ** ss is an invalid pointer, and the locks to which it points have ** been unlocked and freed. So, this is the ONE PLACE in all of SSL ** where the LOCK calls and the corresponding UNLOCK calls are not in ** the same function scope. The unlock calls are in ssl_FreeSocket(). */ rv = (PRStatus)(*ss->ops->close)(ss); return rv;}static int PR_CALLBACKssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags, PRIntervalTime timeout){ sslSocket *ss; int rv; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in recv", SSL_GETPID(), fd)); return SECFailure; } SSL_LOCK_READER(ss); ss->rTimeout = timeout; rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags); SSL_UNLOCK_READER(ss); return rv;}static int PR_CALLBACKssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags, PRIntervalTime timeout){ sslSocket *ss; int rv; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in send", SSL_GETPID(), fd)); return SECFailure; } SSL_LOCK_WRITER(ss); ss->wTimeout = timeout; rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags); SSL_UNLOCK_WRITER(ss); return rv;}static int PR_CALLBACKssl_Read(PRFileDesc *fd, void *buf, PRInt32 len){ sslSocket *ss; int rv; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in read", SSL_GETPID(), fd)); return SECFailure; } SSL_LOCK_READER(ss); ss->rTimeout = PR_INTERVAL_NO_TIMEOUT; rv = (*ss->ops->read)(ss, (unsigned char*)buf, len); SSL_UNLOCK_READER(ss); return rv;}static int PR_CALLBACKssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len){ sslSocket *ss; int rv; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in write", SSL_GETPID(), fd)); return SECFailure; } SSL_LOCK_WRITER(ss); ss->wTimeout = PR_INTERVAL_NO_TIMEOUT; rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len); SSL_UNLOCK_WRITER(ss); return rv;}static PRStatus PR_CALLBACKssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr){ sslSocket *ss; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in getpeername", SSL_GETPID(), fd)); return PR_FAILURE; } return (PRStatus)(*ss->ops->getpeername)(ss, addr);}/*** XXX this code doesn't work properly inside a Socks server.*/SECStatusssl_GetPeerInfo(sslSocket *ss){ sslConnectInfo * ci; PRNetAddr sin; int rv; PRFileDesc * osfd; PORT_Assert((ss->sec != 0)); osfd = ss->fd->lower; ci = &ss->sec->ci; /* If ssl_SocksConnect() has previously recorded the peer's IP & port, * use that. */ if ((ss->port != 0) && ((ss->peer.pr_s6_addr32[0] != 0) || (ss->peer.pr_s6_addr32[1] != 0) || (ss->peer.pr_s6_addr32[2] != 0) || (ss->peer.pr_s6_addr32[3] != 0))) { /* SOCKS code has already recorded the peer's IP addr and port. * (NOT the proxy's addr and port) in ss->peer & port. */ ci->peer = ss->peer; ci->port = ss->port; return SECSuccess; } PORT_Memset(&sin, 0, sizeof(sin)); rv = osfd->methods->getpeername(osfd, &sin); if (rv < 0) { return SECFailure; } /* we have to mask off the high byte because AIX is lame */ if ((sin.inet.family & 0xff) == PR_AF_INET) { PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ci->peer); ci->port = sin.inet.port; } else { PORT_Assert(sin.ipv6.family == PR_AF_INET6); ci->peer = sin.ipv6.ip; ci->port = sin.ipv6.port; } return SECSuccess;}static PRStatus PR_CALLBACKssl_GetSockName(PRFileDesc *fd, PRNetAddr *name){ sslSocket *ss; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in getsockname", SSL_GETPID(), fd)); return PR_FAILURE; } return (PRStatus)(*ss->ops->getsockname)(ss, name);}int PR_CALLBACKSSL_SetSockPeerID(PRFileDesc *fd, char *peerID){ sslSocket *ss; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCacheIndex", SSL_GETPID(), fd)); return SECFailure; } ss->peerID = PORT_Strdup(peerID); return 0;}static PRInt16 PR_CALLBACKssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *out_flags){ sslSocket *ss; PRInt16 ret_flags = how_flags; /* should select on these flags. */ *out_flags = 0; ss = ssl_GetPrivate(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in SSL_Poll", SSL_GETPID(), fd)); return 0; /* don't poll on this socket */ } if ((ret_flags & PR_POLL_WRITE) && ( (ss->useSocks && ss->handshake) || (ss->useSecurity && !ss->connected && /* XXX There needs to be a better test than the following. */ /* Don't check ss->securityHandshake. */ (ss->handshake || ss->nextHandshake)))) { /* The user is trying to write, but the handshake is blocked waiting * to read, so tell NSPR NOT to poll on write. */ ret_flags ^= PR_POLL_WRITE; /* don't select on write. */ ret_flags |= PR_POLL_READ; /* do select on read. */ } if ((ret_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) { *out_flags = PR_POLL_READ; /* it's ready already. */ } else if (ret_flags && (fd->lower->methods->poll != NULL)) { ret_flags = fd->lower->methods->poll(fd->lower, ret_flags, out_flags); } return ret_flags;}PRBoolssl_FdIsBlocking(PRFileDesc *fd){ PRSocketOptionData opt; PRStatus status; opt.option = PR_SockOpt_Nonblocking;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?