strsclnt.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,128 行 · 第 1/2 页
C
1,128 行
PR_Lock(lv->lock); rv = lv->count += addend; if (rv <= 0) { PR_NotifyCondVar(lv->condVar); } PR_Unlock(lv->lock); return rv;}intdo_writes( void * a, void * b, int c){ PRFileDesc * ssl_sock = (PRFileDesc *)a; lockedVars * lv = (lockedVars *)b; int sent = 0; int count = 0; while (sent < bigBuf.len) { count = PR_Write(ssl_sock, bigBuf.data + sent, bigBuf.len - sent); if (count < 0) { errWarn("PR_Write bigBuf"); break; } FPRINTF(stderr, "strsclnt: PR_Write wrote %d bytes from bigBuf\n", count ); sent += count; } if (count >= 0) { /* last write didn't fail. */ PR_Shutdown(ssl_sock, PR_SHUTDOWN_SEND); } /* notify the reader that we're done. */ lockedVars_AddToCount(lv, -1); return (sent < bigBuf.len) ? SECFailure : SECSuccess;}int handle_fdx_connection( PRFileDesc * ssl_sock, int connection){ SECStatus result; int firstTime = 1; int countRead = 0; lockedVars lv; char *buf; lockedVars_Init(&lv); lockedVars_AddToCount(&lv, 1); /* Attempt to launch the writer thread. */ result = launch_thread(do_writes, ssl_sock, &lv, connection); if (result != SECSuccess) goto cleanup; buf = PR_Malloc(RD_BUF_SIZE); if (buf) { do { /* do reads here. */ PRInt32 count; count = PR_Read(ssl_sock, buf, RD_BUF_SIZE); if (count < 0) { errWarn("PR_Read"); break; } countRead += count; FPRINTF(stderr, "strsclnt: connection %d read %d bytes (%d total).\n", connection, count, countRead ); if (firstTime) { firstTime = 0; printSecurityInfo(ssl_sock); } } while (lockedVars_AddToCount(&lv, 0) > 0); PR_Free(buf); buf = 0; } /* Wait for writer to finish */ lockedVars_WaitForDone(&lv); lockedVars_Destroy(&lv); FPRINTF(stderr, "strsclnt: connection %d read %d bytes total. -----------------------\n", connection, countRead);cleanup: /* Caller closes the socket. */ return SECSuccess;}const char request[] = {"GET /abc HTTP/1.0\r\n\r\n" };SECStatushandle_connection( PRFileDesc *ssl_sock, int connection){ int countRead = 0; PRInt32 rv; char *buf; buf = PR_Malloc(RD_BUF_SIZE); if (!buf) return SECFailure; /* compose the http request here. */ rv = PR_Write(ssl_sock, request, strlen(request)); if (rv <= 0) { errWarn("PR_Write"); PR_Free(buf); buf = 0; return SECFailure; } printSecurityInfo(ssl_sock); /* read until EOF */ while (1) { rv = PR_Read(ssl_sock, buf, RD_BUF_SIZE); if (rv == 0) { break; /* EOF */ } if (rv < 0) { errWarn("PR_Read"); break; } countRead += rv; FPRINTF(stderr, "strsclnt: connection %d read %d bytes (%d total).\n", connection, rv, countRead ); } PR_Free(buf); buf = 0; /* Caller closes the socket. */ FPRINTF(stderr, "strsclnt: connection %d read %d bytes total. -----------------------\n", connection, countRead); return SECSuccess; /* success */}/* one copy of this function is launched in a separate thread for each** connection to be made.*/intdo_connects( void * a, void * b, int connection){ PRNetAddr * addr = (PRNetAddr *) a; PRFileDesc * model_sock = (PRFileDesc *) b; PRFileDesc * ssl_sock = 0; PRFileDesc * tcp_sock = 0; PRStatus prStatus; SECStatus result; int rv = SECSuccess; PRSocketOptionData opt;retry: tcp_sock = PR_NewTCPSocket(); if (tcp_sock == NULL) { errExit("PR_NewTCPSocket"); } opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_FALSE; prStatus = PR_SetSocketOption(tcp_sock, &opt); if (prStatus != PR_SUCCESS) { PR_Close(tcp_sock); return SECSuccess; } prStatus = PR_Connect(tcp_sock, addr, PR_INTERVAL_NO_TIMEOUT); if (prStatus != PR_SUCCESS) { PRErrorCode err = PR_GetError(); if ((err == PR_CONNECT_REFUSED_ERROR) || (err == PR_CONNECT_RESET_ERROR) ) { PR_Close(tcp_sock); PR_Sleep(PR_MillisecondsToInterval(10)); goto retry; } errWarn("PR_Connect"); rv = SECFailure; goto done; } ssl_sock = SSL_ImportFD(model_sock, tcp_sock); /* XXX if this import fails, close tcp_sock and return. */ if (!ssl_sock) { PR_Close(tcp_sock); return SECSuccess; } rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 0); if (rv != SECSuccess) { errWarn("SSL_ResetHandshake"); goto done; } if (bigBuf.data != NULL) { result = handle_fdx_connection( ssl_sock, connection); } else { result = handle_connection( ssl_sock, connection); }done: if (ssl_sock) { PR_Close(ssl_sock); } else if (tcp_sock) { PR_Close(tcp_sock); } return SECSuccess;}/* Returns IP address for hostname as PRUint32 in Host Byte Order.** Since the value returned is an integer (not a string of bytes), ** it is inherently in Host Byte Order. */PRUint32getIPAddress(const char * hostName) { const unsigned char *p; PRStatus prStatus; PRUint32 rv; PRHostEnt prHostEnt; char scratch[PR_NETDB_BUF_SIZE]; prStatus = PR_GetHostByName(hostName, scratch, sizeof scratch, &prHostEnt); if (prStatus != PR_SUCCESS) errExit("PR_GetHostByName");#undef h_addr#define h_addr h_addr_list[0] /* address, for backward compatibility */ p = (const unsigned char *)(prHostEnt.h_addr); /* in Network Byte order */ FPRINTF(stderr, "strsclnt: %s -> %d.%d.%d.%d\n", hostName, p[0], p[1], p[2], p[3]); rv = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; return rv;}voidclient_main( unsigned short port, int connections, SECKEYPrivateKey ** privKey, CERTCertificate ** cert, const char * hostName, char * nickName){ PRFileDesc *model_sock = NULL; int i; int rv; PRUint32 ipAddress; /* in host byte order */ PRNetAddr addr; networkStart(); /* Assemble NetAddr struct for connections. */ ipAddress = getIPAddress(hostName); addr.inet.family = PR_AF_INET; addr.inet.port = PR_htons(port); addr.inet.ip = PR_htonl(ipAddress); /* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */ NSS_SetDomesticPolicy();/* all the SSL2 and SSL3 cipher suites are enabled by default. */ if (cipherString) { int ndx; /* disable all the ciphers, then enable the ones we want. */ disableSSL2Ciphers(); disableSSL3Ciphers(); while (0 != (ndx = *cipherString++)) { int *cptr; int cipher; if (! isalpha(ndx)) Usage("strsclnt"); cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites; for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) /* do nothing */; if (cipher) { SECStatus rv; rv = SSL_EnableCipher(cipher, SSL_ALLOWED); if (rv != SECSuccess) { fprintf(stderr, "strsclnt: SSL_EnableCipher failed with value 0x%04x\n", cipher); exit(1); } } } } /* configure model SSL socket. */ model_sock = PR_NewTCPSocket(); if (model_sock == NULL) { errExit("PR_NewTCPSocket on model socket"); } model_sock = SSL_ImportFD(NULL, model_sock); if (model_sock == NULL) { errExit("SSL_ImportFD"); } /* do SSL configuration. */ rv = SSL_Enable(model_sock, SSL_SECURITY, 1); if (rv < 0) { errExit("SSL_Enable SSL_SECURITY"); } if (bigBuf.data) { /* doing FDX */ rv = SSL_Enable(model_sock, SSL_ENABLE_FDX, 1); if (rv < 0) { errExit("SSL_Enable SSL_ENABLE_FDX"); } } SSL_SetURL(model_sock, hostName); SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, (void *)CERT_GetDefaultCertDB()); SSL_BadCertHook(model_sock, myBadCertHandler, NULL); SSL_GetClientAuthDataHook(model_sock, NSS_GetClientAuthData, nickName); /* I'm not going to set the HandshakeCallback function. */ /* end of ssl configuration. */ rv = launch_thread(do_connects, &addr, model_sock, 1); if (connections > 1) { /* wait for the first connection to terminate, then launch the rest. */ reap_threads(); /* Start up the connections */ for (i = 2; i <= connections; ++i) { rv = launch_thread(do_connects, &addr, model_sock, i); } } reap_threads(); destroy_thread_data(); PR_Close(model_sock); networkEnd();}SECStatusreadBigFile(const char * fileName){ PRFileInfo info; PRStatus status; SECStatus rv = SECFailure; int count; int hdrLen; PRFileDesc *local_file_fd = NULL; status = PR_GetFileInfo(fileName, &info); if (status == PR_SUCCESS && info.type == PR_FILE_FILE && info.size > 0 && NULL != (local_file_fd = PR_Open(fileName, PR_RDONLY, 0))) { hdrLen = PORT_Strlen(outHeader); bigBuf.len = hdrLen + info.size; bigBuf.data = PORT_Malloc(bigBuf.len + 4095); if (!bigBuf.data) { errWarn("PORT_Malloc"); goto done; } PORT_Memcpy(bigBuf.data, outHeader, hdrLen); count = PR_Read(local_file_fd, bigBuf.data + hdrLen, info.size); if (count != info.size) { errWarn("PR_Read local file"); goto done; } rv = SECSuccess;done: PR_Close(local_file_fd); } return rv;}intmain(int argc, char **argv){ const char * dir = "."; char * fNickName = NULL; const char * fileName = NULL; char * hostName = NULL; char * nickName = NULL; char * progName = NULL; char * tmp = NULL; char * passwd = NULL; CERTCertificate * cert [kt_kea_size] = { NULL }; SECKEYPrivateKey * privKey[kt_kea_size] = { NULL }; int connections = 1; int exitVal; unsigned short port = 443; SECStatus rv; PLOptState * optstate; PLOptStatus status; /* Call the NSPR initialization routines */ PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); tmp = strrchr(argv[0], '/'); tmp = tmp ? tmp + 1 : argv[0]; progName = strrchr(tmp, '\\'); progName = progName ? progName + 1 : tmp; optstate = PL_CreateOptState(argc, argv, "2:C:c:d:f:n:op:vw:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch(optstate->option) { case '2': fileName = optstate->value; break; case 'C': cipherString = optstate->value; break; case 'c': connections = PORT_Atoi(optstate->value); break; case 'd': dir = optstate->value; break; case 'f': fNickName = optstate->value; break; case 'n': nickName = optstate->value; break; case 'o': MakeCertOK = 1; break; case 'p': port = PORT_Atoi(optstate->value); break; case 'v': verbose++; break; case 'w': passwd = optstate->value; break; case '\0': hostName = PL_strdup(optstate->value); break; default: case '?': Usage(progName); break; } } if (!hostName || status == PL_OPT_BAD) Usage(progName); if (port == 0) Usage(progName); if (fileName) readBigFile(fileName); /* set our password function */ if ( passwd ) { PK11_SetPasswordFunc(ownPasswd); } else { PK11_SetPasswordFunc(SECU_GetModulePassword); } /* Call the libsec initialization routines */ rv = NSS_Init(dir); if (rv != SECSuccess) { fputs("NSS_Init failed.\n", stderr); exit(1); } if (nickName) { cert[kt_rsa] = PK11_FindCertFromNickname(nickName, passwd); if (cert[kt_rsa] == NULL) { fprintf(stderr, "strsclnt: Can't find certificate %s\n", nickName); exit(1); } privKey[kt_rsa] = PK11_FindKeyByAnyCert(cert[kt_rsa], passwd); if (privKey[kt_rsa] == NULL) { fprintf(stderr, "strsclnt: Can't find Private Key for cert %s\n", nickName); exit(1); } } if (fNickName) { cert[kt_fortezza] = PK11_FindCertFromNickname(fNickName, passwd); if (cert[kt_fortezza] == NULL) { fprintf(stderr, "strsclnt: Can't find certificate %s\n", fNickName); exit(1); } privKey[kt_fortezza] = PK11_FindKeyByAnyCert(cert[kt_fortezza], passwd); if (privKey[kt_fortezza] == NULL) { fprintf(stderr, "strsclnt: Can't find Private Key for cert %s\n", fNickName); exit(1); } } client_main(port, connections, privKey, cert, hostName, nickName); /* some final stats. */ if (ssl3_hsh_sid_cache_hits + ssl3_hsh_sid_cache_misses + ssl3_hsh_sid_cache_not_ok == 0) { /* presumably we were testing SSL2. */ printf("strsclnt: %d server certificates tested.\n", certsTested); } else { printf( "strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n", ssl3_hsh_sid_cache_hits, ssl3_hsh_sid_cache_misses, ssl3_hsh_sid_cache_not_ok); } exitVal = (ssl3_hsh_sid_cache_misses > 1) || (ssl3_hsh_sid_cache_not_ok != 0) || (certsTested > 1); NSS_Shutdown(); PR_Cleanup(); return exitVal;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?