CURLcode Curl_proxy_connect(struct connectdata *conn) { if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { #ifndef CURL_DISABLE_PROXY /* for [protocol] tunneled through HTTP proxy */ struct HTTP http_proxy; void *prot_save; const char *hostname; int remote_port; CURLcode result; /* BLOCKING */ /* We want "seamless" operations through HTTP proxy tunnel */ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the * member conn->proto.http; we want [protocol] through HTTP and we have * to change the member temporarily for connecting to the HTTP * proxy. After Curl_proxyCONNECT we have to set back the member to the * original pointer * * This function might be called several times in the multi interface case * if the proxy's CONNTECT response is not instant. */ prot_save = conn->data->req.protop; memset(&http_proxy, 0, sizeof(http_proxy)); conn->data->req.protop = &http_proxy; connkeep(conn, "HTTP proxy CONNECT"); if(conn->bits.conn_to_host) hostname = conn->conn_to_host.name; else hostname = conn->host.name; if(conn->bits.conn_to_port) remote_port = conn->conn_to_port; else remote_port = conn->remote_port; result = Curl_proxyCONNECT(conn, FIRSTSOCKET, hostname, remote_port, FALSE); conn->data->req.protop = prot_save; if(CURLE_OK != result) return result; Curl_safefree(conn->allocptr.proxyuserpwd); #else return CURLE_NOT_BUILT_IN; #endif } /* no HTTP tunnel proxy, just return */ return CURLE_OK; }
/* * pop3_connect() should do everything that is to be considered a part of * the connection phase. * * The variable 'done' points to will be TRUE if the protocol-layer connect * phase is done when this function returns, or FALSE is not. When called as * a part of the easy interface, it will always be TRUE. */ static CURLcode pop3_connect(struct connectdata *conn, bool *done) /* see description above */ { CURLcode result; struct pop3_conn *pop3c = &conn->proto.pop3c; struct SessionHandle *data=conn->data; struct pingpong *pp = &pop3c->pp; *done = FALSE; /* default to not done yet */ /* If there already is a protocol-specific struct allocated for this sessionhandle, deal with it */ Curl_reset_reqproto(conn); result = pop3_init(conn); if(CURLE_OK != result) return result; /* We always support persistent connections on pop3 */ conn->bits.close = FALSE; pp->response_time = RESP_TIMEOUT; /* set default response time-out */ pp->statemach_act = pop3_statemach_act; pp->endofresp = pop3_endofresp; pp->conn = conn; if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { /* for POP3 over HTTP proxy */ struct HTTP http_proxy; struct FTP *pop3_save; /* BLOCKING */ /* We want "seamless" POP3 operations through HTTP proxy tunnel */ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member * conn->proto.http; we want POP3 through HTTP and we have to change the * member temporarily for connecting to the HTTP proxy. After * Curl_proxyCONNECT we have to set back the member to the original struct * POP3 pointer */ pop3_save = data->state.proto.pop3; memset(&http_proxy, 0, sizeof(http_proxy)); data->state.proto.http = &http_proxy; result = Curl_proxyCONNECT(conn, FIRSTSOCKET, conn->host.name, conn->remote_port); data->state.proto.pop3 = pop3_save; if(CURLE_OK != result) return result; } if(conn->handler->flags & PROTOPT_SSL) { /* BLOCKING */ result = Curl_ssl_connect(conn, FIRSTSOCKET); if(result) return result; } Curl_pp_init(pp); /* init the response reader stuff */ /* When we connect, we start in the state where we await the server greet response */ state(conn, POP3_SERVERGREET); if(data->state.used_interface == Curl_if_multi) result = pop3_multi_statemach(conn, done); else { result = pop3_easy_statemach(conn); if(!result) *done = TRUE; } return result; }
/* * smtp_connect() should do everything that is to be considered a part of * the connection phase. * * The variable 'done' points to will be TRUE if the protocol-layer connect * phase is done when this function returns, or FALSE is not. When called as * a part of the easy interface, it will always be TRUE. */ static CURLcode smtp_connect(struct connectdata *conn, bool *done) /* see description above */ { CURLcode result; struct smtp_conn *smtpc = &conn->proto.smtpc; struct SessionHandle *data=conn->data; struct pingpong *pp=&smtpc->pp; const char *path = conn->data->state.path; int len; char localhost[1024 + 1]; *done = FALSE; /* default to not done yet */ /* If there already is a protocol-specific struct allocated for this sessionhandle, deal with it */ Curl_reset_reqproto(conn); result = smtp_init(conn); if(CURLE_OK != result) return result; /* We always support persistant connections on smtp */ conn->bits.close = FALSE; pp->response_time = RESP_TIMEOUT; /* set default response time-out */ pp->statemach_act = smtp_statemach_act; pp->endofresp = smtp_endofresp; pp->conn = conn; #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { /* for SMTP over HTTP proxy */ struct HTTP http_proxy; struct FTP *smtp_save; /* BLOCKING */ /* We want "seamless" SMTP operations through HTTP proxy tunnel */ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member * conn->proto.http; we want SMTP through HTTP and we have to change the * member temporarily for connecting to the HTTP proxy. After * Curl_proxyCONNECT we have to set back the member to the original struct * SMTP pointer */ smtp_save = data->state.proto.smtp; memset(&http_proxy, 0, sizeof(http_proxy)); data->state.proto.http = &http_proxy; result = Curl_proxyCONNECT(conn, FIRSTSOCKET, conn->host.name, conn->remote_port); data->state.proto.smtp = smtp_save; if(CURLE_OK != result) return result; } #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */ if(conn->protocol & PROT_SMTPS) { /* BLOCKING */ /* SMTPS is simply smtp with SSL for the control channel */ /* now, perform the SSL initialization for this socket */ result = Curl_ssl_connect(conn, FIRSTSOCKET); if(result) return result; } Curl_pp_init(pp); /* init the response reader stuff */ pp->response_time = RESP_TIMEOUT; /* set default response time-out */ pp->statemach_act = smtp_statemach_act; pp->endofresp = smtp_endofresp; pp->conn = conn; if(!*path) { if(!Curl_gethostname(localhost, sizeof localhost)) path = localhost; else path = "localhost"; } /* url decode the path and use it as domain with EHLO */ smtpc->domain = curl_easy_unescape(conn->data, path, 0, &len); if(!smtpc->domain) return CURLE_OUT_OF_MEMORY; /* When we connect, we start in the state where we await the server greeting */ state(conn, SMTP_SERVERGREET); if(data->state.used_interface == Curl_if_multi) result = smtp_multi_statemach(conn, done); else { result = smtp_easy_statemach(conn); if(!result) *done = TRUE; } return result; }
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex) { if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) { const CURLcode result = https_proxy_connect(conn, sockindex); if(result) return result; if(!conn->bits.proxy_ssl_connected[sockindex]) return result; /* wait for HTTPS proxy SSL initialization to complete */ } if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { #ifndef CURL_DISABLE_PROXY /* for [protocol] tunneled through HTTP proxy */ struct HTTP http_proxy; void *prot_save; const char *hostname; int remote_port; CURLcode result; /* BLOCKING */ /* We want "seamless" operations through HTTP proxy tunnel */ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the * member conn->proto.http; we want [protocol] through HTTP and we have * to change the member temporarily for connecting to the HTTP * proxy. After Curl_proxyCONNECT we have to set back the member to the * original pointer * * This function might be called several times in the multi interface case * if the proxy's CONNECT response is not instant. */ prot_save = conn->data->req.protop; memset(&http_proxy, 0, sizeof(http_proxy)); conn->data->req.protop = &http_proxy; connkeep(conn, "HTTP proxy CONNECT"); /* for the secondary socket (FTP), use the "connect to host" * but ignore the "connect to port" (use the secondary port) */ if(conn->bits.conn_to_host) hostname = conn->conn_to_host.name; else if(sockindex == SECONDARYSOCKET) hostname = conn->secondaryhostname; else hostname = conn->host.name; if(sockindex == SECONDARYSOCKET) remote_port = conn->secondary_port; else if(conn->bits.conn_to_port) remote_port = conn->conn_to_port; else remote_port = conn->remote_port; result = Curl_proxyCONNECT(conn, sockindex, hostname, remote_port); conn->data->req.protop = prot_save; if(CURLE_OK != result) return result; Curl_safefree(conn->allocptr.proxyuserpwd); #else return CURLE_NOT_BUILT_IN; #endif } /* no HTTP tunnel proxy, just return */ return CURLE_OK; }
/* * imap_connect() should do everything that is to be considered a part of * the connection phase. * * The variable 'done' points to will be TRUE if the protocol-layer connect * phase is done when this function returns, or FALSE is not. When called as * a part of the easy interface, it will always be TRUE. */ static CURLcode imap_connect(struct connectdata *conn, bool *done) /* see description above */ { CURLcode result; struct imap_conn *imapc = &conn->proto.imapc; struct SessionHandle *data=conn->data; struct pingpong *pp = &imapc->pp; *done = FALSE; /* default to not done yet */ /* If there already is a protocol-specific struct allocated for this sessionhandle, deal with it */ Curl_reset_reqproto(conn); result = imap_init(conn); if(CURLE_OK != result) return result; /* We always support persistant connections on imap */ conn->bits.close = FALSE; pp->response_time = RESP_TIMEOUT; /* set default response time-out */ pp->statemach_act = imap_statemach_act; pp->endofresp = imap_endofresp; pp->conn = conn; #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { /* for IMAP over HTTP proxy */ struct HTTP http_proxy; struct FTP *imap_save; /* BLOCKING */ /* We want "seamless" IMAP operations through HTTP proxy tunnel */ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member * conn->proto.http; we want IMAP through HTTP and we have to change the * member temporarily for connecting to the HTTP proxy. After * Curl_proxyCONNECT we have to set back the member to the original struct * IMAP pointer */ imap_save = data->state.proto.imap; memset(&http_proxy, 0, sizeof(http_proxy)); data->state.proto.http = &http_proxy; result = Curl_proxyCONNECT(conn, FIRSTSOCKET, conn->host.name, conn->remote_port); data->state.proto.imap = imap_save; if(CURLE_OK != result) return result; } #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */ if(conn->protocol & PROT_IMAPS) { /* BLOCKING */ /* IMAPS is simply imap with SSL for the control channel */ /* now, perform the SSL initialization for this socket */ result = Curl_ssl_connect(conn, FIRSTSOCKET); if(result) return result; } Curl_pp_init(pp); /* init generic pingpong data */ /* When we connect, we start in the state where we await the server greeting response */ state(conn, IMAP_SERVERGREET); imapc->idstr = "*"; /* we start off waiting for a '*' response */ if(data->state.used_interface == Curl_if_multi) result = imap_multi_statemach(conn, done); else { result = imap_easy_statemach(conn); if(!result) *done = TRUE; } return result; }
static CURLcode ldap_connect(struct connectdata *conn, bool *done) { ldapconninfo *li = conn->proto.generic; struct SessionHandle *data=conn->data; int rc, proto = LDAP_VERSION3; char hosturl[1024], *ptr; strcpy(hosturl, "ldap"); ptr = hosturl+4; if (conn->handler->flags & PROTOPT_SSL) *ptr++ = 's'; snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d", conn->host.name, conn->remote_port); rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld); if (rc) { failf(data, "LDAP local: Cannot connect to %s, %s", hosturl, ldap_err2string(rc)); return CURLE_COULDNT_CONNECT; } ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { /* for LDAP over HTTP proxy */ struct HTTP http_proxy; ldapconninfo *li_save; CURLcode result; /* BLOCKING */ /* We want "seamless" LDAP operations through HTTP proxy tunnel */ /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member * conn->proto.http; we want LDAP through HTTP and we have to change the * member temporarily for connecting to the HTTP proxy. After * Curl_proxyCONNECT we have to set back the member to the original struct * LDAP pointer */ li_save = data->state.proto.generic; memset(&http_proxy, 0, sizeof(http_proxy)); data->state.proto.http = &http_proxy; result = Curl_proxyCONNECT(conn, FIRSTSOCKET, conn->host.name, conn->remote_port); data->state.proto.generic = li_save; if(CURLE_OK != result) return result; } #ifdef USE_SSL if (conn->handler->flags & PROTOPT_SSL) { CURLcode res; if (data->state.used_interface == Curl_if_easy) { res = Curl_ssl_connect(conn, FIRSTSOCKET); if (res) return res; li->ssldone = TRUE; } else { res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone); if (res) return res; } } #endif if (data->state.used_interface == Curl_if_easy) return ldap_connecting(conn, done); return CURLE_OK; }