示例#1
0
文件: io.c 项目: EvertYing/cyassl
int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
                        byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
{
    char domainName[80], path[80];
    int port, httpBufSz, sfd = -1;
    int ocspRespSz = 0;
    byte* httpBuf = NULL;

    (void)ctx;

    if (ocspReqBuf == NULL || ocspReqSz == 0) {
        CYASSL_MSG("OCSP request is required for lookup");
        return -1;
    }

    if (ocspRespBuf == NULL) {
        CYASSL_MSG("Cannot save OCSP response");
        return -1;
    }

    if (decode_url(url, urlSz, domainName, path, &port) < 0) {
        CYASSL_MSG("Unable to decode OCSP URL");
        return -1;
    }
    
    /* Note, the library uses the EmbedOcspRespFree() callback to
     * free this buffer. */
    httpBufSz = SCRATCH_BUFFER_SIZE;
    httpBuf = (byte*)XMALLOC(httpBufSz, NULL, DYNAMIC_TYPE_IN_BUFFER);

    if (httpBuf == NULL) {
        CYASSL_MSG("Unable to create OCSP response buffer");
        return -1;
    }

    httpBufSz = build_http_request(domainName, path, ocspReqSz,
                                                        httpBuf, httpBufSz);

    if ((tcp_connect(&sfd, domainName, port) == 0) && (sfd > 0)) {
        int written;
        written = (int)send(sfd, httpBuf, httpBufSz, 0);
        if (written == httpBufSz) {
            written = (int)send(sfd, ocspReqBuf, ocspReqSz, 0);
            if (written == ocspReqSz) {
                ocspRespSz = process_http_response(sfd, ocspRespBuf,
                                                 httpBuf, SCRATCH_BUFFER_SIZE);
            }
        }
        close(sfd);
        if (ocspRespSz == 0) {
            CYASSL_MSG("OCSP response was not OK, no OCSP response");
            XFREE(httpBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
            return -1;
        }
    } else {
        CYASSL_MSG("OCSP Responder connection failed");
        close(sfd);
        XFREE(httpBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
        return -1;
    }

    XFREE(httpBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
    return ocspRespSz;
}
示例#2
0
文件: io.c 项目: Eppo791906066/cyassl
int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
                        byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
{
    SOCKET_T sfd = 0;
    word16   port;
    int      ret = -1;
#ifdef CYASSL_SMALL_STACK
    char*    path;
    char*    domainName;
#else
    char     path[80];
    char     domainName[80];
#endif

#ifdef CYASSL_SMALL_STACK
    path = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (path == NULL)
        return -1;
    
    domainName = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (domainName == NULL) {
        XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return -1;
    }
#endif

    (void)ctx;

    if (ocspReqBuf == NULL || ocspReqSz == 0) {
        CYASSL_MSG("OCSP request is required for lookup");
    }
    else if (ocspRespBuf == NULL) {
        CYASSL_MSG("Cannot save OCSP response");
    }
    else if (decode_url(url, urlSz, domainName, path, &port) < 0) {
        CYASSL_MSG("Unable to decode OCSP URL");
    }
    else {
        /* Note, the library uses the EmbedOcspRespFree() callback to
         * free this buffer. */
        int   httpBufSz = SCRATCH_BUFFER_SIZE;
        byte* httpBuf   = (byte*)XMALLOC(httpBufSz, NULL, 
                                                        DYNAMIC_TYPE_IN_BUFFER);

        if (httpBuf == NULL) {
            CYASSL_MSG("Unable to create OCSP response buffer");
        }
        else {
            httpBufSz = build_http_request(domainName, path, ocspReqSz,
                                                            httpBuf, httpBufSz);

            if ((tcp_connect(&sfd, domainName, port) != 0) || (sfd <= 0)) {
                CYASSL_MSG("OCSP Responder connection failed");
            }
            else if ((int)send(sfd, (char*)httpBuf, httpBufSz, 0) !=
                                                                    httpBufSz) {
                CYASSL_MSG("OCSP http request failed");
            }
            else if ((int)send(sfd, (char*)ocspReqBuf, ocspReqSz, 0) !=
                                                                    ocspReqSz) {
                CYASSL_MSG("OCSP ocsp request failed");
            }
            else {
                ret = process_http_response(sfd, ocspRespBuf, httpBuf,
                                                           SCRATCH_BUFFER_SIZE);
            }

            close(sfd);
            XFREE(httpBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
        }
    }

#ifdef CYASSL_SMALL_STACK
    XFREE(path,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    return ret;
}
示例#3
0
文件: main.c 项目: NeverMore93/INTANG
/* Process TCP packets
 * Return 0 to accept packet, otherwise to drop packet 
 */
int process_tcp_packet(struct mypacket *packet, char inout)
{
    int ret = 0;
    struct myiphdr *iphdr = packet->iphdr;
    struct mytcphdr *tcphdr = packet->tcphdr;
    unsigned char *payload = packet->payload;

    char sip[16], dip[16];
    ip2str(iphdr->saddr, sip);
    ip2str(iphdr->daddr, dip);

    unsigned short sport, dport;
    //unsigned int seq, ack;
    sport = ntohs(tcphdr->th_sport);
    dport = ntohs(tcphdr->th_dport);
    //seq = tcphdr->th_seq;
    //ack = tcphdr->th_ack;
    log_debug("[TCP] This packet goes from %s:%d to %s:%d", sip, sport, dip, dport);
    log_debug("TCP flags: %s", tcp_flags(tcphdr->th_flags));

    struct fourtuple fourtp;
    fourtp.saddr = iphdr->saddr;
    fourtp.daddr = iphdr->daddr;
    fourtp.sport = tcphdr->th_sport;
    fourtp.dport = tcphdr->th_dport;

    // for testing uni-directional packet forwarding to bypass IP blocking 
    //if (dport == 80 && is_blocked_ip(dip)) {
    //    log_debug("Going to forward that packet!!!");
    //    unsigned int newlen = packet->len + 4;
    //    char *newpkt = (char*)malloc(newlen);
    //    memcpy(newpkt, packet->data, packet->len);
    //    *(u_int32_t*)(newpkt + packet->len) = iphdr->daddr;
    //    ip_hdr(newpkt)->daddr = str2ip(PACKET_FORWARDER);
    //    send_raw(newpkt, newlen);
    //    log_debug("sent!!!");
    //    return 0;
    //}

    if (tcphdr->th_flags == TCP_SYN) {
        // Processing outgoing SYN packet. 

        // Uploading diagnostic log is disabled. (2017.9.1) 
        //if (strcmp(dip, FEEDBACK_SERVER_IP) == 0)
        //    return 0;
        

        // choose a strategy for the newly created connection
        int sid = choose_strategy_by_historical_result(iphdr->daddr);
        log_debug("Using strategy %s", g_strats[sid].name);
        set_sid(&fourtp, sid);
        //cache_strategy(&fourtp, sid);

        if (g_strats[sid].process_syn) {
            ret = g_strats[sid].process_syn(packet);
#ifndef EVALUATION
            if (ret) {
                need_evaluation(&fourtp);
            }
#endif
        }
    }
    if (tcphdr->th_flags == (TCP_SYN | TCP_ACK)) {
        // Got a SYN-ACK from server

        // send an ACK with 1 TTL to make home router happy 
        if (opt_inject_ack_with_one_ttl)
            send_ACK_with_one_ttl(dip, dport, sip, sport, tcphdr->th_ack, htonl(ntohl(tcphdr->th_seq)+1));

        struct fourtuple reverse_fourtp;
        reverse_fourtp.saddr = iphdr->daddr;
        reverse_fourtp.daddr = iphdr->saddr;
        reverse_fourtp.sport = tcphdr->th_dport;
        reverse_fourtp.dport = tcphdr->th_sport;

        int sid = get_sid(&reverse_fourtp);
        if (sid >= 0) {
            if (get_ttl(iphdr->saddr) == 0) {
                // if TTL hasn't been initialized 
                // find initial TTL from SYN/ACK packet
                int ttl = choose_appropriate_ttl(iphdr->ttl);
                set_ttl(iphdr->saddr, ttl);
            }
            if  (g_strats[sid].process_synack) {
                ret = g_strats[sid].process_synack(packet);
#ifndef EVALUATION
                if (ret) {
                    need_evaluation(&reverse_fourtp);
                }
#endif
            }
        }
        else if (sid == -1) {
            ret = process_synack_for_ttl_probing(packet);
        }

        //if (opt_inject_syn_and_syn_ack_with_one_ttl)
        //    send_one_ttl_SYN_and_SYN_ACK(dip, dport, sip, sport, tcphdr->th_ack, tcphdr->th_seq);
    } 
    else if ((tcphdr->th_flags & TCP_ACK) && 
        !(tcphdr->th_flags & (TCP_SYN | TCP_RST))) {
        // ignore ACK packets without payload 
        if (packet->payload_len == 0) 
            return 0;

        if (dport == 80) {
            if ((payload[0] == 'G' && payload[1] == 'E' && 
                 payload[2] == 'T' && payload[3] == ' ') ||
                (payload[0] == 'P' && payload[1] == 'O' && 
                 payload[2] == 'S' && payload[3] == 'T' && 
                 payload[4] == ' ')) {
                // Got a outgoing HTTP request 
                log_debug("[TCP] Sent a HTTP request from %s:%d to %s:%d.", sip, sport, dip, dport);
                int i, j, k, l;
                
                //char req_line[1000];
                //for (i = 0; i < 1000; i++) {
                //    if (payload[i] == '\r' || payload[i] == '\n') {
                //        req_line[i] = 0;
                //        break;
                //    }
                //    req_line[i] = payload[i];
                //}
                
                // Generate the HTTP request line. Format: GET/POST domain/url. e.g. GET www.google.com/index.php
                char req_line2[1000];
                // copy GET/POST 
                for (i = 0; payload[i] != ' ' && i < packet->payload_len; i++) {
                    req_line2[i] = payload[i];
                }
                req_line2[i++] = ' ';
                k = i; 
    
                // find Host field
                for (j = i; j < packet->payload_len; j++) {
                    if (payload[j] == 'H' && payload[j+1] == 'o' &&
                            payload[j+2] == 's' && payload[j+3] == 't' &&
                            payload[j+4] == ':' && (payload[j-1] == '\r' || payload[j-1] == '\n')) {
                        j += 5;
                        // copy Host value 
                        while (payload[j] == ' ') j++;
                        for (l = 0; l < 99 && j+l < packet->payload_len; l++) {
                            if (payload[j+l] == '\r' || payload[j+l] == '\n')
                                break;
                            req_line2[k++] = payload[j+l];
                        }
                        break;
                    }
                }

                // copy the rest of request line 
                for (; i < 900 && i < packet->payload_len; i++) {
                    if (payload[i] == '\r' || payload[i] == '\n') {
                        break;
                    }
                    req_line2[k++] = payload[i];
                }
                req_line2[k] = 0;
    
                log_debug("[TCP] %s", req_line2); 

                int sid = get_sid(&fourtp);
                if (sid >= 0 && g_strats[sid].process_request) {
                    ret = g_strats[sid].process_request(packet);
#ifndef EVALUATION
                    if (ret) {
                        need_evaluation(&fourtp);
                    }
#endif
                }
#ifdef EVALUATION
                if (strstr(req_line2, "ultrasurf") || strstr(req_line2, "goodword")) {
                    need_evaluation(&fourtp);
                }
#endif

                cache_http_request(&fourtp, req_line2);
            }
        }
        else if (sport == 80) {
            if (payload[0] == 'H' && payload[1] == 'T' && payload[2] == 'T' && payload[3] == 'P') {
                // Got a incoming HTTP response 
                log_debug("[TCP] Got a HTTP response from %s:%d to %s:%d.", sip, sport, dip, dport);
                process_http_response(&fourtp, tcphdr->th_seq, iphdr->ttl);
            }
        }
        else if (dport == 53) {
            // Got a DNS request over TCP 
            log_debug("[TCP] Sent a DNS request from %s:%d to %s:%d.", sip, sport, dip, dport);

            int sid = get_sid(&fourtp);
            if (sid >= 0 && g_strats[sid].process_request) {
                ret = g_strats[sid].process_request(packet);
#ifndef EVALUATION
                if (ret) {
                    need_evaluation(&fourtp);
                }
#endif
            }

            cache_dns_tcp_request(&fourtp);
        }
        else if (sport == 53) {
            // Got a DNS response over TCP, maybe triggered by our app, or maybe not 
            log_debug("[TCP] Got a DNS response from %s:%d to %s:%d.", sip, sport, dip, dport);
            // parse the DNS response to get the first qname 
            const unsigned char *dns_payload = packet->payload + 2;
            struct mydnshdr *dnshdr = (struct mydnshdr*)dns_payload;
            unsigned short txn_id = htons(dnshdr->txn_id);
            int qdcount = ntohs(dnshdr->questions);
            char qname[MAX_QNAME_LEN];
            if (qdcount > 0) {
                //log_debug("Questions: %d", qdcount);
                unsigned char *ptr = (unsigned char *)(dnshdr + 1);
                {
                    struct mydnsquery query;
                    int j = 0, l;
                    while (1) {
                        for (l = *ptr++; l != 0; l--) {
                            query.qname[j++] = *ptr++;
                            if (j >= MAX_QNAME_LEN) {
                                while (*ptr != 0) ptr++;
                                break;
                            }
                        }
                        if (*ptr == 0) {
                            query.qname[j] = 0;
                            ptr++;
                            break;
                        }
                        query.qname[j++] = '.';
                    }
                    query.qtype = (ptr[0] << 8) + ptr[1];
                    query.qclass = (ptr[2] << 8) + ptr[3];
                    
                    log_debug("DNS Query: %s %d %d", query.qname, query.qtype, query.qclass);
    
                    // use the first query to calc hash 
                    qname[0] = 0;
                    strncat(qname, query.qname, MAX_QNAME_LEN - 1);
                }

                // Tell the caching thread to process the dns udp response
                // use DNS transaction ID and first query name as unique ID
                // transaction ID alone may cause collision 
                process_dns_tcp_response(txn_id, qname, &fourtp, tcphdr->th_seq, iphdr->ttl, packet->payload, packet->payload_len);

            }
        }
        else if (dport == opt_vpn_port) {
            // outgoing packet
            int sid = get_sid(&fourtp);
            if (sid >= 0 && g_strats[sid].process_request) {
                ret = g_strats[sid].process_request(packet);
                if (ret) {
                    if (opt_inject_syn_and_syn_ack_with_one_ttl == 1)
                        send_one_ttl_SYN(sip, sport, dip, dport, tcphdr->th_seq);
                    else if (opt_inject_syn_and_syn_ack_with_one_ttl == 2)
                        send_one_ttl_SYN_and_SYN_ACK(sip, sport, dip, dport, tcphdr->th_seq, tcphdr->th_ack);
                }
            }
        }
        else if (sport == opt_vpn_port) {
            // incomine packet
        }
        else if (dport == opt_tor_port) {
            // outgoing packet
            int sid = get_sid(&fourtp);
            if (sid >= 0 && g_strats[sid].process_request) {
                ret = g_strats[sid].process_request(packet);
                if (ret) {
                    if (opt_inject_syn_and_syn_ack_with_one_ttl == 1)
                        send_one_ttl_SYN(sip, sport, dip, dport, tcphdr->th_seq);
                    else if (opt_inject_syn_and_syn_ack_with_one_ttl == 2)
                        send_one_ttl_SYN_and_SYN_ACK(sip, sport, dip, dport, tcphdr->th_seq, tcphdr->th_ack);
                }
            }
        }
        else if (sport == opt_tor_port) {
            // incomine packet
        }
        else {
            // TODO: for all other protocols. This branch is a piece of temporary code, should be re-write.
            if (inout == 0) {
                // incoming packet
                log_debug("this is an incoming packet.");
            }
            else {
                // outgoing packet
                log_debug("this is an outgoing packet.");
                int sid = get_sid(&fourtp);
                if (sid >= 0 && g_strats[sid].process_request) {
                    ret = g_strats[sid].process_request(packet);
                    if (ret) {
                        if (opt_inject_syn_and_syn_ack_with_one_ttl == 1)
                            send_one_ttl_SYN(sip, sport, dip, dport, tcphdr->th_seq);
                        else if (opt_inject_syn_and_syn_ack_with_one_ttl == 2)
                            send_one_ttl_SYN_and_SYN_ACK(sip, sport, dip, dport, tcphdr->th_seq, tcphdr->th_ack);
                    }
                }
            }
        }
    }
    else if (tcphdr->th_flags & TCP_RST) {
        // Got an incoming RST 
        log_debug("[TCP] Got an incoming RST from %s:%d to %s:%d.", sip, sport, dip, dport);

        process_incoming_RST(packet);
    }

    return ret;
}