static PRFileDesc *PushNewLayers(PRFileDesc *stack) { PRDescIdentity tmp_identity; PRFileDesc *layer; PRStatus rv; /* push a dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 1"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push a data procesing layer */ layer = PR_CreateIOLayerStub(identity, &myMethods); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push another dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 2"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); return stack; } /* PushLayer */
static bool _check_init(){ if(PR_INVALID_IO_LAYER == _udpt_desc_identity) { udt_startup(); _udpt_desc_identity = PR_GetUniqueIdentity("udptransport"); } return true; }
static void Initialize() { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); static bool initialized = false; if (initialized) { return; } nsNamedPipeLayerIdentity = PR_GetUniqueIdentity("Named Pipe layer"); nsNamedPipeLayerMethods = *PR_GetDefaultIOMethods(); nsNamedPipeLayerMethods.close = nsNamedPipeClose; nsNamedPipeLayerMethods.read = nsNamedPipeRead; nsNamedPipeLayerMethods.write = nsNamedPipeWrite; nsNamedPipeLayerMethods.available = nsNamedPipeAvailable; nsNamedPipeLayerMethods.available64 = nsNamedPipeAvailable64; nsNamedPipeLayerMethods.fsync = nsNamedPipeSync; nsNamedPipeLayerMethods.connect = nsNamedPipeConnect; nsNamedPipeLayerMethods.recv = nsNamedPipeRecv; nsNamedPipeLayerMethods.send = nsNamedPipeSend; nsNamedPipeLayerMethods.poll = nsNamedPipePoll; nsNamedPipeLayerMethods.getsocketoption = nsNamedPipeGetSocketOption; nsNamedPipeLayerMethods.setsocketoption = nsNamedPipeSetSocketOption; nsNamedPipeLayerMethods.connectcontinue = nsNamedPipeConnectContinue; initialized = true; }
static void ssl_nss_init_nss(void) { #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) SSLVersionRange supported, enabled; #endif /* NSS >= 3.14 */ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); NSS_NoDB_Init("."); NSS_SetDomesticPolicy(); SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_256_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_RC4_128_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_RSA_WITH_RC4_128_SHA, 1); SSL_CipherPrefSetDefault(TLS_RSA_WITH_AES_128_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_RSA_WITH_DES_CBC_SHA, 1); SSL_CipherPrefSetDefault(SSL_DHE_DSS_WITH_DES_CBC_SHA, 1); #if NSS_VMAJOR > 3 || ( NSS_VMAJOR == 3 && NSS_VMINOR >= 14 ) /* Get the ranges of supported and enabled SSL versions */ if ((SSL_VersionRangeGetSupported(ssl_variant_stream, &supported) == SECSuccess) && (SSL_VersionRangeGetDefault(ssl_variant_stream, &enabled) == SECSuccess)) { purple_debug_info("nss", "TLS supported versions: " "0x%04hx through 0x%04hx\n", supported.min, supported.max); purple_debug_info("nss", "TLS versions allowed by default: " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); /* Make sure SSL 3.0 is disabled (it's old and everyone should be using at least TLS 1.0 by now), and make sure all versions of TLS supported by the local library are enabled (for some reason NSS doesn't enable newer versions of TLS by default -- more context in ticket #15909). */ if (enabled.min != SSL_LIBRARY_VERSION_TLS_1_0 || supported.max > enabled.max) { enabled.max = supported.max; if (SSL_VersionRangeSetDefault(ssl_variant_stream, &enabled) == SECSuccess) { purple_debug_info("nss", "Changed allowed TLS versions to " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); } else { purple_debug_error("nss", "Error setting allowed TLS versions to " "0x%04hx through 0x%04hx\n", enabled.min, enabled.max); } } } #endif /* NSS >= 3.14 */ /** Disable OCSP Checking until we can make that use our HTTP & Proxy stuff */ CERT_EnableOCSPChecking(PR_FALSE); _identity = PR_GetUniqueIdentity("Purple"); _nss_methods = PR_GetDefaultIOMethods(); }
static void LazyInitSocket() { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); if (sPollableEventLayerMethodsPtr) { return; } sPollableEventLayerIdentity = PR_GetUniqueIdentity("PollableEvent Layer"); sPollableEventLayerMethods = *PR_GetDefaultIOMethods(); sPollableEventLayerMethodsPtr = &sPollableEventLayerMethods; }
void * tls_init(const struct tls_config *conf) { char *dir; tls_nss_ref_count++; if (tls_nss_ref_count > 1) return (void *) 1; PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); nss_layer_id = PR_GetUniqueIdentity("wpa_supplicant"); PK11_SetPasswordFunc(nss_password_cb); dir = getenv("SSL_DIR"); if (dir) { if (NSS_Init(dir) != SECSuccess) { wpa_printf(MSG_ERROR, "NSS: NSS_Init(cert_dir=%s) " "failed", dir); return NULL; } } else { if (NSS_NoDB_Init(NULL) != SECSuccess) { wpa_printf(MSG_ERROR, "NSS: NSS_NoDB_Init(NULL) " "failed"); return NULL; } } if (SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, PR_FALSE) != SECSuccess || SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_FALSE) != SECSuccess || SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE) != SECSuccess || SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE) != SECSuccess) { wpa_printf(MSG_ERROR, "NSS: SSL_OptionSetDefault failed"); return NULL; } if (NSS_SetDomesticPolicy() != SECSuccess) { wpa_printf(MSG_ERROR, "NSS: NSS_SetDomesticPolicy() failed"); return NULL; } return (void *) 1; }
// static void ClosingService::Start() { if (!sTcpUdpPRCloseLayerMethodsPtr) { sTcpUdpPRCloseLayerId = PR_GetUniqueIdentity("TCP and UDP PRClose layer"); PR_ASSERT(PR_INVALID_IO_LAYER != sTcpUdpPRCloseLayerId); sTcpUdpPRCloseLayerMethods = *PR_GetDefaultIOMethods(); sTcpUdpPRCloseLayerMethods.close = TcpUdpPRCloseLayerClose; sTcpUdpPRCloseLayerMethodsPtr = &sTcpUdpPRCloseLayerMethods; } if (!sInstance) { ClosingService* service = new ClosingService(); if (NS_SUCCEEDED(service->StartInternal())) { NS_ADDREF(service); sInstance = service; } else { delete service; } } }
NSAPI_PUBLIC int net_init(int security_on) { _netlayer_identity = PR_GetUniqueIdentity("netlayer/" PRODUCT_FULL_VERSION_ID); const PRIOMethods *default_methods = PR_GetDefaultIOMethods(); _netlayer_methods = *default_methods; _netlayer_methods.recv = _netlayer_method_recv; _netlayer_methods.read = _netlayer_method_read; _netlayer_methods.available = _netlayer_method_available; _netlayer_methods.available64 = _netlayer_method_available64; _netlayer_methods.seek = _netlayer_method_seek; _netlayer_methods.seek64 = _netlayer_method_seek64; _netlayer_methods.recvfrom = _netlayer_method_recvfrom; _netlayer_methods.poll = _netlayer_method_poll; _netlayer_methods.acceptread = _netlayer_method_acceptread; _netlayer_methods.close = _netlayer_method_close; _netlayer_default_close_method = default_methods->close; return 0; }
static PRStatus memio_InitializeLayerName(void) { memio_identity = PR_GetUniqueIdentity("memio"); return PR_SUCCESS; }
PRIntn main(PRIntn argc, char **argv) { PRStatus rv; PRIntn mits; PLOptStatus os; PRFileDesc *client, *service; PRFileDesc *client_stack, *service_stack; PRNetAddr any_address; const char *server_name = NULL; const PRIOMethods *stubMethods; PRThread *client_thread, *server_thread; PRThreadScope thread_scope = PR_LOCAL_THREAD; PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 0: server_name = opt->value; break; case 'd': /* debug mode */ if (verbosity < noisy) verbosity = ChangeVerbosity(verbosity, 1); break; case 'q': /* debug mode */ if (verbosity > silent) verbosity = ChangeVerbosity(verbosity, -1); break; case 'G': /* use global threads */ thread_scope = PR_GLOBAL_THREAD; break; case 'C': /* number of threads waiting */ major_iterations = atoi(opt->value); break; case 'c': /* number of client threads */ minor_iterations = atoi(opt->value); break; case 'p': /* default port */ default_port = atoi(opt->value); break; default: break; } } PL_DestroyOptState(opt); PR_STDIO_INIT(); logFile = PR_GetSpecialFD(PR_StandardError); identity = PR_GetUniqueIdentity("Dummy"); stubMethods = PR_GetDefaultIOMethods(); /* ** The protocol we're going to implement is one where in order to initiate ** a send, the sender must first solicit permission. Therefore, every ** send is really a send - receive - send sequence. */ myMethods = *stubMethods; /* first get the entire batch */ myMethods.recv = MyRecv; /* then override the ones we care about */ myMethods.send = MySend; /* then override the ones we care about */ if (NULL == server_name) rv = PR_InitializeNetAddr( PR_IpAddrLoopback, default_port, &server_address); else { rv = PR_StringToNetAddr(server_name, &server_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_InitializeNetAddr( PR_IpAddrNull, default_port, &server_address); } PR_ASSERT(PR_SUCCESS == rv); /* one type w/o layering */ mits = minor_iterations; while (major_iterations-- > 0) { if (verbosity > silent) PR_fprintf(logFile, "Beginning non-layered test\n"); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); minor_iterations = mits; server_thread = PR_CreateThread( PR_USER_THREAD, Server, service, PR_PRIORITY_HIGH, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != server_thread); client_thread = PR_CreateThread( PR_USER_THREAD, Client, client, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != client_thread); rv = PR_JoinThread(client_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_JoinThread(server_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); if (verbosity > silent) PR_fprintf(logFile, "Ending non-layered test\n"); /* with layering */ if (verbosity > silent) PR_fprintf(logFile, "Beginning layered test\n"); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); PushLayer(client); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); PushLayer(service); rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); minor_iterations = mits; server_thread = PR_CreateThread( PR_USER_THREAD, Server, service, PR_PRIORITY_HIGH, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != server_thread); client_thread = PR_CreateThread( PR_USER_THREAD, Client, client, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != client_thread); rv = PR_JoinThread(client_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_JoinThread(server_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv); /* with layering, using new style stack */ if (verbosity > silent) PR_fprintf(logFile, "Beginning layered test with new style stack\n"); client = PR_NewTCPSocket(); PR_ASSERT(NULL != client); client_stack = PR_CreateIOLayer(client); PushNewLayers(client_stack); service = PR_NewTCPSocket(); PR_ASSERT(NULL != service); service_stack = PR_CreateIOLayer(service); PushNewLayers(service_stack); rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv); minor_iterations = mits; server_thread = PR_CreateThread( PR_USER_THREAD, Server, service_stack, PR_PRIORITY_HIGH, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != server_thread); client_thread = PR_CreateThread( PR_USER_THREAD, Client, client_stack, PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 16 * 1024); PR_ASSERT(NULL != client_thread); rv = PR_JoinThread(client_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_JoinThread(server_thread); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv); rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv); if (verbosity > silent) PR_fprintf(logFile, "Ending layered test\n"); } return 0; } /* main */
int main(int argc, char **argv) { PRHostEnt he; PRStatus status; PRIntn next_index; PRUint16 port_number; char netdb_buf[PR_NETDB_BUF_SIZE]; PRNetAddr client_addr, server_addr; PRThread *client_thread, *server_thread; PRIntervalTime delta = PR_MillisecondsToInterval(500); err_out = PR_STDERR; std_out = PR_STDOUT; accept_timeout = PR_SecondsToInterval(2); emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead"); emu_layer_methods = *PR_GetDefaultIOMethods(); emu_layer_methods.acceptread = emu_AcceptRead; if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); if (PR_SUCCESS != status) { PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); PR_ProcessExit(1); } if (argc < 3) { status = PR_InitializeNetAddr( PR_IpAddrLoopback, port_number, &client_addr); if (PR_SUCCESS != status) { PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); PR_ProcessExit(1); } } else { status = PR_GetHostByName( argv[1], netdb_buf, sizeof(netdb_buf), &he); if (status == PR_FAILURE) { PL_FPrintError(err_out, "PR_GetHostByName failed"); PR_ProcessExit(1); } next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); if (next_index == -1) { PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); PR_ProcessExit(1); } } for ( write_dally = 0; write_dally < accept_timeout + (2 * delta); write_dally += delta) { PR_fprintf( std_out, "Testing w/ write_dally = %d msec\n", PR_IntervalToMilliseconds(write_dally)); server_thread = PR_CreateThread( PR_USER_THREAD, AcceptingThread, &server_addr, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (server_thread == NULL) { PL_FPrintError(err_out, "PR_CreateThread (server) failed"); PR_ProcessExit(1); } PR_Sleep(delta); /* let the server pot thicken */ client_thread = PR_CreateThread( PR_USER_THREAD, ConnectingThread, &client_addr, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (client_thread == NULL) { PL_FPrintError(err_out, "PR_CreateThread (client) failed"); PR_ProcessExit(1); } if (PR_JoinThread(client_thread) == PR_FAILURE) PL_FPrintError(err_out, "PR_JoinThread (client) failed"); if (PR_JoinThread(server_thread) == PR_FAILURE) PL_FPrintError(err_out, "PR_JoinThread (server) failed"); } return 0; }
// add SOCKS IO layer to an existing socket nsresult nsSOCKSIOLayerAddToSocket(int32_t family, const char *host, int32_t port, const char *proxyHost, int32_t proxyPort, int32_t socksVersion, uint32_t flags, PRFileDesc *fd, nsISupports** info) { NS_ENSURE_TRUE((socksVersion == 4) || (socksVersion == 5), NS_ERROR_NOT_INITIALIZED); if (firstTime) { //XXX hack until NSPR provides an official way to detect system IPv6 // support (bug 388519) PRFileDesc *tmpfd = PR_OpenTCPSocket(PR_AF_INET6); if (!tmpfd) { ipv6Supported = false; } else { // If the system does not support IPv6, NSPR will push // IPv6-to-IPv4 emulation layer onto the native layer ipv6Supported = PR_GetIdentitiesLayer(tmpfd, PR_NSPR_IO_LAYER) == tmpfd; PR_Close(tmpfd); } nsSOCKSIOLayerIdentity = PR_GetUniqueIdentity("SOCKS layer"); nsSOCKSIOLayerMethods = *PR_GetDefaultIOMethods(); nsSOCKSIOLayerMethods.connect = nsSOCKSIOLayerConnect; nsSOCKSIOLayerMethods.connectcontinue = nsSOCKSIOLayerConnectContinue; nsSOCKSIOLayerMethods.poll = nsSOCKSIOLayerPoll; nsSOCKSIOLayerMethods.bind = nsSOCKSIOLayerBind; nsSOCKSIOLayerMethods.acceptread = nsSOCKSIOLayerAcceptRead; nsSOCKSIOLayerMethods.getsockname = nsSOCKSIOLayerGetName; nsSOCKSIOLayerMethods.getpeername = nsSOCKSIOLayerGetPeerName; nsSOCKSIOLayerMethods.accept = nsSOCKSIOLayerAccept; nsSOCKSIOLayerMethods.listen = nsSOCKSIOLayerListen; nsSOCKSIOLayerMethods.close = nsSOCKSIOLayerClose; firstTime = false; #if defined(PR_LOGGING) gSOCKSLog = PR_NewLogModule("SOCKS"); #endif } LOGDEBUG(("Entering nsSOCKSIOLayerAddToSocket().")); PRFileDesc * layer; PRStatus rv; layer = PR_CreateIOLayerStub(nsSOCKSIOLayerIdentity, &nsSOCKSIOLayerMethods); if (! layer) { LOGERROR(("PR_CreateIOLayerStub() failed.")); return NS_ERROR_FAILURE; } nsSOCKSSocketInfo * infoObject = new nsSOCKSSocketInfo(); if (!infoObject) { // clean up IOLayerStub LOGERROR(("Failed to create nsSOCKSSocketInfo().")); PR_DELETE(layer); return NS_ERROR_FAILURE; } NS_ADDREF(infoObject); infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags); layer->secret = (PRFilePrivate*) infoObject; rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer); if (rv == PR_FAILURE) { LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv)); NS_RELEASE(infoObject); PR_DELETE(layer); return NS_ERROR_FAILURE; } *info = static_cast<nsISOCKSSocketInfo*>(infoObject); NS_ADDREF(*info); return NS_OK; }
NSAPI_PUBLIC PRStatus filter_init(void) { _filter_list_lock = PR_NewLock(); // Get an IO layer identity for active NSAPI filters _filter_identity = PR_GetUniqueIdentity("NSAPI filter"); // Figure out the NSS IO layer identity PRFileDesc *model = PR_NewTCPSocket(); if (model) { model = SSL_ImportFD(NULL, model); _filter_ssl_identity = model->identity; PR_Close(model); } // Get an IO layer identity for our "null" (bottom of stack) IO layer _filter_null_identity = PR_GetUniqueIdentity("NSAPI filter stack"); // Initialize the PRIOMethods for our "null" (bottom of stack) IO layer _filter_null_priomethods = *PR_GetDefaultIOMethods(); _filter_null_priomethods.file_type = PR_DESC_PIPE; // Not socket/file/layer _filter_null_priomethods.close = &iolayer_null_close; _filter_null_priomethods.read = &iolayer_null_read; _filter_null_priomethods.write = &iolayer_null_write; _filter_null_priomethods.available = &iolayer_null_available; _filter_null_priomethods.available64 = &iolayer_null_available64; _filter_null_priomethods.fsync = &iolayer_null_fsync; _filter_null_priomethods.seek = &iolayer_null_seek; _filter_null_priomethods.seek64 = &iolayer_null_seek64; _filter_null_priomethods.fileInfo = &iolayer_null_fileinfo; _filter_null_priomethods.fileInfo64 = &iolayer_null_fileinfo64; _filter_null_priomethods.writev = &iolayer_null_writev; _filter_null_priomethods.connect = &iolayer_null_connect; _filter_null_priomethods.accept = &iolayer_null_accept; _filter_null_priomethods.bind = &iolayer_null_bind; _filter_null_priomethods.listen = &iolayer_null_listen; _filter_null_priomethods.shutdown = &iolayer_null_shutdown; _filter_null_priomethods.recv = &iolayer_null_recv; _filter_null_priomethods.send = &iolayer_null_send; _filter_null_priomethods.recvfrom = &iolayer_null_recvfrom; _filter_null_priomethods.sendto = &iolayer_null_sendto; _filter_null_priomethods.poll = &iolayer_null_poll; _filter_null_priomethods.acceptread = &iolayer_null_acceptread; _filter_null_priomethods.transmitfile = &iolayer_null_transmitfile; _filter_null_priomethods.getsockname = &iolayer_null_getsockname; _filter_null_priomethods.getpeername = &iolayer_null_getpeername; _filter_null_priomethods.getsocketoption = &iolayer_null_getsocketoption; _filter_null_priomethods.setsocketoption = &iolayer_null_setsocketoption; _filter_null_priomethods.sendfile = &iolayer_null_sendfile; _filter_null_priomethods.connectcontinue = &iolayer_null_connectcontinue; // Initialize pseudo-filters FilterMethods pseudo_methods = FILTER_METHODS_INITIALIZER; pseudo_methods.insert = &filtermethod_never_insert; // user can't insert these filter_fill(FILTER_NAME_TOP, 0x7fffffff /* top */, &pseudo_methods, 0, &_filter_top); filter_fill(FILTER_NAME_BOTTOM, 0 /* bottom */, &pseudo_methods, 0, &_filter_bottom); filter_fill(FILTER_NAME_NETWORK, FILTER_NETWORK, &pseudo_methods, 0, &_filter_network); filter_fill(FILTER_NAME_SSL, FILTER_TRANSPORT_CODING, &pseudo_methods, 0, &_filter_ssl); // Create a filter to call into Output stage and filter_set_request() FilterMethods callback_methods = FILTER_METHODS_INITIALIZER; callback_methods.insert = &filtermethod_always_insert; callback_methods.flush = &filtermethod_callback_flush; callback_methods.read = &filtermethod_callback_read; callback_methods.write = &filtermethod_callback_write; callback_methods.writev = (FilterWritevFunc*)&filtermethod_callback_writev; callback_methods.sendfile = (FilterSendfileFunc*)&filtermethod_callback_sendfile; _filter_callback = filter_create_internal("magnus-internal/callback", FILTER_TOPMOST, &callback_methods, FILTER_CALLS_CALLBACKS); if (!_filter_callback) return PR_FAILURE; // We'll use this per-DaemonSession slot to cache unused PRFileDescs _filter_prfiledesc_slot = session_alloc_thread_slot(NULL); // Will pass this empty pblock (instead of NULL) if filter_insert() is // called with a NULL pblock * _empty_pb = pblock_create(1); return PR_SUCCESS; }
// TODO: make sure this is called from STS. Otherwise // we have thread safety issues bool TransportLayerDtls::Setup() { CheckThread(); SECStatus rv; if (!downward_) { MOZ_MTLOG(ML_ERROR, "DTLS layer with nothing below. This is useless"); return false; } nspr_io_adapter_ = new TransportLayerNSPRAdapter(downward_); if (!identity_) { MOZ_MTLOG(ML_ERROR, "Can't start DTLS without an identity"); return false; } if (verification_mode_ == VERIFY_UNSET) { MOZ_MTLOG(ML_ERROR, "Can't start DTLS without specifying a verification mode"); return false; } if (transport_layer_identity == PR_INVALID_IO_LAYER) { transport_layer_identity = PR_GetUniqueIdentity("nssstreamadapter"); } ScopedPRFileDesc pr_fd(PR_CreateIOLayerStub(transport_layer_identity, &TransportLayerMethods)); MOZ_ASSERT(pr_fd != nullptr); if (!pr_fd) return false; pr_fd->secret = reinterpret_cast<PRFilePrivate *>(nspr_io_adapter_.get()); ScopedPRFileDesc ssl_fd(DTLS_ImportFD(nullptr, pr_fd)); MOZ_ASSERT(ssl_fd != nullptr); // This should never happen if (!ssl_fd) { return false; } pr_fd.forget(); // ownership transfered to ssl_fd; if (role_ == CLIENT) { MOZ_MTLOG(ML_DEBUG, "Setting up DTLS as client"); rv = SSL_GetClientAuthDataHook(ssl_fd, GetClientAuthDataHook, this); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't set identity"); return false; } } else { MOZ_MTLOG(ML_DEBUG, "Setting up DTLS as server"); // Server side rv = SSL_ConfigSecureServer(ssl_fd, identity_->cert(), identity_->privkey(), kt_rsa); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't set identity"); return false; } // Insist on a certificate from the client rv = SSL_OptionSet(ssl_fd, SSL_REQUEST_CERTIFICATE, PR_TRUE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't request certificate"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_REQUIRE_CERTIFICATE, PR_TRUE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't require certificate"); return false; } } // Require TLS 1.1 or 1.2. Perhaps some day in the future we will allow TLS // 1.0 for stream modes. SSLVersionRange version_range = { SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_2 }; rv = SSL_VersionRangeSet(ssl_fd, &version_range); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Can't disable SSLv3"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't disable session tickets"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_NO_CACHE, PR_TRUE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't disable session caching"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_DEFLATE, PR_FALSE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't disable deflate"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_NEVER); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't disable renegotiation"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_FALSE_START, PR_FALSE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't disable false start"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_NO_LOCKS, PR_TRUE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't disable locks"); return false; } rv = SSL_OptionSet(ssl_fd, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't disable ECDHE key reuse"); return false; } if (!SetupCipherSuites(ssl_fd)) { return false; } // Certificate validation rv = SSL_AuthCertificateHook(ssl_fd, AuthCertificateHook, reinterpret_cast<void *>(this)); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't set certificate validation hook"); return false; } // Now start the handshake rv = SSL_ResetHandshake(ssl_fd, role_ == SERVER ? PR_TRUE : PR_FALSE); if (rv != SECSuccess) { MOZ_MTLOG(ML_ERROR, "Couldn't reset handshake"); return false; } ssl_fd_ = ssl_fd.forget(); // Finally, get ready to receive data downward_->SignalStateChange.connect(this, &TransportLayerDtls::StateChange); downward_->SignalPacketReceived.connect(this, &TransportLayerDtls::PacketReceived); if (downward_->state() == TS_OPEN) { Handshake(); } return true; }
NS_IMETHODIMP nsWINCESSLSocketProvider::NewSocket(PRInt32 family, const char *host, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, PRUint32 flags, PRFileDesc **result, nsISupports **socksInfo) { static PRBool firstTime = PR_TRUE; if (firstTime) { nsWINCESSLIOLayerIdentity = PR_GetUniqueIdentity("WINCESSL layer"); nsWINCESSLIOLayerMethods = *PR_GetDefaultIOMethods(); nsWINCESSLIOLayerMethods.connect = nsWINCESSLIOLayerConnect; nsWINCESSLIOLayerMethods.close = nsWINCESSLIOLayerClose; nsWINCESSLIOLayerMethods.available = nsWINCESSLIOLayerAvailable; nsWINCESSLIOLayerMethods.write = nsWINCESSLIOLayerWrite; nsWINCESSLIOLayerMethods.read = nsWINCESSLIOLayerRead; nsWINCESSLIOLayerMethods.poll = nsWINCESSLIOLayerPoll; firstTime = PR_FALSE; } PRFileDesc *fd = PR_OpenTCPSocket(family); if (!fd) return NS_ERROR_OUT_OF_MEMORY; PRFileDesc * layer; PRStatus rv; layer = PR_CreateIOLayerStub(nsWINCESSLIOLayerIdentity, &nsWINCESSLIOLayerMethods); if (! layer) return NS_ERROR_UNEXPECTED; nsWINCESSLSocketInfo * infoObject = new nsWINCESSLSocketInfo(); if (!infoObject) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(infoObject); layer->secret = (PRFilePrivate*) infoObject; rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; nsresult initrv = infoObject->Init(host, proxyHost, proxyPort); if (NS_FAILED(initrv)) { MessageBox(0, "Can not create ssl socket.", "Can not create ssl socket.", MB_APPLMODAL | MB_TOPMOST | MB_SETFOREGROUND); return NS_ERROR_FAILURE; } *result = fd; *socksInfo = (nsISupports*) (nsITransportSecurityInfo*) infoObject; return NS_OK; }