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; (void)done; 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); #ifdef USE_SSL if(conn->handler->flags & PROTOPT_SSL) { CURLcode res; res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone); if(res) return res; } #endif return CURLE_OK; }
static CURLcode smtp_state_upgrade_tls(struct connectdata *conn) { struct smtp_conn *smtpc = &conn->proto.smtpc; CURLcode result; result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); if(smtpc->ssldone) { smtp_to_smtps(conn); result = smtp_state_ehlo(conn); } return result; }
/* Called repeatedly until done from multi.c */ static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done) { struct smtp_conn *smtpc = &conn->proto.smtpc; CURLcode result; if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); else result = Curl_pp_multi_statemach(&smtpc->pp); *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE; return result; }
/* Called repeatedly until done from multi.c */ static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done) { CURLcode result = CURLE_OK; struct pop3_conn *pop3c = &conn->proto.pop3c; if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone); else result = Curl_pp_statemach(&pop3c->pp, FALSE); *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE; return result; }
static CURLcode imap_state_upgrade_tls(struct connectdata *conn) { struct imap_conn *imapc = &conn->proto.imapc; CURLcode result; result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone); if(imapc->ssldone) { imap_to_imaps(conn); result = imap_state_login(conn); } return result; }
/* Called repeatedly until done from multi.c */ static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done) { CURLcode result = CURLE_OK; struct smtp_conn *smtpc = &conn->proto.smtpc; if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) { result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); if(result || !smtpc->ssldone) return result; } result = Curl_pp_statemach(&smtpc->pp, false); *done = (smtpc->state == SMTP_STOP) ? true : false; return result; }
static CURLcode ldap_connect(struct connectdata *conn, bool *done) { ldapconninfo *li = conn->proto.generic; struct Curl_easy *data = conn->data; int rc, proto = LDAP_VERSION3; char hosturl[1024]; char *ptr; (void)done; 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); #ifdef CURL_OPENLDAP_DEBUG static int do_trace = 0; const char *env = getenv("CURL_OPENLDAP_TRACE"); do_trace = (env && strtol(env, NULL, 10) > 0); if(do_trace) { ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace); } #endif 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); #ifdef USE_SSL if(conn->handler->flags & PROTOPT_SSL) { CURLcode result; result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone); if(result) return result; } #endif return CURLE_OK; }
static CURLcode pop3_state_upgrade_tls(struct connectdata *conn) { struct pop3_conn *pop3c = &conn->proto.pop3c; CURLcode result; result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone); if(!result) { if(pop3c->state != POP3_UPGRADETLS) state(conn, POP3_UPGRADETLS); if(pop3c->ssldone) { pop3_to_pop3s(conn); result = pop3_state_capa(conn); } } return result; }
/*********************************************************************** * * smtp_perform_upgrade_tls() * * Performs the upgrade to TLS. */ static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn) { CURLcode result = CURLE_OK; struct smtp_conn *smtpc = &conn->proto.smtpc; /* Start the SSL connection */ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); if(!result) { if(smtpc->state != SMTP_UPGRADETLS) state(conn, SMTP_UPGRADETLS); if(smtpc->ssldone) { smtp_to_smtps(conn); result = smtp_perform_ehlo(conn); } } return result; }
/*********************************************************************** * * pop3_perform_upgrade_tls() * * Performs the upgrade to TLS. */ static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn) { CURLcode result = CURLE_OK; struct pop3_conn *pop3c = &conn->proto.pop3c; /* Start the SSL connection */ result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone); if(!result) { if(pop3c->state != POP3_UPGRADETLS) state(conn, POP3_UPGRADETLS); if(pop3c->ssldone) { pop3_to_pop3s(conn); result = pop3_perform_capa(conn); } } return result; }
/* * Perform SSL initialization for HTTPS proxy. Sets * proxy_ssl_connected connection bit when complete. Can be * called multiple times. */ static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex) { #ifdef USE_SSL CURLcode result = CURLE_OK; DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS); if(!conn->bits.proxy_ssl_connected[sockindex]) { /* perform SSL initialization for this socket */ result = Curl_ssl_connect_nonblocking(conn, sockindex, &conn->bits.proxy_ssl_connected[sockindex]); if(result) conn->bits.close = TRUE; /* a failed connection is marked for closure to prevent (bad) re-use or similar */ } return result; #else (void) conn; (void) sockindex; return CURLE_NOT_BUILT_IN; #endif }
static CURLcode ldap_connecting(struct connectdata *conn, bool *done) { ldapconninfo *li = conn->proto.generic; struct SessionHandle *data = conn->data; LDAPMessage *msg = NULL; struct timeval tv = {0, 1}, *tvp; int rc, err; char *info = NULL; #ifdef USE_SSL if(conn->handler->flags & PROTOPT_SSL) { /* Is the SSL handshake complete yet? */ if(!li->ssldone) { CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone); if(result || !li->ssldone) return result; } /* Have we installed the libcurl SSL handlers into the sockbuf yet? */ if(!li->sslinst) { Sockbuf *sb; ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb); ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn); li->sslinst = TRUE; li->recv = conn->recv[FIRSTSOCKET]; li->send = conn->send[FIRSTSOCKET]; } } #endif tvp = &tv; retry: if(!li->didbind) { char *binddn; struct berval passwd; if(conn->bits.user_passwd) { binddn = conn->user; passwd.bv_val = conn->passwd; passwd.bv_len = strlen(passwd.bv_val); } else { binddn = NULL; passwd.bv_val = NULL; passwd.bv_len = 0; } rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &li->msgid); if(rc) return CURLE_LDAP_CANNOT_BIND; li->didbind = TRUE; if(tvp) return CURLE_OK; } rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg); if(rc < 0) { failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc)); return CURLE_LDAP_CANNOT_BIND; } if(rc == 0) { /* timed out */ return CURLE_OK; } rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1); if(rc) { failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc)); return CURLE_LDAP_CANNOT_BIND; } /* Try to fallback to LDAPv2? */ if(err == LDAP_PROTOCOL_ERROR) { int proto; ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); if(proto == LDAP_VERSION3) { if(info) { ldap_memfree(info); info = NULL; } proto = LDAP_VERSION2; ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); li->didbind = FALSE; goto retry; } } if(err) { failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc), info ? info : ""); if(info) ldap_memfree(info); return CURLE_LOGIN_DENIED; } if(info) ldap_memfree(info); conn->recv[FIRSTSOCKET] = ldap_recv; *done = TRUE; return CURLE_OK; }
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; }