Ejemplo n.º 1
0
NOEXPORT int verify_callback(int preverify_ok, X509_STORE_CTX *callback_ctx) {
        /* our verify callback function */
    SSL *ssl;
    CLI *c;

    /* retrieve application specific data */
    ssl=X509_STORE_CTX_get_ex_data(callback_ctx,
        SSL_get_ex_data_X509_STORE_CTX_idx());
    c=SSL_get_ex_data(ssl, cli_index);
    if(c->opt->verify_level<1) {
        s_log(LOG_INFO, "Certificate verification disabled");
        return 1; /* accept */
    }
    if(verify_checks(preverify_ok, callback_ctx))
        return 1; /* accept */
    if(c->opt->option.client || c->opt->protocol)
        return 0; /* reject */
    if(c->opt->redirect_addr.num) { /* pre-resolved addresses */
        addrlist_dup(&c->connect_addr, &c->opt->redirect_addr);
        s_log(LOG_INFO, "Redirecting connection");
        return 1; /* accept */
    }
    /* delayed lookup */
    if(namelist2addrlist(&c->connect_addr,
            c->opt->redirect_list, DEFAULT_LOOPBACK)) {
        s_log(LOG_INFO, "Redirecting connection");
        return 1; /* accept */
    }
    return 0; /* reject */
}
Ejemplo n.º 2
0
NOEXPORT void connect_server(CLI *c) {
    char *request, *proto, *header;
    NAME_LIST host_list;

    request=fd_getline(c, c->local_rfd.fd);
    if(!is_prefix(request, "CONNECT ")) {
        fd_putline(c, c->local_wfd.fd, "HTTP/1.0 400 Bad Request Method");
        fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
        fd_putline(c, c->local_wfd.fd, "");
        str_free(request);
        longjmp(c->err, 1);
    }
    proto=strchr(request+8, ' ');
    if(!proto || !is_prefix(proto, " HTTP/")) {
        fd_putline(c, c->local_wfd.fd, "HTTP/1.0 400 Bad Request Protocol");
        fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
        fd_putline(c, c->local_wfd.fd, "");
        str_free(request);
        longjmp(c->err, 1);
    }
    *proto='\0';

    header=str_dup("");
    do { /* ignore any headers */
        str_free(header);
        header=fd_getline(c, c->local_rfd.fd);
    } while(*header); /* not empty */
    str_free(header);

    host_list.name=request+8;
    host_list.next=NULL;
    if(!namelist2addrlist(&c->connect_addr, &host_list, DEFAULT_LOOPBACK)) {
        fd_putline(c, c->local_wfd.fd, "HTTP/1.0 404 Not Found");
        fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
        fd_putline(c, c->local_wfd.fd, "");
        str_free(request);
        longjmp(c->err, 1);
    }
    str_free(request);
    fd_putline(c, c->local_wfd.fd, "HTTP/1.0 200 OK");
    fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
    fd_putline(c, c->local_wfd.fd, "");
}
Ejemplo n.º 3
0
NOEXPORT void setup_connect_addr(CLI *c) {
#ifdef SO_ORIGINAL_DST
    socklen_t addrlen=sizeof(SOCKADDR_UNION);
#endif /* SO_ORIGINAL_DST */

    /* check if the address was already set by the verify callback,
     * or a dynamic protocol
     * implemented protocols: CONNECT
     * protocols to be implemented: SOCKS4 */
    if(c->connect_addr.num)
        return;

#ifdef SO_ORIGINAL_DST
    if(c->opt->option.transparent_dst) {
        c->connect_addr.num=1;
        c->connect_addr.addr=str_alloc(sizeof(SOCKADDR_UNION));
        if(getsockopt(c->local_rfd.fd, SOL_IP, SO_ORIGINAL_DST,
                c->connect_addr.addr, &addrlen)) {
            sockerror("setsockopt SO_ORIGINAL_DST");
            longjmp(c->err, 1);
        }
        return;
    }
#endif /* SO_ORIGINAL_DST */

    if(c->opt->connect_addr.num) { /* pre-resolved addresses */
        addrlist_dup(&c->connect_addr, &c->opt->connect_addr);
        return;
    }

    /* delayed lookup */
    if(namelist2addrlist(&c->connect_addr,
            c->opt->connect_list, DEFAULT_LOOPBACK))
        return;

    s_log(LOG_ERR, "No host resolved");
    longjmp(c->err, 1);
}