X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=dbc5e115dee7014db26cb638ab79211c8d2ecf18;hp=5f7a1fd37cd7a96f4bac93ce9204765fc3c954f8;hb=57702318b095358ffe8fa3a99ec330d7aed3fca3;hpb=565187f94976db71fc5be074862af1ebb5afd77c diff --git a/jcc.c b/jcc.c index 5f7a1fd3..dbc5e115 100644 --- a/jcc.c +++ b/jcc.c @@ -62,10 +62,8 @@ #else /* ifndef _WIN32 */ -# if !defined (__OS2__) # include # include -# endif /* ndef __OS2__ */ # include # include # include @@ -86,14 +84,6 @@ # include /* declarations for threads and stuff. */ # endif -# if defined(__EMX__) || defined(__OS2__) -# include /* OS/2/EMX needs a little help with select */ -# endif -# ifdef __OS2__ -#define INCL_DOS -# include -# endif - #ifdef HAVE_POLL #ifdef __GLIBC__ #include @@ -143,7 +133,7 @@ int urls_rejected = 0; /* total nr of urls rejected */ int g_terminate = 0; #endif -#if !defined(_WIN32) && !defined(__OS2__) +#if !defined(_WIN32) static void sig_handler(int the_signal); #endif static int client_protocol_is_unsupported(struct client_state *csp, char *req); @@ -177,10 +167,6 @@ static int32 server_thread(void *data); #define sleep(N) Sleep(((N) * 1000)) #endif -#ifdef __OS2__ -#define sleep(N) DosSleep(((N) * 100)) -#endif - #ifdef FUZZ int process_fuzzed_input(char *fuzz_input_type, char *fuzz_input_file); void show_fuzz_usage(const char *name); @@ -347,7 +333,7 @@ static const struct cruncher crunchers_light[] = { * * here? */ -#if !defined(_WIN32) && !defined(__OS2__) +#if !defined(_WIN32) /********************************************************************* * * Function : sig_handler @@ -857,7 +843,7 @@ static void send_crunch_response(struct client_state *csp, struct http_response { log_error(LOG_LEVEL_CRUNCH, "%s: https://%s%s", crunch_reason(rsp), http->hostport, http->path); - log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" %s %llu", + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" %s %lu", csp->ip_addr_str, http->gpc, http->hostport, http->path, http->version, status_code, rsp->content_length); } @@ -865,7 +851,7 @@ static void send_crunch_response(struct client_state *csp, struct http_response #endif { log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url); - log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u", + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %lu", csp->ip_addr_str, http->ocmd, status_code, rsp->content_length); } /* Write the answer to the client */ @@ -881,8 +867,8 @@ static void send_crunch_response(struct client_state *csp, struct http_response { /* There is nothing we can do about it. */ log_error(LOG_LEVEL_CONNECT, "Couldn't deliver the error message " - "for %s through client socket %d using TLS/SSL", - http->url, csp->cfd); + "for https://%s%s through client socket %d using TLS/SSL", + http->hostport, http->url, csp->cfd); } } else @@ -1190,6 +1176,22 @@ void save_connection_destination(jb_socket sfd, server_connection->gateway_host = NULL; } server_connection->gateway_port = fwd->gateway_port; + if (NULL != fwd->auth_username) + { + server_connection->auth_username = strdup_or_die(fwd->auth_username); + } + else + { + server_connection->auth_username = NULL; + } + if (NULL != fwd->auth_password) + { + server_connection->auth_password = strdup_or_die(fwd->auth_password); + } + else + { + server_connection->auth_password = NULL; + } if (NULL != fwd->forward_host) { @@ -1562,7 +1564,7 @@ static jb_err receive_chunked_client_request_body(struct client_state *csp) return JB_ERR_PARSE; } log_error(LOG_LEVEL_CONNECT, - "Chunked client body completely read. Length: %d", body_length); + "Chunked client body completely read. Length: %lu", body_length); csp->expected_client_content_length = body_length; return JB_ERR_OK; @@ -2166,21 +2168,21 @@ static int send_https_request(struct client_state *csp) csp->http->hostport); return 1; } - if (flushed != 0) + if (flushed != 0 || csp->expected_client_content_length != 0) { if (csp->expected_client_content_length != 0) { if (csp->expected_client_content_length < flushed) { log_error(LOG_LEVEL_ERROR, - "Flushed %d bytes of request body while only expecting %llu", + "Flushed %ld bytes of request body while only expecting %llu", flushed, csp->expected_client_content_length); csp->expected_client_content_length = 0; } else { log_error(LOG_LEVEL_CONNECT, - "Flushed %d bytes of request body while expecting %llu", + "Flushed %ld bytes of request body while expecting %llu", flushed, csp->expected_client_content_length); csp->expected_client_content_length -= (unsigned)flushed; if (receive_and_send_encrypted_post_data(csp)) @@ -2192,7 +2194,7 @@ static int send_https_request(struct client_state *csp) else { log_error(LOG_LEVEL_CONNECT, - "Flushed %d bytes of request body", flushed); + "Flushed %ld bytes of request body", flushed); } } @@ -2290,7 +2292,8 @@ static jb_err process_encrypted_request(struct client_state *csp) err = receive_encrypted_request(csp); if (err != JB_ERR_OK) { - if (csp->client_iob->cur == NULL) + if (csp->client_iob->cur == NULL || + csp->client_iob->cur == csp->client_iob->eod) { /* * We did not receive any data, most likely because the @@ -2486,14 +2489,13 @@ static int cgi_page_requested(const char *host) * failures etc. * * If a connection to the server has already been - * opened it is reused unless the request is blocked. + * opened it is reused unless the request is blocked + * or the forwarder changed. * * If a connection to the server has not yet been - * opened (because the previous request was crunched) - * the connection is dropped so that the client retries - * on a fresh one. - * - * XXX: Forwarding settings are currently ignored. + * opened (because the previous request was crunched), + * or the forwarder changed, the connection is dropped + * so that the client retries on a fresh one. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -2503,6 +2505,8 @@ static int cgi_page_requested(const char *host) *********************************************************************/ static void continue_https_chat(struct client_state *csp) { + const struct forward_spec *fwd; + if (JB_ERR_OK != process_encrypted_request(csp)) { return; @@ -2529,6 +2533,24 @@ static void continue_https_chat(struct client_state *csp) csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; return; } + assert(csp->server_connection.sfd != JB_INVALID_SOCKET); + + fwd = forward_url(csp, csp->http); + if (!connection_destination_matches(&csp->server_connection, csp->http, fwd)) + { + log_error(LOG_LEVEL_CONNECT, + "Dropping the client connection on socket %d with " + "server socket %d connected to %s. The forwarder has changed.", + csp->cfd, csp->server_connection.sfd, csp->server_connection.host); + csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; + return; + } + + log_error(LOG_LEVEL_CONNECT, + "Reusing server socket %d connected to %s. Requests already sent: %u.", + csp->server_connection.sfd, csp->server_connection.host, + csp->server_connection.requests_sent_total); + if (send_https_request(csp)) { /* @@ -2542,6 +2564,7 @@ static void continue_https_chat(struct client_state *csp) csp->cfd); return; } + csp->server_connection.requests_sent_total++; handle_established_connection(csp); freez(csp->receive_buffer); } @@ -2631,15 +2654,7 @@ static void handle_established_connection(struct client_state *csp) for (;;) { #ifndef HAVE_POLL -#ifdef __OS2__ - /* - * FD_ZERO here seems to point to an errant macro which crashes. - * So do this by hand for now... - */ - memset(&rfds,0x00,sizeof(fd_set)); -#else FD_ZERO(&rfds); -#endif #ifdef FEATURE_CONNECTION_KEEP_ALIVE if (!watch_client_socket) { @@ -2678,14 +2693,14 @@ static void handle_established_connection(struct client_state *csp) { log_error(LOG_LEVEL_CONNECT, "Done reading from server. Content length: %llu as expected. " - "Bytes most recently read: %d.", + "Bytes most recently read: %ld.", byte_count, len); } else { log_error(LOG_LEVEL_CONNECT, "Done reading from server. Expected content length: %llu. " - "Actual content length: %llu. Bytes most recently read: %d.", + "Actual content length: %llu. Bytes most recently read: %ld.", csp->expected_content_length, byte_count, len); } len = 0; @@ -2826,6 +2841,37 @@ static void handle_established_connection(struct client_state *csp) #ifdef FEATURE_HTTPS_INSPECTION if (client_use_ssl(csp)) { + if (csp->http->status == 101) + { + len = ssl_recv_data(&(csp->ssl_client_attr), + (unsigned char *)csp->receive_buffer, + (size_t)max_bytes_to_read); + if (len == -1) + { + log_error(LOG_LEVEL_ERROR, "Failed to receive data " + "on client socket %d for an upgraded connection", + csp->cfd); + break; + } + if (len == 0) + { + log_error(LOG_LEVEL_CONNECT, "Done receiving data " + "on client socket %d for an upgraded connection", + csp->cfd); + break; + } + byte_count += (unsigned long long)len; + len = ssl_send_data(&(csp->ssl_server_attr), + (unsigned char *)csp->receive_buffer, (size_t)len); + if (len == -1) + { + log_error(LOG_LEVEL_ERROR, "Failed to send data " + "on server socket %d for an upgraded connection", + csp->server_connection.sfd); + break; + } + continue; + } log_error(LOG_LEVEL_CONNECT, "Breaking with TLS/SSL."); break; } @@ -2848,7 +2894,7 @@ static void handle_established_connection(struct client_state *csp) csp->expected_client_content_length -= (unsigned)len; log_error(LOG_LEVEL_CONNECT, "Expected client content length set to %llu " - "after reading %d bytes.", + "after reading %ld bytes.", csp->expected_client_content_length, len); if (csp->expected_client_content_length == 0) { @@ -3322,7 +3368,7 @@ static void handle_established_connection(struct client_state *csp) */ log_error(LOG_LEVEL_CONNECT, "Continuing buffering server headers from socket %d. " - "Bytes most recently read: %d.", csp->cfd, len); + "Bytes most recently read: %ld.", csp->cfd, len); continue; } } @@ -3667,12 +3713,6 @@ static void chat(struct client_state *csp) /* decide how to route the HTTP request */ fwd = forward_url(csp, http); - if (NULL == fwd) - { - log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!? This can't happen!"); - /* Never get here - LOG_LEVEL_FATAL causes program exit */ - return; - } #ifdef FEATURE_HTTPS_INSPECTION /* @@ -3874,7 +3914,6 @@ static void chat(struct client_state *csp) } if (JB_ERR_OK != process_encrypted_request(csp)) { - log_error(LOG_LEVEL_ERROR, "Failed to parse encrypted request."); close_client_ssl_connection(csp); return; } @@ -4111,10 +4150,12 @@ static void chat(struct client_state *csp) else { /* - * If server certificate is invalid, we must inform client and then - * close connection with client. + * If server certificate has been verified and is invalid, + * we must inform the client and then close the connection + * with client and server. */ - if (csp->server_cert_verification_result != SSL_CERT_VALID) + if (csp->server_cert_verification_result != SSL_CERT_VALID && + csp->server_cert_verification_result != SSL_CERT_NOT_VERIFIED) { ssl_send_certificate_error(csp); close_client_and_server_ssl_connections(csp); @@ -4262,7 +4303,7 @@ static void prepare_csp_for_next_request(struct client_state *csp) assert(bytes_to_shift > 0); assert(data_length > 0); - log_error(LOG_LEVEL_CONNECT, "Shifting %d pipelined bytes by %d bytes", + log_error(LOG_LEVEL_CONNECT, "Shifting %lu pipelined bytes by %ld bytes", data_length, bytes_to_shift); memmove(csp->client_iob->buf, csp->client_iob->cur, data_length); csp->client_iob->cur = csp->client_iob->buf; @@ -4496,6 +4537,20 @@ static void serve(struct client_state *csp) chat(csp); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + if (csp->cfd != JB_INVALID_SOCKET) + { + log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. " + "Keep-alive: %u. Socket alive: %u. Data available: %u. " + "Configuration file change detected: %u. Requests received: %u.", + csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE), + socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0), + config_file_change_detected, csp->requests_received_total); +#ifdef FEATURE_HTTPS_INSPECTION + close_client_ssl_connection(csp); +#endif + drain_and_close_socket(csp->cfd); + } + if (csp->server_connection.sfd != JB_INVALID_SOCKET) { #ifdef FEATURE_CONNECTION_SHARING @@ -4516,20 +4571,6 @@ static void serve(struct client_state *csp) mark_connection_closed(&csp->server_connection); #endif - if (csp->cfd != JB_INVALID_SOCKET) - { - log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. " - "Keep-alive: %u. Socket alive: %u. Data available: %u. " - "Configuration file change detected: %u. Requests received: %u.", - csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE), - socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0), - config_file_change_detected, csp->requests_received_total); -#ifdef FEATURE_HTTPS_INSPECTION - close_client_ssl_connection(csp); -#endif - drain_and_close_socket(csp->cfd); - } - free_csp_resources(csp); csp->flags &= ~CSP_FLAG_ACTIVE; @@ -5013,7 +5054,7 @@ int main(int argc, char **argv) * are handled when and where they occur without relying * on a signal. */ -#if !defined(_WIN32) && !defined(__OS2__) +#if !defined(_WIN32) { int idx; const int catched_signals[] = { SIGTERM, SIGINT, SIGHUP }; @@ -5475,7 +5516,7 @@ static void listen_loop(void) for (;;) #endif { -#if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) +#if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) while (waitpid(-1, NULL, WNOHANG) > 0) { /* zombie children */ @@ -5505,7 +5546,7 @@ static void listen_loop(void) csp = &csp_list->csp; log_error(LOG_LEVEL_CONNECT, - "Waiting for the next client connection. Currently active threads: %d", + "Waiting for the next client connection. Currently active threads: %u", active_threads); /* @@ -5604,10 +5645,11 @@ static void listen_loop(void) #define SELECTED_ONE_OPTION { pthread_t the_thread; + int ret; - errno = pthread_create(&the_thread, &attrs, + ret = pthread_create(&the_thread, &attrs, (void * (*)(void *))serve, csp); - child_id = errno ? -1 : 0; + child_id = ret ? -1 : 0; } #endif @@ -5619,15 +5661,6 @@ static void listen_loop(void) csp); #endif -#if defined(__OS2__) && !defined(SELECTED_ONE_OPTION) -#define SELECTED_ONE_OPTION - child_id = _beginthread( - (void(* _Optlink)(void*))serve, - NULL, - 64 * 1024, - csp); -#endif - #if defined(__BEOS__) && !defined(SELECTED_ONE_OPTION) #define SELECTED_ONE_OPTION { @@ -5730,7 +5763,7 @@ static void listen_loop(void) * XXX: If you assume ... */ log_error(LOG_LEVEL_ERROR, - "Unable to take any additional connections: %E. Active threads: %d", + "Unable to take any additional connections: %E. Active threads: %u", active_threads); write_socket_delayed(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE, strlen(TOO_MANY_CONNECTIONS_RESPONSE), get_write_delay(csp));