Ejemplo n.º 1
0
/******************************************************************************
 * NETCON_secure_connect
 * Initiates a secure connection over an existing plaintext connection.
 */
DWORD NETCON_secure_connect(netconn_t *connection, server_t *server)
{
    DWORD res;

    /* can't connect if we are already connected */
    if(connection->secure) {
        ERR("already connected\n");
        return ERROR_INTERNET_CANNOT_CONNECT;
    }

    if(server != connection->server) {
        server_release(connection->server);
        server_addref(server);
        connection->server = server;
    }

    /* connect with given TLS options */
    res = netcon_secure_connect_setup(connection, FALSE);
    if (res == ERROR_SUCCESS)
        return res;

    /* FIXME: when got version alert and FIN from server */
    /* fallback to connect without TLSv1.1/TLSv1.2        */
    if (res == ERROR_INTERNET_SECURITY_CHANNEL_ERROR && have_compat_cred_handle)
    {
        closesocket(connection->socket);
        res = create_netconn_socket(connection->server, connection, 500);
        if (res != ERROR_SUCCESS)
            return res;
        res = netcon_secure_connect_setup(connection, TRUE);
    }
    return res;
}
Ejemplo n.º 2
0
DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, BOOL mask_errors, DWORD timeout, netconn_t **ret)
{
    netconn_t *netconn;
    int result;

    netconn = heap_alloc_zero(sizeof(*netconn));
    if(!netconn)
        return ERROR_OUTOFMEMORY;

    netconn->socket = -1;
    netconn->security_flags = security_flags | server->security_flags;
    netconn->mask_errors = mask_errors;
    list_init(&netconn->pool_entry);
    SecInvalidateHandle(&netconn->ssl_ctx);

    result = create_netconn_socket(server, netconn, timeout);
    if (result != ERROR_SUCCESS) {
        heap_free(netconn);
        return result;
    }

    server_addref(server);
    netconn->server = server;
    *ret = netconn;
    return result;
}
Ejemplo n.º 3
0
DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, netconn_t **ret)
{
    netconn_t *netconn;
    int result, flag;

    if(useSSL) {
        DWORD res;

        TRACE("using SSL connection\n");

        EnterCriticalSection(&init_ssl_cs);
        res = init_openssl();
        LeaveCriticalSection(&init_ssl_cs);
        if(res != ERROR_SUCCESS)
            return res;
    }

    netconn = heap_alloc_zero(sizeof(*netconn));
    if(!netconn)
        return ERROR_OUTOFMEMORY;

    netconn->useSSL = useSSL;
    netconn->socketFD = -1;
    netconn->security_flags = security_flags;
    list_init(&netconn->pool_entry);

    assert(server->addr_len);
    result = netconn->socketFD = socket(server->addr.ss_family, SOCK_STREAM, 0);
    if(result != -1) {
        result = connect(netconn->socketFD, (struct sockaddr*)&server->addr, server->addr_len);
        if(result == -1)
            closesocket(netconn->socketFD);
    }
    if(result == -1) {
        heap_free(netconn);
        return sock_get_error(errno);
    }

#ifdef TCP_NODELAY
    flag = 1;
    result = setsockopt(netconn->socketFD, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag));
    if(result < 0)
        WARN("setsockopt(TCP_NODELAY) failed\n");
#endif

    server_addref(server);
    netconn->server = server;

    *ret = netconn;
    return ERROR_SUCCESS;
}
Ejemplo n.º 4
0
DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, DWORD timeout, netconn_t **ret)
{
    netconn_t *netconn;
    int result, flag;

    if(useSSL) {
        DWORD res;

        TRACE("using SSL connection\n");

        EnterCriticalSection(&init_ssl_cs);
        res = init_openssl();
        LeaveCriticalSection(&init_ssl_cs);
        if(res != ERROR_SUCCESS)
            return res;
    }

    netconn = heap_alloc_zero(sizeof(*netconn));
    if(!netconn)
        return ERROR_OUTOFMEMORY;

    netconn->useSSL = useSSL;
    netconn->socketFD = -1;
    netconn->security_flags = security_flags;
    list_init(&netconn->pool_entry);

    assert(server->addr_len);
    result = netconn->socketFD = socket(server->addr.ss_family, SOCK_STREAM, 0);
    if(result != -1) {
        flag = 1;
        ioctlsocket(netconn->socketFD, FIONBIO, &flag);
        result = connect(netconn->socketFD, (struct sockaddr*)&server->addr, server->addr_len);
        if(result == -1)
        {
            if (sock_get_error(errno) == WSAEINPROGRESS) {
                struct pollfd pfd;
                int res;

                pfd.fd = netconn->socketFD;
                pfd.events = POLLOUT;
                res = poll(&pfd, 1, timeout);
                if (!res)
                {
                    closesocket(netconn->socketFD);
                    heap_free(netconn);
                    return ERROR_INTERNET_CANNOT_CONNECT;
                }
                else if (res > 0)
                {
                    int err;
                    socklen_t len = sizeof(err);
                    if (!getsockopt(netconn->socketFD, SOL_SOCKET, SO_ERROR, &err, &len) && !err)
                        result = 0;
                }
            }
        }
        if(result == -1)
            closesocket(netconn->socketFD);
        else {
            flag = 0;
            ioctlsocket(netconn->socketFD, FIONBIO, &flag);
        }
    }
    if(result == -1) {
        heap_free(netconn);
        return sock_get_error(errno);
    }

#ifdef TCP_NODELAY
    flag = 1;
    result = setsockopt(netconn->socketFD, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag));
    if(result < 0)
        WARN("setsockopt(TCP_NODELAY) failed\n");
#endif

    server_addref(server);
    netconn->server = server;

    *ret = netconn;
    return ERROR_SUCCESS;
}