CURLcode Curl_creds_create(const char *user,
const char *passwd,
- const char *sasl_authzid,
const char *oauth_bearer,
+ const char *sasl_authzid,
+ const char *sasl_service,
uint8_t source,
struct Curl_creds **pcreds)
{
struct Curl_creds *creds = NULL;
size_t ulen = user ? strlen(user) : 0;
size_t plen = passwd ? strlen(passwd) : 0;
- size_t salen = sasl_authzid ? strlen(sasl_authzid) : 0;
size_t olen = oauth_bearer ? strlen(oauth_bearer) : 0;
+ size_t salen = sasl_authzid ? strlen(sasl_authzid) : 0;
+ size_t sslen = sasl_service ? strlen(sasl_service) : 0;
char *s, *buf;
CURLcode result = CURLE_OK;
Curl_creds_unlink(pcreds);
/* Everything empty/NULL, this is the NULL credential */
- if(!ulen && !plen && !salen && !olen)
+ if(!ulen && !plen && !olen && !salen && !sslen)
goto out;
if((ulen > CURL_MAX_INPUT_LENGTH) ||
(plen > CURL_MAX_INPUT_LENGTH) ||
+ (olen > CURL_MAX_INPUT_LENGTH) ||
(salen > CURL_MAX_INPUT_LENGTH) ||
- (olen > CURL_MAX_INPUT_LENGTH)) {
+ (sslen > CURL_MAX_INPUT_LENGTH)) {
result = CURLE_BAD_FUNCTION_ARGUMENT;
goto out;
}
/* NUL terminator for user already part of struct */
creds = curlx_calloc(1, sizeof(*creds) +
- ulen + plen + 1 + salen + 1 + olen + 1);
+ ulen + plen + 1 + olen + 1 + salen + 1 + sslen + 1);
if(!creds) {
result = CURLE_OUT_OF_MEMORY;
goto out;
creds->passwd = s = buf + ulen + 1;
if(plen)
memcpy(s, CURL_UNCONST(passwd), plen + 1);
- creds->sasl_authzid = s = buf + ulen + 1 + plen + 1;
- if(salen)
- memcpy(s, CURL_UNCONST(sasl_authzid), salen + 1);
- creds->oauth_bearer = s = buf + ulen + 1 + plen + 1 + salen + 1;
+ creds->oauth_bearer = s = buf + ulen + 1 + plen + 1;
if(olen)
memcpy(s, CURL_UNCONST(oauth_bearer), olen + 1);
+ creds->sasl_authzid = s = buf + ulen + 1 + plen + 1 + olen + 1;
+ if(salen)
+ memcpy(s, CURL_UNCONST(sasl_authzid), salen + 1);
+ creds->sasl_service = s = buf + ulen + 1 + plen + 1 + olen + 1 + salen + 1;
+ if(sslen)
+ memcpy(s, CURL_UNCONST(sasl_service), sslen + 1);
out:
if(!result)
if(!passwd || !passwd[0])
passwd = Curl_creds_passwd(creds_in);
result = Curl_creds_create(user, passwd,
- Curl_creds_sasl_authzid(creds_in),
Curl_creds_oauth_bearer(creds_in),
+ Curl_creds_sasl_authzid(creds_in),
+ Curl_creds_sasl_service(creds_in),
source, &creds_out);
Curl_creds_link(pcreds_out, creds_out);
Curl_creds_unlink(&creds_out);
(c1 && c2 &&
!Curl_timestrcmp(c1->user, c2->user) &&
!Curl_timestrcmp(c1->passwd, c2->passwd) &&
+ !Curl_timestrcmp(c1->oauth_bearer, c2->oauth_bearer) &&
!Curl_timestrcmp(c1->sasl_authzid, c2->sasl_authzid) &&
- !Curl_timestrcmp(c1->oauth_bearer, c2->oauth_bearer));
+ !Curl_timestrcmp(c1->sasl_service, c2->sasl_service));
}
#ifdef CURLVERBOSE
struct Curl_creds {
const char *user; /* non-NULL, maybe empty string */
const char *passwd; /* non-NULL, maybe empty string */
- const char *sasl_authzid; /* non-NULL, maybe empty string */
const char *oauth_bearer; /* non-NULL, maybe empty string */
+ const char *sasl_authzid; /* non-NULL, maybe empty string */
+ const char *sasl_service; /* non-NULL, maybe empty string */
uint32_t refcount;
uint8_t source; /* CREDS_* value */
char buf[1];
CURLcode Curl_creds_create(const char *user,
const char *passwd,
- const char *sasl_authzid,
const char *oauth_bearer,
+ const char *sasl_authzid,
+ const char *sasl_service,
uint8_t source,
struct Curl_creds **pcreds);
#define Curl_creds_has_user(c) ((c) && (c)->user[0])
#define Curl_creds_has_passwd(c) ((c) && (c)->passwd[0])
#define Curl_creds_has_oauth_bearer(c) ((c) && (c)->oauth_bearer[0])
+#define Curl_creds_has_sasl_service(c) ((c) && (c)->sasl_service[0])
#define Curl_creds_user(c) ((c)? (c)->user : "")
#define Curl_creds_passwd(c) ((c)? (c)->passwd : "")
-#define Curl_creds_sasl_authzid(c) ((c)? (c)->sasl_authzid : "")
#define Curl_creds_oauth_bearer(c) ((c)? (c)->oauth_bearer : "")
-
+#define Curl_creds_sasl_authzid(c) ((c)? (c)->sasl_authzid : "")
+#define Curl_creds_sasl_service(c) ((c)? (c)->sasl_service : "")
#ifdef CURLVERBOSE
void Curl_creds_trace(struct Curl_easy *data, struct Curl_creds *creds,
if((sctx->enabledmechs & SASL_MECH_GSSAPI) &&
Curl_auth_is_gssapi_supported() &&
Curl_auth_user_contains_domain(sctx->conn->creds)) {
- const char *service = data->set.str[STRING_SERVICE_NAME] ?
- data->set.str[STRING_SERVICE_NAME] :
- sctx->sasl->params->service;
+ const char *service = Curl_creds_has_sasl_service(sctx->conn->creds) ?
+ Curl_creds_sasl_service(sctx->conn->creds) : sctx->sasl->params->service;
sctx->sasl->mutual_auth = FALSE;
sctx->mech = SASL_MECH_STRING_GSSAPI;
{
if((sctx->enabledmechs & SASL_MECH_NTLM) &&
Curl_auth_is_ntlm_supported()) {
- const char *service = data->set.str[STRING_SERVICE_NAME] ?
- data->set.str[STRING_SERVICE_NAME] :
- sctx->sasl->params->service;
+ const char *service = Curl_creds_has_sasl_service(sctx->conn->creds) ?
+ Curl_creds_sasl_service(sctx->conn->creds) : sctx->sasl->params->service;
const char *hostname;
Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, NULL);
struct bufref resp;
const char *hostname;
int port;
-#if defined(USE_KERBEROS5) || defined(USE_NTLM) || \
- !defined(CURL_DISABLE_DIGEST_AUTH)
- const char *service = data->set.str[STRING_SERVICE_NAME] ?
- data->set.str[STRING_SERVICE_NAME] :
- sasl->params->service;
-#endif
struct bufref serverdata;
Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
result = get_server_message(sasl, data, &serverdata);
if(!result)
result = Curl_auth_create_digest_md5_message(data, &serverdata,
- conn->creds, service,
+ conn->creds,
+ sasl->params->service,
&resp);
if(!result && (sasl->params->flags & SASL_FLAG_BASE64))
newstate = SASL_DIGESTMD5_RESP;
struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE);
result = !ntlm ? CURLE_OUT_OF_MEMORY :
Curl_auth_create_ntlm_type1_message(data, conn->creds,
- service, hostname,
+ sasl->params->service, hostname,
ntlm, &resp);
newstate = SASL_NTLM_TYPE2MSG;
break;
struct kerberos5data *krb5 = Curl_auth_krb5_get(conn);
result = !krb5 ? CURLE_OUT_OF_MEMORY :
Curl_auth_create_gssapi_user_message(data, conn->creds,
- service, conn->origin->hostname,
+ sasl->params->service,
+ conn->origin->hostname,
(bool)sasl->mutual_auth, NULL,
krb5, &resp);
newstate = SASL_GSSAPI_TOKEN;
CURLcode result;
size_t len;
- /* Point to the username, password, service and host */
+ /* Point to credentials and host */
struct Curl_creds *creds = NULL;
- const char *service;
const char *host;
/* Point to the correct struct with this */
if(proxy) {
#ifndef CURL_DISABLE_PROXY
creds = conn->http_proxy.creds;
- service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
- data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
host = conn->http_proxy.peer->hostname;
state = conn->proxy_negotiate_state;
#else
}
else {
creds = data->state.creds;
- service = data->set.str[STRING_SERVICE_NAME] ?
- data->set.str[STRING_SERVICE_NAME] : "HTTP";
host = conn->origin->hostname;
state = conn->http_negotiate_state;
}
#endif /* GSS_C_CHANNEL_BOUND_FLAG */
/* Initialize the security context and decode our challenge */
- result = Curl_auth_decode_spnego_message(data, creds, service,
+ result = Curl_auth_decode_spnego_message(data, creds, "HTTP",
host, header, neg_ctx);
#ifdef GSS_C_CHANNEL_BOUND_FLAG
server, which is for a plain host or for an HTTP proxy */
char **allocuserpwd;
- /* point to credentials, service and host */
+ /* point to credentials and host */
struct Curl_creds *creds = NULL;
- const char *service = NULL;
const char *hostname = NULL;
/* point to the correct struct with this */
#ifndef CURL_DISABLE_PROXY
allocuserpwd = &data->req.hd_proxy_auth;
creds = conn->http_proxy.creds;
- service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
- data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
hostname = conn->http_proxy.peer->hostname;
state = &conn->proxy_ntlm_state;
authp = &data->state.authproxy;
else {
allocuserpwd = &data->req.hd_auth;
creds = data->state.creds;
- service = data->set.str[STRING_SERVICE_NAME] ?
- data->set.str[STRING_SERVICE_NAME] : "HTTP";
hostname = conn->origin->hostname;
state = &conn->http_ntlm_state;
authp = &data->state.authhost;
switch(*state) {
case NTLMSTATE_TYPE1:
- default: /* for the weird cases we (re)start here */
+ default: /* for the weird cases we (re)start here */
if(!proxy) {
/* Start it up. From this time onwards, the connection is tied
* tp the credentials used. */
}
Curl_creds_link(&conn->creds, creds);
}
- result = Curl_auth_create_ntlm_type1_message(data, creds, service,
+ result = Curl_auth_create_ntlm_type1_message(data, creds, "HTTP",
hostname, ntlm, &ntlmmsg);
if(!result) {
DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0);
/* Check we have a username and password to authenticate with and end the
connect phase if we do not */
- if(!data->state.creds) {
+ if(!conn->creds) {
imap_state(data, imapc, IMAP_STOP);
return result;
/* success without a password, set a blank one */
const char *passwd = ns->password ? ns->password : "";
- if(Curl_creds_create(login, passwd, NULL, NULL, CREDS_NETRC, pcreds)) {
+ if(Curl_creds_create(login, passwd, NULL, NULL, NULL, CREDS_NETRC,
+ pcreds)) {
retcode = NETRC_OUT_OF_MEMORY;
goto out;
}
passwd.bv_val = NULL;
passwd.bv_len = 0;
- if(data->state.creds) {
+ if(conn->creds) {
binddn = Curl_creds_user(conn->creds);
passwd.bv_val = CURL_UNCONST(Curl_creds_passwd(conn->creds));
passwd.bv_len = strlen(passwd.bv_val);
/* Check we have a username and password to authenticate with and end the
connect phase if we do not */
- if(!data->state.creds) {
+ if(!conn->creds) {
pop3_state(data, POP3_STOP);
return result;
case SOCKS5_ST_GSSAPI_INIT: {
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
/* GSSAPI stuff done non-blocking */
- CURLcode result = Curl_SOCKS5_gssapi_negotiate(cf, data);
+ CURLcode result = Curl_SOCKS5_gssapi_negotiate(cf, data, sx->creds);
if(result) {
failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
return CURLPX_GSSAPI;
* This function handles the SOCKS5 GSS-API negotiation and initialization
*/
CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf,
- struct Curl_easy *data);
+ struct Curl_easy *data,
+ struct Curl_creds *creds);
#endif
/* Insert a SOCKS filter after `cf_at` for connecting to `dest`.
}
CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ struct Curl_easy *data,
+ struct Curl_creds *creds)
{
struct connectdata *conn = cf->conn;
curl_socket_t sock = conn->sock[cf->sockindex];
CURLcode result;
OM_uint32 gss_ret_flags = 0;
gss_name_t server = GSS_C_NO_NAME;
- const char *serviceptr =
- data->set.str[STRING_PROXY_SERVICE_NAME] ?
- data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd";
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : "rcmd";
gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
- result = socks5_gss_create_service_name(data, conn, serviceptr, &server);
+ result = socks5_gss_create_service_name(data, conn, service, &server);
if(!result) {
(void)curlx_nonblock(sock, FALSE);
result = socks5_gss_auth_loop(cf, data, &server, &gss_context,
/* This is the SSPI-using version of this function */
static CURLcode socks5_sspi_setup(struct Curl_cfilter *cf,
struct Curl_easy *data,
+ struct Curl_creds *creds,
CredHandle *cred_handle,
char **service_namep)
{
struct connectdata *conn = cf->conn;
- const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
- data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd";
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : "rcmd";
SECURITY_STATUS status;
/* prepare service name */
}
CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf,
- struct Curl_easy *data)
+ struct Curl_easy *data,
+ struct Curl_creds *creds)
{
struct connectdata *conn = cf->conn;
curl_socket_t sock = conn->sock[cf->sockindex];
memset(&sspi_context, 0, sizeof(sspi_context));
names.sUserName = NULL;
- result = socks5_sspi_setup(cf, data, &cred_handle, &service_name);
+ result = socks5_sspi_setup(cf, data, creds, &cred_handle, &service_name);
if(result)
goto error;
Curl_peer_same_destination(data->state.initial_origin, conn->origin))) {
result = Curl_creds_create(data->set.str[STRING_USERNAME],
data->set.str[STRING_PASSWORD],
- data->set.str[STRING_SASL_AUTHZID],
data->set.str[STRING_BEARER],
+ data->set.str[STRING_SASL_AUTHZID],
+ data->set.str[STRING_SERVICE_NAME],
CREDS_OPTION, &data->state.creds);
if(result)
return result;
if(proxyuser || proxypasswd) {
result = Curl_creds_create(proxyuser, proxypasswd, NULL, NULL,
+ data->set.str[STRING_PROXY_SERVICE_NAME],
CREDS_URL, &proxyinfo->creds);
if(result)
goto error;
}
else if(!for_pre_proxy &&
(data->set.str[STRING_PROXYUSERNAME] ||
- data->set.str[STRING_PROXYPASSWORD])) {
+ data->set.str[STRING_PROXYPASSWORD] ||
+ data->set.str[STRING_PROXY_SERVICE_NAME])) {
/* No user/passwd in URL, if this is not a pre-proxy, the
* CURLOPT_PROXY* settings apply. */
result = Curl_creds_create(data->set.str[STRING_PROXYUSERNAME],
data->set.str[STRING_PROXYPASSWORD],
NULL, NULL,
+ data->set.str[STRING_PROXY_SERVICE_NAME],
CREDS_OPTION, &proxyinfo->creds);
}
else
if(data->set.use_netrc == CURL_NETRC_REQUIRED) {
/* use the URL user to search netrc */
result = Curl_creds_create(
- data->state.creds->user, NULL, NULL, NULL, CREDS_URL, &ncreds_in);
+ data->state.creds->user, NULL, NULL, NULL, NULL, CREDS_URL,
+ &ncreds_in);
if(result)
goto out;
}
Curl_creds_link(&conn->creds, data->state.creds);
else
return Curl_creds_create(CURL_DEFAULT_USER, CURL_DEFAULT_PASSWORD,
- NULL, NULL, CREDS_NONE, &conn->creds);
+ NULL, NULL, NULL, CREDS_NONE, &conn->creds);
}
else if(!(conn->scheme->flags & PROTOPT_CREDSPERREQUEST)) {
/* for protocols that do not handle credentials per request,
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
const struct bufref *chlg,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
struct bufref *out)
{
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
size_t i;
struct MD5_context *ctxt;
const char *userp = Curl_creds_user(creds);
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
const struct bufref *chlg,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
struct bufref *out)
{
CURLcode result = CURLE_OK;
SecBufferDesc resp_desc;
SECURITY_STATUS status;
unsigned long attrs;
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
/* Ensure we have a valid challenge message */
if(!Curl_bufref_len(chlg)) {
*/
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
const bool mutual_auth,
const struct bufref *chlg,
OM_uint32 unused_status;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
-
- (void)creds;
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
if(!krb5->spn) {
gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
*/
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
const bool mutual_auth,
const struct bufref *chlg,
SecBufferDesc resp_desc;
SECURITY_STATUS status;
unsigned long attrs;
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
if(!krb5->spn) {
/* Generate our SPN */
*/
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
struct ntlmdata *ntlm,
struct bufref *out)
(*) -> Optional
*/
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
size_t size;
char *ntlmbuf;
*/
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
struct ntlmdata *ntlm,
struct bufref *out)
SecBufferDesc type_1_desc;
SECURITY_STATUS status;
unsigned long attrs;
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
/* Clean up any former leftovers and initialise to defaults */
Curl_auth_cleanup_ntlm(ntlm);
*/
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
const char *chlg64,
struct negotiatedata *nego)
gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
/* Generate our SPN */
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
char *spn = Curl_auth_build_spn(service, NULL, host);
if(!spn)
return CURLE_OUT_OF_MEMORY;
*/
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
const char *chlg64,
struct negotiatedata *nego)
if(!nego->spn) {
/* Generate our SPN */
+ const char *service = Curl_creds_has_sasl_service(creds) ?
+ Curl_creds_sasl_service(creds) : default_service;
nego->spn = Curl_auth_build_spn(service, host, NULL);
if(!nego->spn)
return CURLE_OUT_OF_MEMORY;
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
const struct bufref *chlg,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
struct bufref *out);
/* This is used to decode an HTTP DIGEST challenge message */
/* This is used to generate a base64 encoded NTLM type-1 message */
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
struct ntlmdata *ntlm,
struct bufref *out);
message */
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
const bool mutual_auth,
const struct bufref *chlg,
message */
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
struct Curl_creds *creds,
- const char *service,
+ const char *default_service,
const char *host,
const char *chlg64,
struct negotiatedata *nego);
{
Curl_creds_unlink(pcreds);
if(user || passwd)
- return !Curl_creds_create(user, passwd, NULL, NULL, CREDS_NONE, pcreds);
+ return !Curl_creds_create(user, passwd, NULL, NULL, NULL, CREDS_NONE,
+ pcreds);
else
return TRUE;
}