Beispiel #1
0
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 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();
}
Beispiel #4
0
static void LazyInitSocket()
{
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  if (sPollableEventLayerMethodsPtr) {
    return;
  }
  sPollableEventLayerIdentity = PR_GetUniqueIdentity("PollableEvent Layer");
  sPollableEventLayerMethods = *PR_GetDefaultIOMethods();
  sPollableEventLayerMethodsPtr = &sPollableEventLayerMethods;
}
// 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;
}
Beispiel #7
0
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;
}
PR_END_EXTERN_C


/* ----------------------------- filter_fill ------------------------------ */

static Filter *filter_fill(const char *name, int order, const FilterMethods *methods, int flags, Filter *filter)
{
    filter->name = PERM_STRDUP(name);
    filter->flags = flags;
    filter->order = order & FILTER_MASK; // Reserve topmost bits for future use

    /*
     * Setup NSAPI-specific filter methods
     */

    if (methods->insert) {
        filter->insert = methods->insert;
    } else {
        filter->insert = &filtermethod_always_insert;
    }

    if (methods->remove) {
        filter->remove = methods->remove;
    } else {
        filter->remove = &filtermethod_default_remove;
    }

    if (methods->read) {
        filter->read = methods->read;
    } else {
        filter->read = NULL;
    }

    /*
     * Setup NSPR filter methods
     */

    filter->priomethods = *PR_GetDefaultIOMethods();
    filter->priomethods.file_type = PR_DESC_LAYERED;

    // Assert NSPR IO layer and NSAPI filter binary compatibility
    PR_ASSERT(sizeof(PRSendFileData) == sizeof(sendfiledata));
    PR_ASSERT(sizeof(PRIOVec) == sizeof(NSAPIIOVec));
    PR_ASSERT(sizeof(PRStatus) == sizeof(int));
    PR_ASSERT(sizeof(PRInt32) == sizeof(int));
    PR_ASSERT(sizeof(PRSize) == sizeof(size_t));

    filter->priomethods.close = &filtermethod_close;

    if (methods->flush) {
        filter->priomethods.fsync = (PRFsyncFN)methods->flush;
    } else {
        filter->priomethods.fsync = &filtermethod_default_fsync;
    }

    if (methods->read) {
        filter->priomethods.read = &filtermethod_emulate_read;
        filter->priomethods.recv = &filtermethod_emulate_recv;
    } else {
        filter->priomethods.read = &filtermethod_default_read;
        filter->priomethods.recv = &filtermethod_default_recv;
    }

    if (methods->write) {
        filter->priomethods.write = (PRWriteFN)methods->write;
        filter->priomethods.send = (PRSendFN)methods->write;
    } else {
        filter->priomethods.write = &filtermethod_default_write;
        filter->priomethods.send = &filtermethod_default_send;
    }

    if (methods->writev) {
        filter->priomethods.writev = (PRWritevFN)methods->writev;
    } else if (methods->write) {
        ereport(LOG_VERBOSE, "Emulating writev for filter %s", filter->name);
        filter->priomethods.writev = &filtermethod_emulate_writev;
    } else {
        filter->priomethods.writev = &filtermethod_default_writev;
    }

    if (methods->sendfile) {
        filter->priomethods.sendfile = (PRSendfileFN)methods->sendfile;
    } else if (methods->write) {
        ereport(LOG_VERBOSE, "Emulating sendfile for filter %s", filter->name);
        filter->priomethods.sendfile = &filtermethod_emulate_sendfile;
    } else {
        filter->priomethods.sendfile = &filtermethod_default_sendfile;
    }

    /*
     * Add the filter to the front of the server-wide list
     */

    PR_Lock(_filter_list_lock);

    filter->next = _filter_list;
    _filter_list = filter;

    _filter_hash.remove((void *)filter->name);
    _filter_hash.insert((void *)filter->name, filter);

    PR_Unlock(_filter_list_lock);

    return filter;
}
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;
}
Beispiel #12
0
static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd)
{
    PR_DELETE(fd->secret);  /* manage my secret file object */
    return (PR_GetDefaultIOMethods())->close(fd);  /* let him do all the work */
}  /* MyClose */
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;

}