mirror of
https://github.com/curl/curl.git
synced 2026-07-10 11:17:15 +03:00
creds: hold credentials
Authorizdation credentials are kept in `struct Curl_creds`. This contains: * `user`: the username, maybe the empty string * `passwd`: the password, maybe the empty string * `sasl_authzid`: the SASL authz value, maybe the empty string * `oauth_bearer`: the OAUTH bearer token, maybe the empty string * `source`: where the credentials from from * `refcount`: a reference counter to link/unkink creds A `creds` with all values empty is equivalent to NULL, e.g. no `creds` instance. With reference counting, `creds` can be linked/unlinked in several places. See docs/internals/CREDENTIALS.md for use. Closes #21548
This commit is contained in:
parent
a32a2b0b77
commit
8f71d0fde5
47 changed files with 1138 additions and 962 deletions
|
|
@ -53,6 +53,7 @@ INTERNALDOCS = \
|
|||
internals/CLIENT-WRITERS.md \
|
||||
internals/CODE_STYLE.md \
|
||||
internals/CONNECTION-FILTERS.md \
|
||||
internals/CREDENTIALS.md \
|
||||
internals/CURLX.md \
|
||||
internals/DYNBUF.md \
|
||||
internals/HASH.md \
|
||||
|
|
|
|||
75
docs/internals/CREDENTIALS.md
Normal file
75
docs/internals/CREDENTIALS.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<!--
|
||||
Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
|
||||
SPDX-License-Identifier: curl
|
||||
-->
|
||||
|
||||
# curl `creds`
|
||||
|
||||
Authorization credentials are kept in `struct Curl_creds`. This contains:
|
||||
|
||||
* `user`: the username, maybe the empty string
|
||||
* `passwd`: the password, maybe the empty string
|
||||
* `sasl_authzid`: the SASL `authz` value, maybe the empty string
|
||||
* `oauth_bearer`: the OAUTH bearer token, maybe the empty string
|
||||
* `source`: where the credentials from
|
||||
* `refcount`: a reference counter to link/unlink `creds`
|
||||
|
||||
A `creds` with all values empty is equivalent to NULL, e.g. no `creds`
|
||||
instance. With reference counting, `creds` can be linked in several places.
|
||||
|
||||
Two `creds` are the same if all values are equal apart from `source`
|
||||
and `refcount`. The comparison of strings is done via `Curl_timestrcmp()`
|
||||
to prevent side channel attacks.
|
||||
|
||||
## `creds` locations
|
||||
|
||||
Credentials are kept in three places:
|
||||
|
||||
* `data->state.creds`: the credentials to use for the transfer in talking
|
||||
to the `origin` (see PEERS)
|
||||
* `conn->creds`: the credentials tied to a connection (more below)
|
||||
* `conn->*_proxy.creds`: credentials used to talk to the `conn->*_proxy.peer`
|
||||
|
||||
### `data->state.creds`
|
||||
|
||||
This `creds` instance is created when the transfer starts looking for a
|
||||
suitable connection. For an `easy_perform()` this may happen several times
|
||||
if, for example, http redirects are followed.
|
||||
|
||||
When an `easy_perform()` starts, the transfer's `data->state.initial_origin`
|
||||
peer is cleared. When creating the connection, `conn->origin` is calculated
|
||||
(e.g. who the request talks to). If `data->state.initial_origin` is not
|
||||
set, the first `conn->origin` is linked there. Now `libcurl` knows where
|
||||
the transfer initially talked to on all possible subsequent requests.
|
||||
|
||||
Credential information from `CURLOPT_*` settings is only applicable for the
|
||||
initial origin. Any followup request going to another origin must not
|
||||
use it. Therefore `data->state.creds` is *only* created from `CURLOPT_*`
|
||||
when current origin and initial origin match.
|
||||
|
||||
Without credentials from `CURLOPT_*`, the URL is inspected for user and
|
||||
password and `netrc` is consulted as well (when built in).
|
||||
|
||||
### `conn->creds`
|
||||
|
||||
Once `data->state.creds` is known, the connection credentials are
|
||||
determined. For protocols that tie authorization to everything send
|
||||
on a connection (protocols without flag `PROTOPT_CREDSPERREQUEST`),
|
||||
`conn->creds` is linked to `data->state.creds`. Only connections
|
||||
carrying the same credentials may be reused.
|
||||
|
||||
Protocol with flag `PROTOPT_CREDSPERREQUEST` leave `conn->creds` empty,
|
||||
as connections for such protocols may be reused with different
|
||||
credentials.
|
||||
|
||||
That being said, there are authentication schemes like `NTLM` and
|
||||
`NEGOTIATE` that tie credentials to a connection. Those do set `conn->creds`
|
||||
once they start to operate, preventing connection reuse from then on
|
||||
for transfers with different credentials.
|
||||
|
||||
### `conn->*_proxy.creds`
|
||||
|
||||
Those are set during connection setup from the `CURLOPT_*` values. They
|
||||
do not require any "initial origin" handling as the origin of a proxy
|
||||
does not change for a transfer.
|
||||
|
|
@ -161,6 +161,7 @@ LIB_CFILES = \
|
|||
connect.c \
|
||||
content_encoding.c \
|
||||
cookie.c \
|
||||
creds.c \
|
||||
cshutdn.c \
|
||||
curl_addrinfo.c \
|
||||
curl_endian.c \
|
||||
|
|
@ -293,6 +294,7 @@ LIB_HFILES = \
|
|||
connect.h \
|
||||
content_encoding.h \
|
||||
cookie.h \
|
||||
creds.h \
|
||||
curl_addrinfo.h \
|
||||
curl_ctype.h \
|
||||
curl_endian.h \
|
||||
|
|
|
|||
|
|
@ -387,8 +387,7 @@ connect_sub_chain:
|
|||
result = Curl_cf_socks_proxy_insert_after(
|
||||
cf, data, dest, cf->conn->ip_version,
|
||||
cf->conn->socks_proxy.proxytype,
|
||||
cf->conn->socks_proxy.user,
|
||||
cf->conn->socks_proxy.passwd);
|
||||
cf->conn->socks_proxy.creds);
|
||||
|
||||
CURL_TRC_CF(data, cf, "added SOCKS filter to %s:%u -> %d",
|
||||
dest->hostname, dest->port, result);
|
||||
|
|
|
|||
183
lib/creds.c
Normal file
183
lib/creds.c
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <stddef.h> /* for offsetof() */
|
||||
|
||||
#include "creds.h"
|
||||
#include "curl_trc.h"
|
||||
#include "strcase.h"
|
||||
#include "urldata.h"
|
||||
|
||||
|
||||
CURLcode Curl_creds_create(const char *user,
|
||||
const char *passwd,
|
||||
const char *sasl_authzid,
|
||||
const char *oauth_bearer,
|
||||
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;
|
||||
char *s, *buf;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
Curl_creds_unlink(pcreds);
|
||||
|
||||
/* Everything empty/NULL, this is the NULL credential */
|
||||
if(!ulen && !plen && !salen && !olen)
|
||||
goto out;
|
||||
|
||||
if((ulen > CURL_MAX_INPUT_LENGTH) ||
|
||||
(plen > CURL_MAX_INPUT_LENGTH) ||
|
||||
(salen > CURL_MAX_INPUT_LENGTH) ||
|
||||
(olen > 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);
|
||||
if(!creds) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
creds->refcount = 1;
|
||||
creds->source = source;
|
||||
/* Some compilers try to be too smart about our dynamic struct size */
|
||||
buf = ((char *)creds) + offsetof(struct Curl_creds, buf);
|
||||
creds->user = s = buf;
|
||||
if(ulen)
|
||||
memcpy(s, CURL_UNCONST(user), ulen + 1);
|
||||
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;
|
||||
if(olen)
|
||||
memcpy(s, CURL_UNCONST(oauth_bearer), olen + 1);
|
||||
|
||||
out:
|
||||
if(!result)
|
||||
*pcreds = creds;
|
||||
else
|
||||
Curl_creds_unlink(&creds);
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_creds_merge(const char *user,
|
||||
const char *passwd,
|
||||
struct Curl_creds *creds_in,
|
||||
uint8_t source,
|
||||
struct Curl_creds **pcreds_out)
|
||||
{
|
||||
struct Curl_creds *creds_out = NULL;
|
||||
CURLcode result;
|
||||
|
||||
if(!user || !user[0])
|
||||
user = Curl_creds_user(creds_in);
|
||||
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),
|
||||
source, &creds_out);
|
||||
Curl_creds_link(pcreds_out, creds_out);
|
||||
Curl_creds_unlink(&creds_out);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_creds_link(struct Curl_creds **pdest, struct Curl_creds *src)
|
||||
{
|
||||
if(*pdest != src) {
|
||||
Curl_creds_unlink(pdest);
|
||||
*pdest = src;
|
||||
if(src) {
|
||||
DEBUGASSERT(src->refcount < UINT32_MAX);
|
||||
src->refcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_creds_unlink(struct Curl_creds **pcreds)
|
||||
{
|
||||
if(*pcreds) {
|
||||
struct Curl_creds *creds = *pcreds;
|
||||
|
||||
DEBUGASSERT(creds->refcount);
|
||||
*pcreds = NULL;
|
||||
if(creds->refcount)
|
||||
creds->refcount--;
|
||||
if(!creds->refcount) {
|
||||
curlx_free(creds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Curl_creds_same_user(struct Curl_creds *creds, const char *user)
|
||||
{
|
||||
return creds && !Curl_timestrcmp(creds->user, user);
|
||||
}
|
||||
|
||||
bool Curl_creds_same_passwd(struct Curl_creds *creds, const char *passwd)
|
||||
{
|
||||
return creds && !Curl_timestrcmp(creds->passwd, passwd);
|
||||
}
|
||||
|
||||
bool Curl_creds_same(struct Curl_creds *c1, struct Curl_creds *c2)
|
||||
{
|
||||
return (c1 == c2) ||
|
||||
(c1 && c2 &&
|
||||
!Curl_timestrcmp(c1->user, c2->user) &&
|
||||
!Curl_timestrcmp(c1->passwd, c2->passwd) &&
|
||||
!Curl_timestrcmp(c1->sasl_authzid, c2->sasl_authzid) &&
|
||||
!Curl_timestrcmp(c1->oauth_bearer, c2->oauth_bearer));
|
||||
}
|
||||
|
||||
#ifdef CURLVERBOSE
|
||||
void Curl_creds_trace(struct Curl_easy *data, struct Curl_creds *creds,
|
||||
const char *msg)
|
||||
{
|
||||
if(creds) {
|
||||
CURL_TRC_M(data, "%s: user=%s, passwd=%s, "
|
||||
"sasl_authzid=%s, oauth_bearer=%s, source=%d",
|
||||
msg,
|
||||
Curl_creds_user(creds),
|
||||
Curl_creds_has_passwd(creds) ? "***" : "",
|
||||
Curl_creds_sasl_authzid(creds),
|
||||
Curl_creds_oauth_bearer(creds),
|
||||
creds->source);
|
||||
}
|
||||
else
|
||||
CURL_TRC_M(data, "%s: -", msg);
|
||||
}
|
||||
|
||||
#endif
|
||||
86
lib/creds.h
Normal file
86
lib/creds.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#ifndef HEADER_CURL_CREDS_H
|
||||
#define HEADER_CURL_CREDS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
struct Curl_easy;
|
||||
|
||||
#define CREDS_NONE 0 /* used for default username/passwd */
|
||||
#define CREDS_URL 1 /* username/passwd from URL */
|
||||
#define CREDS_OPTION 2 /* username/passwd set with a CURLOPT_ */
|
||||
#define CREDS_NETRC 3 /* username/passwd found in netrc */
|
||||
|
||||
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 */
|
||||
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,
|
||||
uint8_t source,
|
||||
struct Curl_creds **pcreds);
|
||||
|
||||
/* Create credentials by overriding `user` and/or `passwd` in `creds_in` */
|
||||
CURLcode Curl_creds_merge(const char *user,
|
||||
const char *passwd,
|
||||
struct Curl_creds *creds_in,
|
||||
uint8_t source,
|
||||
struct Curl_creds **pcreds_out);
|
||||
|
||||
/* Unlink any creds in `*pdest`, assign src, increase src
|
||||
* refcount when not NULL. */
|
||||
void Curl_creds_link(struct Curl_creds **pdest, struct Curl_creds *src);
|
||||
|
||||
/* Drop a reference, creds may be passed as NULL */
|
||||
void Curl_creds_unlink(struct Curl_creds **pcreds);
|
||||
|
||||
/* TRUE if both creds are NULL or have same username and password. */
|
||||
bool Curl_creds_same(struct Curl_creds *c1, struct Curl_creds *c2);
|
||||
bool Curl_creds_same_user(struct Curl_creds *creds, const char *user);
|
||||
bool Curl_creds_same_passwd(struct Curl_creds *creds, const char *passwd);
|
||||
|
||||
|
||||
/* Provides properties for creds or, if creds is NULL, the empty string */
|
||||
#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_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 : "")
|
||||
|
||||
|
||||
#ifdef CURLVERBOSE
|
||||
void Curl_creds_trace(struct Curl_easy *data, struct Curl_creds *creds,
|
||||
const char *msg);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_CREDS_H */
|
||||
110
lib/curl_sasl.c
110
lib/curl_sasl.c
|
|
@ -276,7 +276,7 @@ static CURLcode build_message(struct SASL *sasl, struct bufref *msg)
|
|||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data)
|
||||
{
|
||||
/* Have credentials been provided? */
|
||||
if(data->conn->user[0])
|
||||
if(data->conn->creds)
|
||||
return TRUE;
|
||||
|
||||
/* EXTERNAL can authenticate without a username and/or password */
|
||||
|
|
@ -299,13 +299,15 @@ struct sasl_ctx {
|
|||
|
||||
static bool sasl_choose_external(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
if((sctx->enabledmechs & SASL_MECH_EXTERNAL) && !sctx->conn->passwd[0]) {
|
||||
if((sctx->enabledmechs & SASL_MECH_EXTERNAL) &&
|
||||
!Curl_creds_has_passwd(sctx->conn->creds)) {
|
||||
sctx->mech = SASL_MECH_STRING_EXTERNAL;
|
||||
sctx->state1 = SASL_EXTERNAL;
|
||||
sctx->sasl->authused = SASL_MECH_EXTERNAL;
|
||||
|
||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||
Curl_auth_create_external_message(sctx->conn->user, &sctx->resp);
|
||||
Curl_auth_create_external_message(
|
||||
Curl_creds_user(sctx->conn->creds), &sctx->resp);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -316,7 +318,7 @@ static bool sasl_choose_krb5(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
{
|
||||
if((sctx->enabledmechs & SASL_MECH_GSSAPI) &&
|
||||
Curl_auth_is_gssapi_supported() &&
|
||||
Curl_auth_user_contains_domain(sctx->conn->user)) {
|
||||
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;
|
||||
|
|
@ -330,8 +332,7 @@ static bool sasl_choose_krb5(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
if(sctx->sasl->force_ir || data->set.sasl_ir) {
|
||||
struct kerberos5data *krb5 = Curl_auth_krb5_get(sctx->conn);
|
||||
sctx->result = !krb5 ? CURLE_OUT_OF_MEMORY :
|
||||
Curl_auth_create_gssapi_user_message(data, sctx->conn->user,
|
||||
sctx->conn->passwd,
|
||||
Curl_auth_create_gssapi_user_message(data, sctx->conn->creds,
|
||||
service,
|
||||
sctx->conn->origin->hostname,
|
||||
(bool)sctx->sasl->mutual_auth,
|
||||
|
|
@ -375,8 +376,7 @@ static bool sasl_choose_gsasl(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
Curl_bufref_init(&nullmsg);
|
||||
sctx->state1 = SASL_GSASL;
|
||||
sctx->state2 = SASL_GSASL;
|
||||
sctx->result = Curl_auth_gsasl_start(data, sctx->conn->user,
|
||||
sctx->conn->passwd, gsasl);
|
||||
sctx->result = Curl_auth_gsasl_start(data, sctx->conn->creds, gsasl);
|
||||
if(!sctx->result && (sctx->sasl->force_ir || data->set.sasl_ir))
|
||||
sctx->result = Curl_auth_gsasl_token(data, &nullmsg, gsasl, &sctx->resp);
|
||||
return TRUE;
|
||||
|
|
@ -427,9 +427,7 @@ static bool sasl_choose_ntlm(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
if(sctx->sasl->force_ir || data->set.sasl_ir) {
|
||||
struct ntlmdata *ntlm = Curl_auth_ntlm_get(sctx->conn, FALSE);
|
||||
sctx->result = !ntlm ? CURLE_OUT_OF_MEMORY :
|
||||
Curl_auth_create_ntlm_type1_message(data,
|
||||
sctx->conn->user,
|
||||
sctx->conn->passwd,
|
||||
Curl_auth_create_ntlm_type1_message(data, sctx->conn->creds,
|
||||
service, hostname,
|
||||
ntlm, &sctx->resp);
|
||||
}
|
||||
|
|
@ -441,11 +439,8 @@ static bool sasl_choose_ntlm(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
const char *oauth_bearer =
|
||||
(!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
|
||||
data->set.str[STRING_BEARER] : NULL;
|
||||
|
||||
if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) {
|
||||
if(Curl_creds_has_oauth_bearer(data->state.creds) &&
|
||||
(sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) {
|
||||
const char *hostname;
|
||||
int port;
|
||||
Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
|
||||
|
|
@ -457,9 +452,8 @@ static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||
sctx->result =
|
||||
Curl_auth_create_oauth_bearer_message(sctx->conn->user,
|
||||
hostname, port,
|
||||
oauth_bearer, &sctx->resp);
|
||||
Curl_auth_create_oauth_bearer_message(sctx->conn->creds,
|
||||
hostname, port, &sctx->resp);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -467,19 +461,15 @@ static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
static bool sasl_choose_oauth2(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||
{
|
||||
const char *oauth_bearer =
|
||||
(!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
|
||||
data->set.str[STRING_BEARER] : NULL;
|
||||
|
||||
if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_XOAUTH2)) {
|
||||
if(Curl_creds_has_oauth_bearer(sctx->conn->creds) &&
|
||||
(sctx->enabledmechs & SASL_MECH_XOAUTH2)) {
|
||||
sctx->mech = SASL_MECH_STRING_XOAUTH2;
|
||||
sctx->state1 = SASL_OAUTH2;
|
||||
sctx->sasl->authused = SASL_MECH_XOAUTH2;
|
||||
|
||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||
sctx->result = Curl_auth_create_xoauth_bearer_message(sctx->conn->user,
|
||||
oauth_bearer,
|
||||
&sctx->resp);
|
||||
sctx->result = Curl_auth_create_xoauth_bearer_message(
|
||||
sctx->conn->creds, &sctx->resp);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -494,9 +484,7 @@ static bool sasl_choose_plain(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
|
||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||
sctx->result =
|
||||
Curl_auth_create_plain_message(sctx->conn->sasl_authzid,
|
||||
sctx->conn->user, sctx->conn->passwd,
|
||||
&sctx->resp);
|
||||
Curl_auth_create_plain_message(sctx->conn->creds, &sctx->resp);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -511,7 +499,8 @@ static bool sasl_choose_login(struct Curl_easy *data, struct sasl_ctx *sctx)
|
|||
sctx->sasl->authused = SASL_MECH_LOGIN;
|
||||
|
||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||
Curl_auth_create_login_message(sctx->conn->user, &sctx->resp);
|
||||
Curl_auth_create_login_message(
|
||||
Curl_creds_user(sctx->conn->creds), &sctx->resp);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -606,7 +595,6 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
data->set.str[STRING_SERVICE_NAME] :
|
||||
sasl->params->service;
|
||||
#endif
|
||||
const char *oauth_bearer = data->set.str[STRING_BEARER];
|
||||
struct bufref serverdata;
|
||||
|
||||
Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
|
||||
|
|
@ -634,18 +622,17 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
*progress = SASL_DONE;
|
||||
return result;
|
||||
case SASL_PLAIN:
|
||||
result = Curl_auth_create_plain_message(conn->sasl_authzid,
|
||||
conn->user, conn->passwd, &resp);
|
||||
result = Curl_auth_create_plain_message(conn->creds, &resp);
|
||||
break;
|
||||
case SASL_LOGIN:
|
||||
Curl_auth_create_login_message(conn->user, &resp);
|
||||
Curl_auth_create_login_message(Curl_creds_user(conn->creds), &resp);
|
||||
newstate = SASL_LOGIN_PASSWD;
|
||||
break;
|
||||
case SASL_LOGIN_PASSWD:
|
||||
Curl_auth_create_login_message(conn->passwd, &resp);
|
||||
Curl_auth_create_login_message(Curl_creds_passwd(conn->creds), &resp);
|
||||
break;
|
||||
case SASL_EXTERNAL:
|
||||
Curl_auth_create_external_message(conn->user, &resp);
|
||||
Curl_auth_create_external_message(Curl_creds_user(conn->creds), &resp);
|
||||
break;
|
||||
#ifdef USE_GSASL
|
||||
case SASL_GSASL:
|
||||
|
|
@ -663,15 +650,15 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
case SASL_CRAMMD5:
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_create_cram_md5_message(&serverdata, conn->user,
|
||||
conn->passwd, &resp);
|
||||
result = Curl_auth_create_cram_md5_message(&serverdata, conn->creds,
|
||||
&resp);
|
||||
break;
|
||||
case SASL_DIGESTMD5:
|
||||
result = get_server_message(sasl, data, &serverdata);
|
||||
if(!result)
|
||||
result = Curl_auth_create_digest_md5_message(data, &serverdata,
|
||||
conn->user, conn->passwd,
|
||||
service, &resp);
|
||||
conn->creds, service,
|
||||
&resp);
|
||||
if(!result && (sasl->params->flags & SASL_FLAG_BASE64))
|
||||
newstate = SASL_DIGESTMD5_RESP;
|
||||
break;
|
||||
|
|
@ -685,8 +672,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
/* Create the type-1 message */
|
||||
struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE);
|
||||
result = !ntlm ? CURLE_OUT_OF_MEMORY :
|
||||
Curl_auth_create_ntlm_type1_message(data,
|
||||
conn->user, conn->passwd,
|
||||
Curl_auth_create_ntlm_type1_message(data, conn->creds,
|
||||
service, hostname,
|
||||
ntlm, &resp);
|
||||
newstate = SASL_NTLM_TYPE2MSG;
|
||||
|
|
@ -700,9 +686,8 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
if(!result)
|
||||
result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, ntlm);
|
||||
if(!result)
|
||||
result = Curl_auth_create_ntlm_type3_message(data, conn->user,
|
||||
conn->passwd, ntlm,
|
||||
&resp);
|
||||
result = Curl_auth_create_ntlm_type3_message(data, conn->creds,
|
||||
ntlm, &resp);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -711,7 +696,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
case SASL_GSSAPI: {
|
||||
struct kerberos5data *krb5 = Curl_auth_krb5_get(conn);
|
||||
result = !krb5 ? CURLE_OUT_OF_MEMORY :
|
||||
Curl_auth_create_gssapi_user_message(data, conn->user, conn->passwd,
|
||||
Curl_auth_create_gssapi_user_message(data, conn->creds,
|
||||
service, conn->origin->hostname,
|
||||
(bool)sasl->mutual_auth, NULL,
|
||||
krb5, &resp);
|
||||
|
|
@ -727,7 +712,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
else if(sasl->mutual_auth) {
|
||||
/* Decode the user token challenge and create the optional response
|
||||
message */
|
||||
result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
|
||||
result = Curl_auth_create_gssapi_user_message(data, NULL,
|
||||
NULL, NULL,
|
||||
(bool)sasl->mutual_auth,
|
||||
&serverdata,
|
||||
|
|
@ -736,10 +721,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
}
|
||||
else
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_auth_create_gssapi_security_message(data,
|
||||
conn->sasl_authzid,
|
||||
&serverdata,
|
||||
krb5, &resp);
|
||||
result = Curl_auth_create_gssapi_security_message(
|
||||
data, Curl_creds_sasl_authzid(conn->creds), &serverdata,
|
||||
krb5, &resp);
|
||||
}
|
||||
break;
|
||||
case SASL_GSSAPI_NO_DATA:
|
||||
|
|
@ -750,10 +734,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
if(!krb5)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
result = Curl_auth_create_gssapi_security_message(data,
|
||||
conn->sasl_authzid,
|
||||
&serverdata,
|
||||
krb5, &resp);
|
||||
result = Curl_auth_create_gssapi_security_message(
|
||||
data, Curl_creds_sasl_authzid(conn->creds), &serverdata,
|
||||
krb5, &resp);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -761,18 +744,16 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
|||
case SASL_OAUTH2:
|
||||
/* Create the authorization message */
|
||||
if(sasl->authused == SASL_MECH_OAUTHBEARER) {
|
||||
result = Curl_auth_create_oauth_bearer_message(conn->user,
|
||||
result = Curl_auth_create_oauth_bearer_message(conn->creds,
|
||||
hostname,
|
||||
port,
|
||||
oauth_bearer,
|
||||
&resp);
|
||||
|
||||
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
|
||||
newstate = SASL_OAUTH2_RESP;
|
||||
}
|
||||
else
|
||||
result = Curl_auth_create_xoauth_bearer_message(conn->user,
|
||||
oauth_bearer,
|
||||
result = Curl_auth_create_xoauth_bearer_message(conn->creds,
|
||||
&resp);
|
||||
break;
|
||||
|
||||
|
|
@ -862,7 +843,7 @@ static void sasl_unchosen(struct Curl_easy *data, unsigned short mech,
|
|||
else {
|
||||
if(param_missing)
|
||||
infof(data, "SASL: %s is missing %s", mname, param_missing);
|
||||
if(!data->conn->user[0])
|
||||
if(!Curl_creds_has_user(data->conn->creds))
|
||||
infof(data, "SASL: %s is missing username", mname);
|
||||
}
|
||||
}
|
||||
|
|
@ -904,7 +885,8 @@ CURLcode Curl_sasl_is_blocked(struct SASL *sasl, struct Curl_easy *data)
|
|||
"auth mechanisms");
|
||||
else {
|
||||
infof(data, "SASL: no auth mechanism offered could be selected");
|
||||
if((enabledmechs & SASL_MECH_EXTERNAL) && data->conn->passwd[0])
|
||||
if((enabledmechs & SASL_MECH_EXTERNAL) &&
|
||||
Curl_creds_has_passwd(data->conn->creds))
|
||||
infof(data, "SASL: auth EXTERNAL not chosen with password");
|
||||
sasl_unchosen(data, SASL_MECH_GSSAPI, enabledmechs,
|
||||
CURL_SASL_KERBEROS5, Curl_auth_is_gssapi_supported(), NULL);
|
||||
|
|
@ -919,10 +901,10 @@ CURLcode Curl_sasl_is_blocked(struct SASL *sasl, struct Curl_easy *data)
|
|||
sasl_unchosen(data, SASL_MECH_NTLM, enabledmechs,
|
||||
CURL_SASL_NTLM, Curl_auth_is_ntlm_supported(), NULL);
|
||||
sasl_unchosen(data, SASL_MECH_OAUTHBEARER, enabledmechs, TRUE, TRUE,
|
||||
data->set.str[STRING_BEARER] ?
|
||||
Curl_creds_has_oauth_bearer(data->conn->creds) ?
|
||||
NULL : "CURLOPT_XOAUTH2_BEARER");
|
||||
sasl_unchosen(data, SASL_MECH_XOAUTH2, enabledmechs, TRUE, TRUE,
|
||||
data->set.str[STRING_BEARER] ?
|
||||
Curl_creds_has_oauth_bearer(data->conn->creds) ?
|
||||
NULL : "CURLOPT_XOAUTH2_BEARER");
|
||||
}
|
||||
#endif /* CURLVERBOSE */
|
||||
|
|
|
|||
|
|
@ -743,7 +743,7 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
|
|||
struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = Curl_pp_sendf(data, &ftpc->pp, "USER %s",
|
||||
conn->user ? conn->user : "");
|
||||
Curl_creds_user(conn->creds));
|
||||
if(!result) {
|
||||
ftpc->ftp_trying_alternative = FALSE;
|
||||
ftp_state(data, ftpc, FTP_USER);
|
||||
|
|
@ -2941,7 +2941,8 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
|
|||
if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
|
||||
/* 331 Password required for ...
|
||||
(the server requires to send the user's password too) */
|
||||
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s", data->conn->passwd);
|
||||
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
|
||||
Curl_creds_passwd(data->conn->creds));
|
||||
if(!result)
|
||||
ftp_state(data, ftpc, FTP_PASS);
|
||||
}
|
||||
|
|
|
|||
118
lib/http.c
118
lib/http.c
|
|
@ -250,14 +250,14 @@ char *Curl_copy_header_value(const char *header)
|
|||
*
|
||||
* Returns CURLcode.
|
||||
*/
|
||||
static CURLcode http_output_basic(struct Curl_easy *data, bool proxy)
|
||||
static CURLcode http_output_basic(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool proxy)
|
||||
{
|
||||
size_t size = 0;
|
||||
char *authorization = NULL;
|
||||
char **p_hd;
|
||||
const char *user;
|
||||
const char *pwd;
|
||||
CURLcode result;
|
||||
struct Curl_creds *creds = NULL;
|
||||
char *out;
|
||||
|
||||
/* credentials are unique per transfer for HTTP, do not use the ones for the
|
||||
|
|
@ -265,19 +265,23 @@ static CURLcode http_output_basic(struct Curl_easy *data, bool proxy)
|
|||
if(proxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
p_hd = &data->req.hd_proxy_auth;
|
||||
user = data->state.aptr.proxyuser;
|
||||
pwd = data->state.aptr.proxypasswd;
|
||||
creds = conn->http_proxy.creds;
|
||||
#else
|
||||
(void)conn;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
p_hd = &data->req.hd_auth;
|
||||
user = data->state.aptr.user;
|
||||
pwd = data->state.aptr.passwd;
|
||||
creds = data->state.creds;
|
||||
}
|
||||
|
||||
out = curl_maprintf("%s:%s", user ? user : "", pwd ? pwd : "");
|
||||
if(!creds) {
|
||||
DEBUGASSERT(0);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
out = curl_maprintf("%s:%s", creds->user, creds->passwd);
|
||||
if(!out)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -320,10 +324,11 @@ static CURLcode http_output_bearer(struct Curl_easy *data)
|
|||
char **userp;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(Curl_creds_has_oauth_bearer(data->state.creds));
|
||||
userp = &data->req.hd_auth;
|
||||
curlx_free(*userp);
|
||||
*userp = curl_maprintf("Authorization: Bearer %s\r\n",
|
||||
data->set.str[STRING_BEARER]);
|
||||
Curl_creds_oauth_bearer(data->state.creds));
|
||||
|
||||
if(!*userp) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -527,10 +532,10 @@ static bool http_should_fail(struct Curl_easy *data, int httpcode)
|
|||
* Either we are not authenticating, or we are supposed to be authenticating
|
||||
* something else. This is an error.
|
||||
*/
|
||||
if((httpcode == 401) && !data->state.aptr.user)
|
||||
if((httpcode == 401) && !data->state.creds)
|
||||
return TRUE;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if((httpcode == 407) && !data->conn->bits.proxy_user_passwd)
|
||||
if((httpcode == 407) && !data->conn->http_proxy.creds)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
|
|
@ -551,7 +556,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
|||
CURLcode result = CURLE_OK;
|
||||
unsigned long authmask = ~0UL;
|
||||
|
||||
if(!data->set.str[STRING_BEARER])
|
||||
if(!Curl_creds_has_oauth_bearer(data->state.creds))
|
||||
authmask &= (unsigned long)~CURLAUTH_BEARER;
|
||||
|
||||
if(100 <= data->req.httpcode && data->req.httpcode <= 199)
|
||||
|
|
@ -561,7 +566,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
|||
if(data->state.authproblem)
|
||||
return data->set.http_fail_on_error ? CURLE_HTTP_RETURNED_ERROR : CURLE_OK;
|
||||
|
||||
if((data->state.aptr.user || data->set.str[STRING_BEARER]) &&
|
||||
if(data->state.creds &&
|
||||
((data->req.httpcode == 401) ||
|
||||
(data->req.authneg && data->req.httpcode < 300))) {
|
||||
pickhost = pickoneauth(&data->state.authhost, authmask);
|
||||
|
|
@ -578,7 +583,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
|||
}
|
||||
}
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.proxy_user_passwd &&
|
||||
if(conn->http_proxy.creds &&
|
||||
((data->req.httpcode == 407) ||
|
||||
(data->req.authneg && data->req.httpcode < 300))) {
|
||||
pickproxy = pickoneauth(&data->state.authproxy,
|
||||
|
|
@ -694,14 +699,14 @@ static CURLcode output_auth_headers(struct Curl_easy *data,
|
|||
/* Basic */
|
||||
if(
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
(proxy && conn->bits.proxy_user_passwd &&
|
||||
(proxy && conn->http_proxy.creds &&
|
||||
!Curl_checkProxyheaders(data, conn,
|
||||
STRCONST("Proxy-authorization"))) ||
|
||||
#endif
|
||||
(!proxy && data->state.aptr.user &&
|
||||
(!proxy && data->state.creds &&
|
||||
!Curl_checkheaders(data, STRCONST("Authorization")))) {
|
||||
auth = "Basic";
|
||||
result = http_output_basic(data, proxy);
|
||||
result = http_output_basic(data, conn, proxy);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
|
@ -714,8 +719,7 @@ static CURLcode output_auth_headers(struct Curl_easy *data,
|
|||
#ifndef CURL_DISABLE_BEARER_AUTH
|
||||
if(authstatus->picked == CURLAUTH_BEARER) {
|
||||
/* Bearer */
|
||||
if(!proxy && data->set.str[STRING_BEARER] &&
|
||||
Curl_auth_allowed_to_host(data) &&
|
||||
if(!proxy && Curl_creds_has_oauth_bearer(data->state.creds) &&
|
||||
!Curl_checkheaders(data, STRCONST("Authorization"))) {
|
||||
auth = "Bearer";
|
||||
result = http_output_bearer(data);
|
||||
|
|
@ -737,15 +741,15 @@ static CURLcode output_auth_headers(struct Curl_easy *data,
|
|||
data->info.httpauthpicked = authstatus->picked;
|
||||
infof(data, "%s auth using %s with user '%s'",
|
||||
proxy ? "Proxy" : "Server", auth,
|
||||
proxy ? (data->state.aptr.proxyuser ?
|
||||
data->state.aptr.proxyuser : "") :
|
||||
(data->state.aptr.user ?
|
||||
data->state.aptr.user : ""));
|
||||
proxy ? (conn->http_proxy.creds ?
|
||||
conn->http_proxy.creds->user : "") :
|
||||
(data->state.creds ?
|
||||
data->state.creds->user : ""));
|
||||
#else
|
||||
(void)proxy;
|
||||
infof(data, "Server auth using %s with user '%s'",
|
||||
auth, data->state.aptr.user ?
|
||||
data->state.aptr.user : "");
|
||||
auth, data->state.creds ?
|
||||
data->state.creds->user : "");
|
||||
#endif
|
||||
authstatus->multipass = !authstatus->done;
|
||||
}
|
||||
|
|
@ -780,14 +784,13 @@ CURLcode Curl_http_output_auth(struct Curl_easy *data,
|
|||
|
||||
if(
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
(!conn->bits.httpproxy || !conn->bits.proxy_user_passwd) &&
|
||||
(!conn->bits.httpproxy || !conn->http_proxy.creds) &&
|
||||
#endif
|
||||
!data->state.aptr.user &&
|
||||
#ifdef USE_SPNEGO
|
||||
!(authhost->want & CURLAUTH_NEGOTIATE) &&
|
||||
!(authproxy->want & CURLAUTH_NEGOTIATE) &&
|
||||
#endif
|
||||
!data->set.str[STRING_BEARER]) {
|
||||
!data->state.creds) {
|
||||
/* no authentication with no user or password */
|
||||
authhost->done = TRUE;
|
||||
authproxy->done = TRUE;
|
||||
|
|
@ -832,13 +835,9 @@ CURLcode Curl_http_output_auth(struct Curl_easy *data,
|
|||
with it */
|
||||
authproxy->done = TRUE;
|
||||
|
||||
/* To prevent the user+password to get sent to other than the original host
|
||||
due to a location-follow */
|
||||
if(Curl_auth_allowed_to_host(data)
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
|| conn->bits.netrc
|
||||
#endif
|
||||
)
|
||||
/* Either we have credentials for the origin we talk to or
|
||||
performing authentication is allowed here */
|
||||
if(data->state.creds || Curl_auth_allowed_to_host(data))
|
||||
result = output_auth_headers(data, conn, authhost, request,
|
||||
path_and_query, FALSE);
|
||||
else
|
||||
|
|
@ -1227,8 +1226,6 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
bool same_origin;
|
||||
CURLcode result;
|
||||
CURLU *u = curl_url();
|
||||
if(!u)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -1242,29 +1239,16 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||
return Curl_uc_to_curlcode(uc);
|
||||
}
|
||||
|
||||
same_origin = Curl_url_same_origin(u, data->state.uh);
|
||||
curl_url_cleanup(u);
|
||||
|
||||
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||
if(!same_origin)
|
||||
Curl_auth_digest_cleanup(&data->state.digest);
|
||||
{
|
||||
bool same_origin = Curl_url_same_origin(u, data->state.uh);
|
||||
curl_url_cleanup(u);
|
||||
if(!same_origin)
|
||||
Curl_auth_digest_cleanup(&data->state.digest);
|
||||
}
|
||||
#else
|
||||
curl_url_cleanup(u);
|
||||
#endif
|
||||
|
||||
if((!same_origin && !data->set.allow_auth_to_other_hosts) ||
|
||||
!data->set.str[STRING_USERNAME]) {
|
||||
result = Curl_reset_userpwd(data);
|
||||
if(result) {
|
||||
curlx_free(follow_url);
|
||||
return result;
|
||||
}
|
||||
curlx_safefree(data->state.aptr.user);
|
||||
curlx_safefree(data->state.aptr.passwd);
|
||||
}
|
||||
result = Curl_reset_proxypwd(data);
|
||||
if(result) {
|
||||
curlx_free(follow_url);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
DEBUGASSERT(follow_url);
|
||||
|
||||
|
|
@ -2005,9 +1989,6 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
|
|||
struct dynamically_allocated_data *aptr = &data->state.aptr;
|
||||
const char *ptr;
|
||||
|
||||
if(!data->state.this_is_a_follow)
|
||||
Curl_peer_link(&data->state.first_origin, conn->origin);
|
||||
|
||||
curlx_safefree(aptr->host);
|
||||
#ifndef CURL_DISABLE_COOKIES
|
||||
curlx_safefree(data->req.cookiehost);
|
||||
|
|
@ -2015,7 +1996,7 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
|
|||
|
||||
ptr = Curl_checkheaders(data, STRCONST("Host"));
|
||||
if(ptr && (!data->state.this_is_a_follow ||
|
||||
Curl_peer_equal(data->state.first_origin, conn->origin))) {
|
||||
Curl_peer_equal(data->state.initial_origin, conn->origin))) {
|
||||
#ifndef CURL_DISABLE_COOKIES
|
||||
/* If we have a given custom Host: header, we extract the hostname in
|
||||
order to possibly use it for cookie reasons later on. We only allow the
|
||||
|
|
@ -2138,6 +2119,19 @@ static CURLcode http_target(struct Curl_easy *data,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else if(data->state.creds && (data->state.creds->source != CREDS_URL)) {
|
||||
/* credentials not from the URL need to be set */
|
||||
uc = curl_url_set(h, CURLUPART_USER,
|
||||
data->state.creds->user, CURLU_URLENCODE);
|
||||
if(!uc)
|
||||
uc = curl_url_set(h, CURLUPART_PASSWORD,
|
||||
data->state.creds->passwd, CURLU_URLENCODE);
|
||||
if(uc) {
|
||||
curl_url_cleanup(h);
|
||||
return Curl_uc_to_curlcode(uc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract the URL to use in the request. */
|
||||
uc = curl_url_get(h, CURLUPART_URL, &url, CURLU_NO_DEFAULT_PORT);
|
||||
if(uc) {
|
||||
|
|
|
|||
|
|
@ -848,7 +848,8 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data)
|
|||
char *request_type = NULL;
|
||||
char *credential_scope = NULL;
|
||||
char *str_to_sign = NULL;
|
||||
const char *user = data->state.aptr.user ? data->state.aptr.user : "";
|
||||
const char *user = Curl_creds_user(data->state.creds);
|
||||
const char *passwd = Curl_creds_passwd(data->state.creds);
|
||||
char *secret = NULL;
|
||||
unsigned char sign0[CURL_SHA256_DIGEST_LENGTH] = { 0 };
|
||||
unsigned char sign1[CURL_SHA256_DIGEST_LENGTH] = { 0 };
|
||||
|
|
@ -1068,8 +1069,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data)
|
|||
str_to_sign);
|
||||
|
||||
secret = curl_maprintf("%.*s4%s", (int)curlx_strlen(&provider0),
|
||||
curlx_str(&provider0), data->state.aptr.passwd ?
|
||||
data->state.aptr.passwd : "");
|
||||
curlx_str(&provider0), passwd);
|
||||
if(!secret)
|
||||
goto fail;
|
||||
/* make provider0 part done uppercase */
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
|||
char **allocuserpwd;
|
||||
|
||||
/* Point to the name and password for this */
|
||||
const char *userp;
|
||||
const char *passwdp;
|
||||
struct Curl_creds *creds = NULL;
|
||||
|
||||
/* Point to the correct struct with this */
|
||||
struct digestdata *digest;
|
||||
|
|
@ -90,28 +89,19 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
|||
#else
|
||||
digest = &data->state.proxydigest;
|
||||
allocuserpwd = &data->req.hd_proxy_auth;
|
||||
userp = data->state.aptr.proxyuser;
|
||||
passwdp = data->state.aptr.proxypasswd;
|
||||
creds = data->conn->http_proxy.creds;
|
||||
authp = &data->state.authproxy;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
digest = &data->state.digest;
|
||||
allocuserpwd = &data->req.hd_auth;
|
||||
userp = data->state.aptr.user;
|
||||
passwdp = data->state.aptr.passwd;
|
||||
creds = data->state.creds;
|
||||
authp = &data->state.authhost;
|
||||
}
|
||||
|
||||
curlx_safefree(*allocuserpwd);
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
userp = "";
|
||||
|
||||
if(!passwdp)
|
||||
passwdp = "";
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
have_chlg = !!digest->input_token;
|
||||
#else
|
||||
|
|
@ -123,8 +113,8 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
result = Curl_auth_create_digest_http_message(data, userp, passwdp,
|
||||
request, uripath, digest,
|
||||
result = Curl_auth_create_digest_http_message(data, creds, request,
|
||||
uripath, digest,
|
||||
&response, &len);
|
||||
if(result)
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -40,8 +40,10 @@ static void http_auth_nego_reset(struct connectdata *conn,
|
|||
{
|
||||
if(proxy)
|
||||
conn->proxy_negotiate_state = GSS_AUTHNONE;
|
||||
else
|
||||
else {
|
||||
conn->http_negotiate_state = GSS_AUTHNONE;
|
||||
Curl_creds_unlink(&conn->creds);
|
||||
}
|
||||
if(neg_ctx)
|
||||
Curl_auth_cleanup_spnego(neg_ctx);
|
||||
}
|
||||
|
|
@ -53,8 +55,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
size_t len;
|
||||
|
||||
/* Point to the username, password, service and host */
|
||||
const char *userp;
|
||||
const char *passwdp;
|
||||
struct Curl_creds *creds = NULL;
|
||||
const char *service;
|
||||
const char *host;
|
||||
|
||||
|
|
@ -64,8 +65,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
|
||||
if(proxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
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;
|
||||
|
|
@ -75,8 +75,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
#endif
|
||||
}
|
||||
else {
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
creds = data->state.creds;
|
||||
service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
||||
host = conn->origin->hostname;
|
||||
|
|
@ -87,13 +86,6 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
if(!neg_ctx)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Not set means empty */
|
||||
if(!userp)
|
||||
userp = "";
|
||||
|
||||
if(!passwdp)
|
||||
passwdp = "";
|
||||
|
||||
/* Obtain the input token, if any */
|
||||
header += strlen("Negotiate");
|
||||
curlx_str_passblanks(&header);
|
||||
|
|
@ -135,7 +127,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
#endif /* GSS_C_CHANNEL_BOUND_FLAG */
|
||||
|
||||
/* Initialize the security context and decode our challenge */
|
||||
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
|
||||
result = Curl_auth_decode_spnego_message(data, creds, service,
|
||||
host, header, neg_ctx);
|
||||
|
||||
#ifdef GSS_C_CHANNEL_BOUND_FLAG
|
||||
|
|
@ -145,6 +137,16 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
|||
if(result)
|
||||
http_auth_nego_reset(conn, neg_ctx, proxy);
|
||||
|
||||
if(!proxy) {
|
||||
/* Start it up. From this time onwards, the connection is tied
|
||||
* tp the credentials used. */
|
||||
if(conn->creds && !Curl_creds_same(creds, conn->creds)) {
|
||||
DEBUGASSERT(0); /* should not happen. */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
Curl_creds_link(&conn->creds, creds);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,9 +122,8 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
|||
server, which is for a plain host or for an HTTP proxy */
|
||||
char **allocuserpwd;
|
||||
|
||||
/* point to the username, password, service and host */
|
||||
const char *userp;
|
||||
const char *passwdp;
|
||||
/* point to credentials, service and host */
|
||||
struct Curl_creds *creds = NULL;
|
||||
const char *service = NULL;
|
||||
const char *hostname = NULL;
|
||||
|
||||
|
|
@ -140,8 +139,7 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
|||
if(proxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
allocuserpwd = &data->req.hd_proxy_auth;
|
||||
userp = data->state.aptr.proxyuser;
|
||||
passwdp = data->state.aptr.proxypasswd;
|
||||
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;
|
||||
|
|
@ -153,26 +151,19 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
|||
}
|
||||
else {
|
||||
allocuserpwd = &data->req.hd_auth;
|
||||
userp = data->state.aptr.user;
|
||||
passwdp = data->state.aptr.passwd;
|
||||
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;
|
||||
}
|
||||
|
||||
ntlm = Curl_auth_ntlm_get(conn, proxy);
|
||||
if(!ntlm)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
authp->done = FALSE;
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
userp = "";
|
||||
|
||||
if(!passwdp)
|
||||
passwdp = "";
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
if(!Curl_pSecFn) {
|
||||
/* not thread-safe and leaks - use curl_global_init() to avoid */
|
||||
|
|
@ -195,8 +186,16 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
|||
switch(*state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
/* Create a type-1 message */
|
||||
result = Curl_auth_create_ntlm_type1_message(data, userp, passwdp, service,
|
||||
if(!proxy) {
|
||||
/* Start it up. From this time onwards, the connection is tied
|
||||
* tp the credentials used. */
|
||||
if(conn->creds && !Curl_creds_same(creds, conn->creds)) {
|
||||
DEBUGASSERT(0); /* should not happen. */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
Curl_creds_link(&conn->creds, creds);
|
||||
}
|
||||
result = Curl_auth_create_ntlm_type1_message(data, creds, service,
|
||||
hostname, ntlm, &ntlmmsg);
|
||||
if(!result) {
|
||||
DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0);
|
||||
|
|
@ -215,8 +214,7 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
|||
|
||||
case NTLMSTATE_TYPE2:
|
||||
/* We already received the type-2 message, create a type-3 message */
|
||||
result = Curl_auth_create_ntlm_type3_message(data, userp, passwdp,
|
||||
ntlm, &ntlmmsg);
|
||||
result = Curl_auth_create_ntlm_type3_message(data, creds, ntlm, &ntlmmsg);
|
||||
if(!result && Curl_bufref_len(&ntlmmsg)) {
|
||||
result = curlx_base64_encode(Curl_bufref_uptr(&ntlmmsg),
|
||||
Curl_bufref_len(&ntlmmsg), &base64, &len);
|
||||
|
|
|
|||
|
|
@ -597,15 +597,15 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
|
|||
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we do not */
|
||||
if(!data->state.aptr.user) {
|
||||
if(!data->state.creds) {
|
||||
imap_state(data, imapc, IMAP_STOP);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Make sure the username and password are in the correct atom format */
|
||||
user = imap_atom(conn->user, FALSE);
|
||||
passwd = imap_atom(conn->passwd, FALSE);
|
||||
user = imap_atom(Curl_creds_user(conn->creds), FALSE);
|
||||
passwd = imap_atom(Curl_creds_passwd(conn->creds), FALSE);
|
||||
|
||||
/* Send the LOGIN command */
|
||||
result = imap_sendf(data, imapc, "LOGIN %s %s", user ? user : "",
|
||||
|
|
@ -712,7 +712,6 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
|
|||
/* Calculate the SASL login details */
|
||||
result = Curl_sasl_start(&imapc->sasl, data, (bool)imapc->ir_supported,
|
||||
&progress);
|
||||
|
||||
if(!result) {
|
||||
if(progress == SASL_INPROGRESS)
|
||||
imap_state(data, imapc, IMAP_AUTHENTICATE);
|
||||
|
|
|
|||
11
lib/ldap.c
11
lib/ldap.c
|
|
@ -252,8 +252,10 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
|||
#else
|
||||
char *host = NULL;
|
||||
#endif
|
||||
char *user = NULL;
|
||||
char *passwd = NULL;
|
||||
const char *user = Curl_creds_has_user(data->state.creds) ?
|
||||
data->state.creds->user : NULL;
|
||||
const char *passwd = Curl_creds_has_passwd(data->state.creds) ?
|
||||
data->state.creds->passwd : NULL;
|
||||
struct ip_quadruple ipquad;
|
||||
bool is_ipv6;
|
||||
BerElement *ber = NULL;
|
||||
|
|
@ -295,11 +297,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
|||
host = conn->origin->hostname;
|
||||
#endif
|
||||
|
||||
if(data->state.aptr.user) {
|
||||
user = conn->user;
|
||||
passwd = conn->passwd;
|
||||
}
|
||||
|
||||
#ifdef USE_WIN32_LDAP
|
||||
if(ldap_ssl)
|
||||
server = ldap_sslinit(host, (curl_ldap_num_t)ipquad.remote_port, 1);
|
||||
|
|
|
|||
15
lib/mqtt.c
15
lib/mqtt.c
|
|
@ -280,11 +280,9 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
|
|||
char *packet = NULL;
|
||||
|
||||
/* extracting username from request */
|
||||
const char *username = data->state.aptr.user ? data->state.aptr.user : "";
|
||||
const size_t ulen = strlen(username);
|
||||
/* extracting password from request */
|
||||
const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : "";
|
||||
const size_t plen = strlen(passwd);
|
||||
struct Curl_creds *creds = data->state.creds;
|
||||
const size_t ulen = creds ? strlen(creds->user) : 0;
|
||||
const size_t plen = creds ? strlen(creds->passwd) : 0;
|
||||
const size_t payloadlen = ulen + plen + MQTT_CLIENTID_LEN + 2 +
|
||||
/* The plus 2s below are for the MSB and LSB describing the length of the
|
||||
string to be added on the payload. Refer to spec 1.5.2 and 1.5.4 */
|
||||
|
|
@ -326,7 +324,7 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
|
|||
if(ulen) {
|
||||
start_pwd += 2;
|
||||
|
||||
rc = add_user(username, ulen,
|
||||
rc = add_user(creds->user, ulen,
|
||||
(unsigned char *)packet, start_user, remain_pos);
|
||||
if(rc) {
|
||||
failf(data, "Username too long: [%zu]", ulen);
|
||||
|
|
@ -337,7 +335,7 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
|
|||
|
||||
/* if passwd was provided, add it to the packet */
|
||||
if(plen) {
|
||||
rc = add_passwd(passwd, plen, packet, start_pwd, remain_pos);
|
||||
rc = add_passwd(creds->passwd, plen, packet, start_pwd, remain_pos);
|
||||
if(rc) {
|
||||
failf(data, "Password too long: [%zu]", plen);
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
|
|
@ -351,8 +349,7 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
|
|||
end:
|
||||
if(packet)
|
||||
curlx_free(packet);
|
||||
curlx_safefree(data->state.aptr.user);
|
||||
curlx_safefree(data->state.aptr.passwd);
|
||||
Curl_creds_unlink(&data->state.creds);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
95
lib/netrc.c
95
lib/netrc.c
|
|
@ -36,6 +36,7 @@
|
|||
#endif
|
||||
|
||||
#include "netrc.h"
|
||||
#include "creds.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "curlx/fopen.h"
|
||||
|
|
@ -108,6 +109,7 @@ static NETRCcode file2memory(const char *filename, struct dynbuf *filebuf)
|
|||
|
||||
/* bundled parser state to keep function signatures compact */
|
||||
struct netrc_state {
|
||||
struct Curl_creds *existing;
|
||||
char *login;
|
||||
char *password;
|
||||
enum host_lookup_state state;
|
||||
|
|
@ -116,7 +118,6 @@ struct netrc_state {
|
|||
unsigned char found; /* FOUND_LOGIN | FOUND_PASSWORD bits */
|
||||
bool our_login;
|
||||
bool done;
|
||||
bool specific_login;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -250,8 +251,7 @@ static void netrc_new_machine(struct netrc_state *ns)
|
|||
ns->found = 0;
|
||||
ns->our_login = FALSE;
|
||||
curlx_safefree(ns->password);
|
||||
if(!ns->specific_login)
|
||||
curlx_safefree(ns->login);
|
||||
curlx_safefree(ns->login);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -263,8 +263,8 @@ static void netrc_new_machine(struct netrc_state *ns)
|
|||
static NETRCcode netrc_hostvalid(struct netrc_state *ns, const char *tok)
|
||||
{
|
||||
if(ns->keyword == LOGIN) {
|
||||
if(ns->specific_login)
|
||||
ns->our_login = !Curl_timestrcmp(ns->login, tok);
|
||||
if(Curl_creds_has_user(ns->existing))
|
||||
ns->our_login = !Curl_timestrcmp(ns->existing->user, tok);
|
||||
else {
|
||||
ns->our_login = TRUE;
|
||||
curlx_free(ns->login);
|
||||
|
|
@ -289,15 +289,15 @@ static NETRCcode netrc_hostvalid(struct netrc_state *ns, const char *tok)
|
|||
ns->keyword = PASSWORD;
|
||||
else if(curl_strequal("machine", tok)) {
|
||||
/* a new machine here */
|
||||
bool specific_login = Curl_creds_has_user(ns->existing);
|
||||
|
||||
if(ns->found & FOUND_PASSWORD &&
|
||||
if((ns->found & FOUND_PASSWORD) &&
|
||||
/* a password was provided for this host */
|
||||
|
||||
((!ns->specific_login || ns->our_login) ||
|
||||
/* either there was no specific login to search for, or this
|
||||
is the specific one we wanted */
|
||||
(ns->specific_login && !(ns->found & FOUND_LOGIN)))) {
|
||||
/* or we look for a specific login, but that was not specified */
|
||||
(!specific_login || ns->our_login ||
|
||||
/* and found a login that is suitable
|
||||
(either matched specific one or simply present) */
|
||||
(specific_login && !(ns->found & FOUND_LOGIN)))) {
|
||||
/* or we look for a specific login, but no login was not specified */
|
||||
|
||||
ns->done = TRUE;
|
||||
return NETRC_OK;
|
||||
|
|
@ -361,38 +361,48 @@ static NETRCcode netrc_handle_token(struct netrc_state *ns,
|
|||
* resources on error.
|
||||
*/
|
||||
static NETRCcode netrc_finalize(struct netrc_state *ns,
|
||||
char **loginp,
|
||||
char **passwordp,
|
||||
struct store_netrc *store)
|
||||
struct store_netrc *store,
|
||||
struct Curl_creds **pcreds)
|
||||
{
|
||||
NETRCcode retcode = ns->retcode;
|
||||
if(!retcode) {
|
||||
if(!ns->password && ns->our_login) {
|
||||
/* success without a password, set a blank one */
|
||||
ns->password = curlx_strdup("");
|
||||
if(!ns->password)
|
||||
if(!ns->password) {
|
||||
retcode = NETRC_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if(!ns->login && !ns->password)
|
||||
else if(!ns->login && !ns->password) {
|
||||
/* a default with no credentials */
|
||||
retcode = NETRC_NO_MATCH;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if(!retcode) {
|
||||
/* success */
|
||||
if(!ns->specific_login)
|
||||
*loginp = ns->login;
|
||||
|
||||
/* netrc_finalize() can return a password even when specific_login is set
|
||||
if(!retcode) {
|
||||
/* success
|
||||
netrc_finalize() can return a password even when specific_login is set
|
||||
but our_login is false (e.g., host matched but the requested login
|
||||
never matched). See test 685. */
|
||||
*passwordp = ns->password;
|
||||
const char *login = Curl_creds_has_user(ns->existing) ?
|
||||
ns->existing->user : ns->login;
|
||||
/* 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)) {
|
||||
retcode = NETRC_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
out:
|
||||
curlx_free(ns->login);
|
||||
curlx_free(ns->password);
|
||||
if(retcode) {
|
||||
curlx_dyn_free(&store->filebuf);
|
||||
store->loaded = FALSE;
|
||||
if(!ns->specific_login)
|
||||
curlx_free(ns->login);
|
||||
curlx_free(ns->password);
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
|
@ -402,21 +412,20 @@ static NETRCcode netrc_finalize(struct netrc_state *ns,
|
|||
*/
|
||||
static NETRCcode parsenetrc(struct store_netrc *store,
|
||||
const char *host,
|
||||
char **loginp,
|
||||
char **passwordp,
|
||||
const char *netrcfile)
|
||||
struct Curl_creds *existing,
|
||||
const char *netrcfile,
|
||||
struct Curl_creds **pcreds)
|
||||
{
|
||||
const char *netrcbuffer;
|
||||
struct dynbuf token;
|
||||
struct dynbuf *filebuf = &store->filebuf;
|
||||
struct netrc_state ns;
|
||||
|
||||
DEBUGASSERT(!existing || !Curl_creds_has_passwd(existing));
|
||||
memset(&ns, 0, sizeof(ns));
|
||||
ns.retcode = NETRC_NO_MATCH;
|
||||
ns.login = *loginp;
|
||||
ns.specific_login = !!ns.login;
|
||||
ns.existing = existing;
|
||||
|
||||
DEBUGASSERT(!*passwordp);
|
||||
curlx_dyn_init(&token, MAX_NETRC_TOKEN);
|
||||
|
||||
if(!store->loaded) {
|
||||
|
|
@ -466,7 +475,7 @@ static NETRCcode parsenetrc(struct store_netrc *store,
|
|||
|
||||
out:
|
||||
curlx_dyn_free(&token);
|
||||
return netrc_finalize(&ns, loginp, passwordp, store);
|
||||
return netrc_finalize(&ns, store, pcreds);
|
||||
}
|
||||
|
||||
const char *Curl_netrc_strerror(NETRCcode ret)
|
||||
|
|
@ -493,12 +502,14 @@ const char *Curl_netrc_strerror(NETRCcode ret)
|
|||
* in.
|
||||
*/
|
||||
NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
||||
char **loginp, char **passwordp,
|
||||
const char *netrcfile)
|
||||
struct Curl_creds *existing,
|
||||
const char *netrcfile,
|
||||
struct Curl_creds **pcreds)
|
||||
{
|
||||
NETRCcode retcode = NETRC_OK;
|
||||
char *filealloc = NULL;
|
||||
|
||||
Curl_creds_unlink(pcreds);
|
||||
if(!netrcfile) {
|
||||
char *home = NULL;
|
||||
char *homea = NULL;
|
||||
|
|
@ -543,10 +554,11 @@ NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
|||
filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR);
|
||||
if(!filealloc) {
|
||||
curlx_free(homea);
|
||||
return NETRC_OUT_OF_MEMORY;
|
||||
retcode = NETRC_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
|
||||
retcode = parsenetrc(store, host, existing, filealloc, pcreds);
|
||||
curlx_free(filealloc);
|
||||
#ifdef _WIN32
|
||||
if(retcode == NETRC_FILE_MISSING) {
|
||||
|
|
@ -556,14 +568,17 @@ NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
|||
curlx_free(homea);
|
||||
return NETRC_OUT_OF_MEMORY;
|
||||
}
|
||||
retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
|
||||
retcode = parsenetrc(store, host, existing, filealloc, pcreds);
|
||||
curlx_free(filealloc);
|
||||
}
|
||||
#endif
|
||||
curlx_free(homea);
|
||||
}
|
||||
else
|
||||
retcode = parsenetrc(store, host, loginp, passwordp, netrcfile);
|
||||
retcode = parsenetrc(store, host, existing, netrcfile, pcreds);
|
||||
out:
|
||||
if(retcode)
|
||||
Curl_creds_unlink(pcreds);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "curlx/dynbuf.h"
|
||||
|
||||
struct Curl_creds;
|
||||
|
||||
struct store_netrc {
|
||||
struct dynbuf filebuf;
|
||||
char *filename;
|
||||
|
|
@ -49,8 +51,9 @@ void Curl_netrc_init(struct store_netrc *store);
|
|||
void Curl_netrc_cleanup(struct store_netrc *store);
|
||||
|
||||
NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
||||
char **loginp, char **passwordp,
|
||||
const char *netrcfile);
|
||||
struct Curl_creds *existing,
|
||||
const char *netrcfile,
|
||||
struct Curl_creds **pcreds);
|
||||
/* Assume: (*passwordp)[0]=0, host[0] != 0.
|
||||
* If (*loginp)[0] = 0, search for login and password within a machine
|
||||
* section in the netrc.
|
||||
|
|
|
|||
|
|
@ -345,9 +345,9 @@ static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate)
|
|||
passwd.bv_val = NULL;
|
||||
passwd.bv_len = 0;
|
||||
|
||||
if(data->state.aptr.user) {
|
||||
binddn = conn->user;
|
||||
passwd.bv_val = conn->passwd;
|
||||
if(data->state.creds) {
|
||||
binddn = Curl_creds_user(conn->creds);
|
||||
passwd.bv_val = CURL_UNCONST(Curl_creds_passwd(conn->creds));
|
||||
passwd.bv_len = strlen(passwd.bv_val);
|
||||
}
|
||||
|
||||
|
|
@ -355,7 +355,7 @@ static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate)
|
|||
NULL, NULL, &li->msgid);
|
||||
if(rc != LDAP_SUCCESS)
|
||||
return oldap_map_error(rc,
|
||||
data->state.aptr.user ?
|
||||
data->state.creds ?
|
||||
CURLE_LOGIN_DENIED : CURLE_LDAP_CANNOT_BIND);
|
||||
oldap_state(data, li, newstate);
|
||||
return CURLE_OK;
|
||||
|
|
@ -911,7 +911,7 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
|||
else if(ssl_installed(conn)) {
|
||||
if(li->sasl.prefmech != SASL_AUTH_NONE)
|
||||
result = oldap_perform_mechs(data);
|
||||
else if(data->state.aptr.user)
|
||||
else if(data->state.creds)
|
||||
result = oldap_perform_bind(data, OLDAP_BIND);
|
||||
else {
|
||||
/* Version 3 supported: no bind required */
|
||||
|
|
|
|||
16
lib/pop3.c
16
lib/pop3.c
|
|
@ -527,7 +527,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
|
|||
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we do not */
|
||||
if(!data->state.aptr.user) {
|
||||
if(!data->state.creds) {
|
||||
pop3_state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
|
|
@ -535,7 +535,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
|
|||
|
||||
/* Send the USER command */
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "USER %s",
|
||||
conn->user ? conn->user : "");
|
||||
Curl_creds_user(conn->creds));
|
||||
if(!result)
|
||||
pop3_state(data, POP3_USER);
|
||||
|
||||
|
|
@ -564,7 +564,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
|||
|
||||
/* Check we have a username and password to authenticate with and end the
|
||||
connect phase if we do not */
|
||||
if(!data->state.aptr.user) {
|
||||
if(!data->state.creds) {
|
||||
pop3_state(data, POP3_STOP);
|
||||
|
||||
return result;
|
||||
|
|
@ -578,8 +578,8 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
|||
Curl_MD5_update(ctxt, (const unsigned char *)pop3c->apoptimestamp,
|
||||
curlx_uztoui(strlen(pop3c->apoptimestamp)));
|
||||
|
||||
Curl_MD5_update(ctxt, (const unsigned char *)conn->passwd,
|
||||
curlx_uztoui(strlen(conn->passwd)));
|
||||
Curl_MD5_update(ctxt, (const unsigned char *)Curl_creds_passwd(conn->creds),
|
||||
curlx_uztoui(strlen(Curl_creds_passwd(conn->creds))));
|
||||
|
||||
/* Finalise the digest */
|
||||
Curl_MD5_final(ctxt, digest);
|
||||
|
|
@ -588,7 +588,8 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
|||
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
curl_msnprintf(&secret[2 * i], 3, "%02x", digest[i]);
|
||||
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret);
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s",
|
||||
Curl_creds_user(conn->creds), secret);
|
||||
|
||||
if(!result)
|
||||
pop3_state(data, POP3_APOP);
|
||||
|
|
@ -1038,7 +1039,8 @@ static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code,
|
|||
}
|
||||
else
|
||||
/* Send the PASS command */
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "PASS %s", conn->passwd);
|
||||
result = Curl_pp_sendf(data, &pop3c->pp, "PASS %s",
|
||||
Curl_creds_passwd(conn->creds));
|
||||
if(!result)
|
||||
pop3_state(data, POP3_PASS);
|
||||
|
||||
|
|
|
|||
|
|
@ -301,12 +301,6 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
|||
rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq;
|
||||
rtsp->CSeq_recv = 0;
|
||||
|
||||
/* Setup the first_* fields to allow auth details get sent
|
||||
to this origin */
|
||||
|
||||
if(!data->state.first_origin)
|
||||
Curl_peer_link(&data->state.first_origin, conn->origin);
|
||||
|
||||
/* Setup the 'p_request' pointer to the proper p_request string
|
||||
* Since all RTSP requests are included here, there is no need to
|
||||
* support custom requests like HTTP.
|
||||
|
|
|
|||
20
lib/smb.c
20
lib/smb.c
|
|
@ -61,7 +61,7 @@ enum smb_conn_state {
|
|||
/* SMB connection data, kept at connection */
|
||||
struct smb_conn {
|
||||
enum smb_conn_state state;
|
||||
char *user;
|
||||
const char *user;
|
||||
char *domain;
|
||||
char *share;
|
||||
unsigned char challenge[8];
|
||||
|
|
@ -468,13 +468,14 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
|
|||
struct connectdata *conn = data->conn;
|
||||
struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
|
||||
char *slash;
|
||||
const char *user = Curl_creds_user(conn->creds);
|
||||
|
||||
(void)done;
|
||||
if(!smbc)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Check we have a username and password to authenticate with */
|
||||
if(!data->state.aptr.user)
|
||||
if(!Curl_creds_has_user(data->state.creds))
|
||||
return CURLE_LOGIN_DENIED;
|
||||
|
||||
/* Initialize the connection state */
|
||||
|
|
@ -487,19 +488,19 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Parse the username, domain, and password */
|
||||
slash = strchr(conn->user, '/');
|
||||
slash = strchr(user, '/');
|
||||
if(!slash)
|
||||
slash = strchr(conn->user, '\\');
|
||||
slash = strchr(user, '\\');
|
||||
|
||||
if(slash) {
|
||||
smbc->user = slash + 1;
|
||||
smbc->domain = curlx_strdup(conn->user);
|
||||
smbc->domain = curlx_strdup(user);
|
||||
if(!smbc->domain)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
smbc->domain[slash - conn->user] = 0;
|
||||
smbc->domain[slash - user] = 0;
|
||||
}
|
||||
else {
|
||||
smbc->user = conn->user;
|
||||
smbc->user = user;
|
||||
smbc->domain = curlx_strdup(conn->origin->hostname);
|
||||
if(!smbc->domain)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -670,6 +671,7 @@ static CURLcode smb_send_setup(struct Curl_easy *data)
|
|||
unsigned char nt_hash[21];
|
||||
unsigned char nt[24];
|
||||
size_t byte_count;
|
||||
const char *passwd = Curl_creds_passwd(conn->creds);
|
||||
|
||||
if(!smbc || !req)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
|
@ -680,9 +682,9 @@ static CURLcode smb_send_setup(struct Curl_easy *data)
|
|||
if(byte_count > sizeof(msg.bytes))
|
||||
return CURLE_FILESIZE_EXCEEDED;
|
||||
|
||||
Curl_ntlm_core_mk_lm_hash(conn->passwd, lm_hash);
|
||||
Curl_ntlm_core_mk_lm_hash(passwd, lm_hash);
|
||||
Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
|
||||
Curl_ntlm_core_mk_nt_hash(conn->passwd, nt_hash);
|
||||
Curl_ntlm_core_mk_nt_hash(passwd, nt_hash);
|
||||
Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
|
||||
|
||||
memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes));
|
||||
|
|
|
|||
38
lib/socks.c
38
lib/socks.c
|
|
@ -99,8 +99,7 @@ struct socks_ctx {
|
|||
enum socks_state_t state;
|
||||
struct bufq iobuf;
|
||||
struct Curl_peer *dest;
|
||||
const char *user;
|
||||
const char *passwd;
|
||||
struct Curl_creds *creds;
|
||||
CURLproxycode presult;
|
||||
uint32_t resolv_id;
|
||||
uint8_t ip_version;
|
||||
|
|
@ -287,8 +286,8 @@ static CURLproxycode socks4_req_add_user(struct socks_ctx *sx,
|
|||
CURLcode result;
|
||||
size_t nwritten;
|
||||
|
||||
if(sx->user) {
|
||||
size_t plen = strlen(sx->user);
|
||||
if(sx->creds) {
|
||||
size_t plen = strlen(sx->creds->user);
|
||||
if(plen > 255) {
|
||||
/* there is no real size limit to this field in the protocol, but
|
||||
SOCKS5 limits the proxy user field to 255 bytes and it seems likely
|
||||
|
|
@ -297,7 +296,7 @@ static CURLproxycode socks4_req_add_user(struct socks_ctx *sx,
|
|||
return CURLPX_LONG_USER;
|
||||
}
|
||||
/* add proxy name WITH trailing zero */
|
||||
result = Curl_bufq_cwrite(&sx->iobuf, sx->user, plen + 1,
|
||||
result = Curl_bufq_cwrite(&sx->iobuf, sx->creds->user, plen + 1,
|
||||
&nwritten);
|
||||
if(result || (nwritten != (plen + 1)))
|
||||
return CURLPX_SEND_REQUEST;
|
||||
|
|
@ -603,7 +602,7 @@ static CURLproxycode socks5_req0_init(struct Curl_cfilter *cf,
|
|||
"CURLOPT_SOCKS5_AUTH: %u", auth);
|
||||
if(!(auth & CURLAUTH_BASIC))
|
||||
/* disable username/password auth */
|
||||
sx->user = NULL;
|
||||
Curl_creds_unlink(&sx->creds);
|
||||
|
||||
req[0] = 5; /* version */
|
||||
nauths = 1;
|
||||
|
|
@ -614,7 +613,7 @@ static CURLproxycode socks5_req0_init(struct Curl_cfilter *cf,
|
|||
req[1 + nauths] = 1; /* GSS-API */
|
||||
}
|
||||
#endif
|
||||
if(sx->user) {
|
||||
if(sx->creds) {
|
||||
++nauths;
|
||||
req[1 + nauths] = 2; /* username/password */
|
||||
}
|
||||
|
|
@ -687,9 +686,9 @@ static CURLproxycode socks5_auth_init(struct Curl_cfilter *cf,
|
|||
unsigned char buf[2];
|
||||
CURLcode result;
|
||||
|
||||
if(sx->user && sx->passwd) {
|
||||
ulen = strlen(sx->user);
|
||||
plen = strlen(sx->passwd);
|
||||
if(sx->creds) {
|
||||
ulen = strlen(sx->creds->user);
|
||||
plen = strlen(sx->creds->passwd);
|
||||
/* the lengths must fit in a single byte */
|
||||
if(ulen > 255) {
|
||||
failf(data, "Excessive username length for proxy auth");
|
||||
|
|
@ -714,7 +713,8 @@ static CURLproxycode socks5_auth_init(struct Curl_cfilter *cf,
|
|||
if(result || (nwritten != 2))
|
||||
return CURLPX_SEND_REQUEST;
|
||||
if(ulen) {
|
||||
result = Curl_bufq_cwrite(&sx->iobuf, sx->user, ulen, &nwritten);
|
||||
result = Curl_bufq_cwrite(&sx->iobuf, sx->creds->user, ulen,
|
||||
&nwritten);
|
||||
if(result || (nwritten != ulen))
|
||||
return CURLPX_SEND_REQUEST;
|
||||
}
|
||||
|
|
@ -723,7 +723,8 @@ static CURLproxycode socks5_auth_init(struct Curl_cfilter *cf,
|
|||
if(result || (nwritten != 1))
|
||||
return CURLPX_SEND_REQUEST;
|
||||
if(plen) {
|
||||
result = Curl_bufq_cwrite(&sx->iobuf, sx->passwd, plen, &nwritten);
|
||||
result = Curl_bufq_cwrite(&sx->iobuf, sx->creds->passwd, plen,
|
||||
&nwritten);
|
||||
if(result || (nwritten != plen))
|
||||
return CURLPX_SEND_REQUEST;
|
||||
}
|
||||
|
|
@ -1185,6 +1186,7 @@ static void socks_proxy_ctx_free(struct socks_ctx *ctx)
|
|||
{
|
||||
if(ctx) {
|
||||
Curl_peer_unlink(&ctx->dest);
|
||||
Curl_creds_unlink(&ctx->creds);
|
||||
Curl_bufq_free(&ctx->iobuf);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
|
|
@ -1259,10 +1261,8 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf,
|
|||
|
||||
out:
|
||||
*done = (bool)cf->connected;
|
||||
if(*done || result) {
|
||||
ctx->user = NULL;
|
||||
ctx->passwd = NULL;
|
||||
}
|
||||
if(*done || result)
|
||||
Curl_creds_unlink(&ctx->creds);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1361,8 +1361,7 @@ CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at,
|
|||
struct Curl_peer *dest,
|
||||
uint8_t ip_version,
|
||||
uint8_t proxy_type,
|
||||
const char *user,
|
||||
const char *passwd)
|
||||
struct Curl_creds *creds)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
struct socks_ctx *ctx;
|
||||
|
|
@ -1391,8 +1390,7 @@ CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at,
|
|||
Curl_peer_link(&ctx->dest, dest);
|
||||
ctx->ip_version = ip_version;
|
||||
ctx->proxy_type = proxy_type;
|
||||
ctx->user = user;
|
||||
ctx->passwd = passwd;
|
||||
Curl_creds_link(&ctx->creds, creds);
|
||||
Curl_bufq_init2(&ctx->iobuf, SOCKS_CHUNK_SIZE, SOCKS_CHUNKS,
|
||||
BUFQ_OPT_SOFT_LIMIT);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#ifndef CURL_DISABLE_PROXY
|
||||
|
||||
struct Curl_peer;
|
||||
struct Curl_creds;
|
||||
|
||||
/*
|
||||
* Helper read-from-socket functions. Does the same as Curl_read() but it
|
||||
|
|
@ -58,8 +59,7 @@ CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at,
|
|||
struct Curl_peer *dest,
|
||||
uint8_t ip_version,
|
||||
uint8_t proxy_type,
|
||||
const char *user,
|
||||
const char *passwd);
|
||||
struct Curl_creds *creds);
|
||||
|
||||
extern struct Curl_cftype Curl_cft_socks_proxy;
|
||||
|
||||
|
|
|
|||
|
|
@ -840,13 +840,14 @@ static CURLcode check_telnet_options(struct Curl_easy *data,
|
|||
|
||||
/* Add the username as an environment variable if it
|
||||
was given on the command line */
|
||||
if(data->state.aptr.user) {
|
||||
if(data->state.creds) {
|
||||
char buffer[256];
|
||||
if(str_is_nonascii(data->conn->user)) {
|
||||
if(str_is_nonascii(Curl_creds_user(data->conn->creds))) {
|
||||
DEBUGF(infof(data, "set a non ASCII username in telnet"));
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
curl_msnprintf(buffer, sizeof(buffer), "USER,%s", data->conn->user);
|
||||
curl_msnprintf(buffer, sizeof(buffer), "USER,%s",
|
||||
Curl_creds_user(data->conn->creds));
|
||||
beg = curl_slist_append(tn->telnet_vars, buffer);
|
||||
if(!beg) {
|
||||
curl_slist_free_all(tn->telnet_vars);
|
||||
|
|
|
|||
|
|
@ -438,40 +438,6 @@ void Curl_init_CONNECT(struct Curl_easy *data)
|
|||
data->state.upload = (data->state.httpreq == HTTPREQ_PUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the user credentials to those set in options.
|
||||
*/
|
||||
CURLcode Curl_reset_userpwd(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result;
|
||||
if(data->set.str[STRING_USERNAME] || data->set.str[STRING_PASSWORD])
|
||||
data->state.creds_from = CREDS_OPTION;
|
||||
result = Curl_setstropt(&data->state.aptr.user,
|
||||
data->set.str[STRING_USERNAME]);
|
||||
if(!result)
|
||||
result = Curl_setstropt(&data->state.aptr.passwd,
|
||||
data->set.str[STRING_PASSWORD]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the proxy credentials to those set in options.
|
||||
*/
|
||||
CURLcode Curl_reset_proxypwd(struct Curl_easy *data)
|
||||
{
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
CURLcode result = Curl_setstropt(&data->state.aptr.proxyuser,
|
||||
data->set.str[STRING_PROXYUSERNAME]);
|
||||
if(!result)
|
||||
result = Curl_setstropt(&data->state.aptr.proxypasswd,
|
||||
data->set.str[STRING_PROXYPASSWORD]);
|
||||
return result;
|
||||
#else
|
||||
(void)data;
|
||||
return CURLE_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_pretransfer() is called immediately before a transfer starts, and only
|
||||
* once for one transfer no matter if it has redirects or do multi-pass
|
||||
|
|
@ -524,6 +490,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
|
|||
#endif
|
||||
data->state.httpreq = data->set.method;
|
||||
|
||||
/* initial transfer request coming up, forget the initial origin
|
||||
* from a previous perform() on this handle. */
|
||||
Curl_peer_unlink(&data->state.initial_origin);
|
||||
data->state.requests = 0;
|
||||
data->state.followlocation = 0; /* reset the location-follow counter */
|
||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
||||
|
|
@ -625,11 +594,6 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!result)
|
||||
result = Curl_reset_userpwd(data);
|
||||
if(!result)
|
||||
result = Curl_reset_proxypwd(data);
|
||||
|
||||
data->req.headerbytecount = 0;
|
||||
Curl_headers_cleanup(data);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ char *Curl_checkheaders(const struct Curl_easy *data,
|
|||
|
||||
void Curl_init_CONNECT(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_reset_userpwd(struct Curl_easy *data);
|
||||
CURLcode Curl_reset_proxypwd(struct Curl_easy *data);
|
||||
CURLcode Curl_pretransfer(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_sendrecv(struct Curl_easy *data);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
|
||||
#include "asyn.h"
|
||||
#include "cookie.h"
|
||||
#include "creds.h"
|
||||
#include "psl.h"
|
||||
#include "formdata.h"
|
||||
#include "http_chunks.h" /* for the structs and enum stuff */
|
||||
|
|
@ -206,10 +207,9 @@ struct digestdata {
|
|||
BYTE *input_token;
|
||||
size_t input_token_len;
|
||||
CtxtHandle *http_context;
|
||||
/* copy of user/passwd used to make the identity for http_context.
|
||||
either may be NULL. */
|
||||
char *user;
|
||||
char *passwd;
|
||||
/* linked credentials used to make the identity for http_context.
|
||||
may be NULL. */
|
||||
struct Curl_creds *creds;
|
||||
#else
|
||||
char *nonce;
|
||||
char *cnonce;
|
||||
|
|
@ -249,7 +249,6 @@ struct ConnectBits {
|
|||
#ifndef CURL_DISABLE_PROXY
|
||||
BIT(httpproxy); /* if set, this transfer is done through an HTTP proxy */
|
||||
BIT(socksproxy); /* if set, this transfer is done through a socks proxy */
|
||||
BIT(proxy_user_passwd); /* user+password for the proxy? */
|
||||
BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy.
|
||||
This is implicit when SSL-protocols are used through
|
||||
proxies, but can also be enabled explicitly by
|
||||
|
|
@ -275,9 +274,6 @@ struct ConnectBits {
|
|||
EPRT does not work we disable it for the forthcoming
|
||||
requests */
|
||||
BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
BIT(netrc); /* name+password provided by netrc */
|
||||
#endif
|
||||
BIT(bound); /* set true if bind() has already been done on this socket/
|
||||
connection */
|
||||
|
|
@ -328,9 +324,8 @@ struct ip_quadruple {
|
|||
|
||||
struct proxy_info {
|
||||
struct Curl_peer *peer; /* proxy to this peer */
|
||||
struct Curl_creds *creds; /* use these credentials, maybe NULL */
|
||||
uint8_t proxytype; /* what kind of proxy that is in use */
|
||||
char *user; /* proxy username string, allocated */
|
||||
char *passwd; /* proxy password string, allocated */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -370,11 +365,8 @@ struct connectdata {
|
|||
struct proxy_info socks_proxy;
|
||||
struct proxy_info http_proxy;
|
||||
#endif
|
||||
char *user; /* username string, allocated */
|
||||
char *passwd; /* password string, allocated */
|
||||
struct Curl_creds *creds; /* When connection itself is tied to credentials */
|
||||
char *options; /* options string, allocated */
|
||||
char *sasl_authzid; /* authorization identity string, allocated */
|
||||
char *oauth_bearer; /* OAUTH2 bearer, allocated */
|
||||
struct curltime created; /* creation time */
|
||||
struct curltime lastused; /* when returned to the connection pool as idle */
|
||||
|
||||
|
|
@ -652,11 +644,6 @@ struct urlpieces {
|
|||
char *query;
|
||||
};
|
||||
|
||||
#define CREDS_NONE 0
|
||||
#define CREDS_URL 1 /* from URL */
|
||||
#define CREDS_OPTION 2 /* set with a CURLOPT_ */
|
||||
#define CREDS_NETRC 3 /* found in netrc */
|
||||
|
||||
struct UrlState {
|
||||
/* buffers to store authentication data in, as parsed from input options */
|
||||
struct curltime keeps_speed; /* for the progress meter really */
|
||||
|
|
@ -672,10 +659,10 @@ struct UrlState {
|
|||
curl_off_t current_speed; /* the ProgressShow() function sets this,
|
||||
bytes / second */
|
||||
|
||||
/* origin of the first (not followed) request.
|
||||
if set, this is the origin we sent authorization to, none else.
|
||||
Used to make Location: following not keep sending user+password. */
|
||||
struct Curl_peer *first_origin;
|
||||
/* Origin of the initial (e.g. not followed) request of a transfer.
|
||||
Credentials from CURLOPT_* are only valid for this origin.
|
||||
Always set once a transfer starts searching for connections. */
|
||||
struct Curl_peer *initial_origin;
|
||||
|
||||
int os_errno; /* filled in with errno whenever an error occurs */
|
||||
int requests; /* request counter: redirects + authentication retakes */
|
||||
|
|
@ -765,6 +752,8 @@ struct UrlState {
|
|||
struct store_netrc netrc;
|
||||
#endif
|
||||
|
||||
struct Curl_creds *creds; /* Credentials for the origin only */
|
||||
|
||||
/* Dynamically allocated strings, MUST be freed before this struct is
|
||||
killed. */
|
||||
struct dynamically_allocated_data {
|
||||
|
|
@ -776,14 +765,6 @@ struct UrlState {
|
|||
#ifndef CURL_DISABLE_RTSP
|
||||
char *rtsp_transport;
|
||||
#endif
|
||||
|
||||
/* transfer credentials */
|
||||
char *user;
|
||||
char *passwd;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
char *proxyuser;
|
||||
char *proxypasswd;
|
||||
#endif
|
||||
} aptr;
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
struct http_negotiation http_neg;
|
||||
|
|
@ -793,8 +774,6 @@ struct UrlState {
|
|||
CONN_MAX_RETRIES */
|
||||
uint8_t httpreq; /* Curl_HttpReq; what kind of HTTP request (if any)
|
||||
is this */
|
||||
unsigned int creds_from:2; /* where is the server credentials originating
|
||||
from, see the CREDS_* defines above */
|
||||
|
||||
/* when curl_easy_perform() is called, the multi handle is "owned" by
|
||||
the easy handle so curl_easy_cleanup() on such an easy handle will
|
||||
|
|
|
|||
|
|
@ -40,24 +40,21 @@
|
|||
*
|
||||
* Parameters:
|
||||
*
|
||||
* authzid [in] - The authorization identity.
|
||||
* authcid [in] - The authentication identity.
|
||||
* creds [in] - The credentials.
|
||||
* passwd [in] - The password.
|
||||
* out [out] - The result storage.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_plain_message(const char *authzid,
|
||||
const char *authcid,
|
||||
const char *passwd,
|
||||
CURLcode Curl_auth_create_plain_message(struct Curl_creds *creds,
|
||||
struct bufref *out)
|
||||
{
|
||||
size_t len;
|
||||
char *auth;
|
||||
|
||||
size_t zlen = (authzid == NULL ? 0 : strlen(authzid));
|
||||
size_t clen = strlen(authcid);
|
||||
size_t plen = strlen(passwd);
|
||||
size_t zlen = strlen(Curl_creds_sasl_authzid(creds));
|
||||
size_t clen = strlen(Curl_creds_user(creds));
|
||||
size_t plen = strlen(Curl_creds_passwd(creds));
|
||||
|
||||
if((zlen > CURL_MAX_INPUT_LENGTH) || (clen > CURL_MAX_INPUT_LENGTH) ||
|
||||
(plen > CURL_MAX_INPUT_LENGTH))
|
||||
|
|
@ -65,8 +62,10 @@ CURLcode Curl_auth_create_plain_message(const char *authzid,
|
|||
|
||||
len = zlen + clen + plen + 2;
|
||||
|
||||
auth = curl_maprintf("%s%c%s%c%s", authzid ? authzid : "", '\0',
|
||||
authcid, '\0', passwd);
|
||||
auth = curl_maprintf("%s%c%s%c%s",
|
||||
Curl_creds_sasl_authzid(creds), '\0',
|
||||
Curl_creds_user(creds), '\0',
|
||||
Curl_creds_passwd(creds));
|
||||
if(!auth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
Curl_bufref_set(out, auth, len, curl_free);
|
||||
|
|
|
|||
|
|
@ -47,18 +47,19 @@
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
struct bufref *out)
|
||||
{
|
||||
struct HMAC_context *ctxt;
|
||||
unsigned char digest[MD5_DIGEST_LEN];
|
||||
char *response;
|
||||
const char *user = Curl_creds_user(creds);
|
||||
const char *passwd = Curl_creds_passwd(creds);
|
||||
|
||||
/* Compute the digest using the password as the key */
|
||||
ctxt = Curl_HMAC_init(&Curl_HMAC_MD5,
|
||||
(const unsigned char *)passwdp,
|
||||
curlx_uztoui(strlen(passwdp)));
|
||||
(const unsigned char *)passwd,
|
||||
curlx_uztoui(strlen(passwd)));
|
||||
if(!ctxt)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
|||
/* Generate the response */
|
||||
response = curl_maprintf(
|
||||
"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
userp, digest[0], digest[1], digest[2], digest[3], digest[4],
|
||||
user, digest[0], digest[1], digest[2], digest[3], digest[4],
|
||||
digest[5], digest[6], digest[7], digest[8], digest[9], digest[10],
|
||||
digest[11], digest[12], digest[13], digest[14], digest[15]);
|
||||
if(!response)
|
||||
|
|
|
|||
|
|
@ -332,13 +332,14 @@ bool Curl_auth_is_digest_supported(void)
|
|||
*/
|
||||
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
const struct bufref *chlg,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
struct bufref *out)
|
||||
{
|
||||
size_t i;
|
||||
struct MD5_context *ctxt;
|
||||
const char *userp = Curl_creds_user(creds);
|
||||
const char *passwdp = Curl_creds_passwd(creds);
|
||||
char *response = NULL;
|
||||
unsigned char digest[MD5_DIGEST_LEN];
|
||||
char HA1_hex[(2 * MD5_DIGEST_LEN) + 1];
|
||||
|
|
@ -666,8 +667,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
|||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* userp [in] - The username.
|
||||
* passwdp [in] - The user's password.
|
||||
* creds [in] - The credentials
|
||||
* request [in] - The HTTP request.
|
||||
* uripath [in] - The path of the HTTP uri.
|
||||
* digest [in/out] - The digest data struct being used and modified.
|
||||
|
|
@ -679,8 +679,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
|||
*/
|
||||
static CURLcode auth_create_digest_http_message(
|
||||
struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uripath,
|
||||
struct digestdata *digest,
|
||||
|
|
@ -689,6 +688,8 @@ static CURLcode auth_create_digest_http_message(
|
|||
CURLcode (*hash)(unsigned char *, const unsigned char *, const size_t))
|
||||
{
|
||||
CURLcode result;
|
||||
const char *userp = Curl_creds_user(creds);
|
||||
const char *passwdp = Curl_creds_passwd(creds);
|
||||
unsigned char hashbuf[32]; /* 32 bytes/256 bits */
|
||||
unsigned char request_digest[65];
|
||||
unsigned char ha1[65]; /* 64 digits and 1 zero byte */
|
||||
|
|
@ -986,29 +987,28 @@ oom:
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uripath,
|
||||
struct digestdata *digest,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
if(digest->algo <= ALGO_MD5SESS)
|
||||
return auth_create_digest_http_message(data, userp, passwdp,
|
||||
return auth_create_digest_http_message(data, creds,
|
||||
request, uripath, digest,
|
||||
outptr, outlen,
|
||||
auth_digest_md5_to_ascii,
|
||||
Curl_md5it);
|
||||
|
||||
if(digest->algo <= ALGO_SHA256SESS)
|
||||
return auth_create_digest_http_message(data, userp, passwdp,
|
||||
return auth_create_digest_http_message(data, creds,
|
||||
request, uripath, digest,
|
||||
outptr, outlen,
|
||||
auth_digest_sha256_to_ascii,
|
||||
Curl_sha256it);
|
||||
#ifdef CURL_HAVE_SHA512_256
|
||||
if(digest->algo <= ALGO_SHA512_256SESS)
|
||||
return auth_create_digest_http_message(data, userp, passwdp,
|
||||
return auth_create_digest_http_message(data, creds,
|
||||
request, uripath, digest,
|
||||
outptr, outlen,
|
||||
auth_digest_sha256_to_ascii,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_DIGEST_AUTH)
|
||||
|
||||
#include "creds.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "vauth/digest.h"
|
||||
#include "curlx/multibyte.h"
|
||||
|
|
@ -83,8 +84,7 @@ bool Curl_auth_is_digest_supported(void)
|
|||
*/
|
||||
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
const struct bufref *chlg,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
struct bufref *out)
|
||||
{
|
||||
|
|
@ -137,9 +137,10 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(userp && *userp) {
|
||||
if(Curl_creds_has_user(creds)) {
|
||||
/* Populate our identity structure */
|
||||
result = Curl_create_sspi_identity(userp, passwdp, &identity);
|
||||
result = Curl_create_sspi_identity(creds->user, creds->passwd,
|
||||
&identity);
|
||||
if(result) {
|
||||
curlx_free(spn);
|
||||
curlx_free(output_token);
|
||||
|
|
@ -381,8 +382,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uripath,
|
||||
struct digestdata *digest,
|
||||
|
|
@ -421,16 +421,12 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
|||
|
||||
/* If the user/passwd that was used to make the identity for http_context
|
||||
has changed then delete that context. */
|
||||
if((userp && !digest->user) || (!userp && digest->user) ||
|
||||
(passwdp && !digest->passwd) || (!passwdp && digest->passwd) ||
|
||||
(userp && digest->user && Curl_timestrcmp(userp, digest->user)) ||
|
||||
(passwdp && digest->passwd && Curl_timestrcmp(passwdp, digest->passwd))) {
|
||||
if(!Curl_creds_same(creds, digest->creds)) {
|
||||
if(digest->http_context) {
|
||||
Curl_pSecFn->DeleteSecurityContext(digest->http_context);
|
||||
curlx_safefree(digest->http_context);
|
||||
}
|
||||
curlx_safefree(digest->user);
|
||||
curlx_safefree(digest->passwd);
|
||||
Curl_creds_unlink(&digest->creds);
|
||||
}
|
||||
|
||||
if(digest->http_context) {
|
||||
|
|
@ -473,13 +469,13 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
|||
unsigned long attrs;
|
||||
TCHAR *spn;
|
||||
|
||||
/* free the copy of user/passwd used to make the previous identity */
|
||||
curlx_safefree(digest->user);
|
||||
curlx_safefree(digest->passwd);
|
||||
/* free the credentials used to make the previous identity */
|
||||
Curl_creds_unlink(&digest->creds);
|
||||
|
||||
if(userp && *userp) {
|
||||
if(Curl_creds_has_user(creds)) {
|
||||
/* Populate our identity structure */
|
||||
if(Curl_create_sspi_identity(userp, passwdp, &identity)) {
|
||||
if(Curl_create_sspi_identity(creds->user, creds->passwd,
|
||||
&identity)) {
|
||||
curlx_free(output_token);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
@ -499,26 +495,8 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
|||
/* Use the current Windows user */
|
||||
p_identity = NULL;
|
||||
|
||||
if(userp) {
|
||||
digest->user = curlx_strdup(userp);
|
||||
|
||||
if(!digest->user) {
|
||||
curlx_free(output_token);
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if(passwdp) {
|
||||
digest->passwd = curlx_strdup(passwdp);
|
||||
|
||||
if(!digest->passwd) {
|
||||
curlx_free(output_token);
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
curlx_safefree(digest->user);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
if(creds)
|
||||
Curl_creds_link(&digest->creds, creds);
|
||||
|
||||
/* Acquire our credentials handle */
|
||||
status = Curl_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
|
|
@ -649,8 +627,7 @@ void Curl_auth_digest_cleanup(struct digestdata *digest)
|
|||
}
|
||||
|
||||
/* Free the copy of user/passwd used to make the identity for http_context */
|
||||
curlx_safefree(digest->user);
|
||||
curlx_safefree(digest->passwd);
|
||||
Curl_creds_unlink(&digest->creds);
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_DIGEST_AUTH */
|
||||
|
|
|
|||
|
|
@ -54,15 +54,14 @@ bool Curl_auth_gsasl_is_supported(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
struct gsasldata *gsasl)
|
||||
{
|
||||
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||
int res;
|
||||
res =
|
||||
#endif
|
||||
gsasl_property_set(gsasl->client, GSASL_AUTHID, userp);
|
||||
gsasl_property_set(gsasl->client, GSASL_AUTHID, creds->user);
|
||||
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||
if(res != GSASL_OK) {
|
||||
failf(data, "setting AUTHID failed: %s", gsasl_strerror(res));
|
||||
|
|
@ -73,7 +72,7 @@ CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
|
|||
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||
res =
|
||||
#endif
|
||||
gsasl_property_set(gsasl->client, GSASL_PASSWORD, passwdp);
|
||||
gsasl_property_set(gsasl->client, GSASL_PASSWORD, creds->passwd);
|
||||
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||
if(res != GSASL_OK) {
|
||||
failf(data, "setting PASSWORD failed: %s", gsasl_strerror(res));
|
||||
|
|
|
|||
|
|
@ -74,8 +74,7 @@ bool Curl_auth_is_gssapi_supported(void)
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
const bool mutual_auth,
|
||||
|
|
@ -90,8 +89,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
|||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
|
||||
(void)userp;
|
||||
(void)passwdp;
|
||||
(void)creds;
|
||||
|
||||
if(!krb5->spn) {
|
||||
gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
|
||||
|
|
|
|||
|
|
@ -79,8 +79,7 @@ bool Curl_auth_is_gssapi_supported(void)
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
const bool mutual_auth,
|
||||
|
|
@ -128,9 +127,10 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
|||
|
||||
if(!krb5->credentials) {
|
||||
/* Do we have credentials to use or are we using single sign-on? */
|
||||
if(userp && *userp) {
|
||||
if(Curl_creds_has_user(creds)) {
|
||||
/* Populate our identity structure */
|
||||
result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity);
|
||||
result = Curl_create_sspi_identity(
|
||||
creds->user, creds->passwd, &krb5->identity);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -421,8 +421,7 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
struct ntlmdata *ntlm,
|
||||
|
|
@ -453,8 +452,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
|||
size_t domoff = hostoff + hostlen; /* This is 0: remember that host and
|
||||
domain are empty */
|
||||
(void)data;
|
||||
(void)userp;
|
||||
(void)passwdp;
|
||||
(void)creds;
|
||||
(void)service;
|
||||
(void)host;
|
||||
|
||||
|
|
@ -542,8 +540,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
struct ntlmdata *ntlm,
|
||||
struct bufref *out)
|
||||
{
|
||||
|
|
@ -579,6 +576,8 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||
/* The fixed hostname we provide, in order to not leak our real local host
|
||||
name. Copy the name used by Firefox. */
|
||||
static const char host[] = "WORKSTATION";
|
||||
const char *userp = Curl_creds_user(creds);
|
||||
const char *passwdp = Curl_creds_passwd(creds);
|
||||
const char *user;
|
||||
const char *domain = "";
|
||||
size_t hostoff = 0;
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@ bool Curl_auth_is_ntlm_supported(void)
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
struct ntlmdata *ntlm,
|
||||
|
|
@ -111,11 +110,12 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
|||
if(!ntlm->output_token)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(userp && *userp) {
|
||||
if(Curl_creds_has_user(creds)) {
|
||||
CURLcode result;
|
||||
|
||||
/* Populate our identity structure */
|
||||
result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity);
|
||||
result = Curl_create_sspi_identity(
|
||||
creds->user, creds->passwd, &ntlm->identity);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
|
@ -227,8 +227,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
struct ntlmdata *ntlm,
|
||||
struct bufref *out)
|
||||
{
|
||||
|
|
@ -240,8 +239,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||
SECURITY_STATUS status;
|
||||
unsigned long attrs;
|
||||
|
||||
(void)passwdp;
|
||||
(void)userp;
|
||||
(void)creds;
|
||||
|
||||
/* Setup the type-2 "input" security buffer */
|
||||
type_2_desc.ulVersion = SECBUFFER_VERSION;
|
||||
|
|
|
|||
|
|
@ -47,21 +47,22 @@
|
|||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_oauth_bearer_message(const char *user,
|
||||
CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_creds *creds,
|
||||
const char *host,
|
||||
const long port,
|
||||
const char *bearer,
|
||||
struct bufref *out)
|
||||
{
|
||||
char *oauth;
|
||||
|
||||
/* Generate the message */
|
||||
if(port == 0 || port == 80)
|
||||
oauth = curl_maprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host,
|
||||
bearer);
|
||||
oauth = curl_maprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1",
|
||||
Curl_creds_user(creds), host,
|
||||
Curl_creds_oauth_bearer(creds));
|
||||
else
|
||||
oauth = curl_maprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1",
|
||||
user, host, port, bearer);
|
||||
Curl_creds_user(creds), host, port,
|
||||
Curl_creds_oauth_bearer(creds));
|
||||
if(!oauth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -83,12 +84,13 @@ CURLcode Curl_auth_create_oauth_bearer_message(const char *user,
|
|||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_create_xoauth_bearer_message(const char *user,
|
||||
const char *bearer,
|
||||
CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_creds *creds,
|
||||
struct bufref *out)
|
||||
{
|
||||
/* Generate the message */
|
||||
char *xoauth = curl_maprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
|
||||
char *xoauth = curl_maprintf("user=%s\1auth=Bearer %s\1\1",
|
||||
Curl_creds_user(creds),
|
||||
Curl_creds_oauth_bearer(creds));
|
||||
if(!xoauth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
|
|
|||
|
|
@ -70,8 +70,7 @@ bool Curl_auth_is_spnego_supported(void)
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||
const char *user,
|
||||
const char *password,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
const char *chlg64,
|
||||
|
|
@ -90,8 +89,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
struct gss_channel_bindings_struct chan;
|
||||
#endif
|
||||
|
||||
(void)user;
|
||||
(void)password;
|
||||
(void)creds;
|
||||
|
||||
if(nego->context && nego->status == GSS_S_COMPLETE) {
|
||||
/* We finished successfully our part of authentication, but server
|
||||
|
|
|
|||
|
|
@ -78,8 +78,7 @@ bool Curl_auth_is_spnego_supported(void)
|
|||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||
const char *user,
|
||||
const char *password,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
const char *chlg64,
|
||||
|
|
@ -133,9 +132,10 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
|
||||
if(!nego->credentials) {
|
||||
/* Do we have credentials to use or are we using single sign-on? */
|
||||
if(user && *user) {
|
||||
if(Curl_creds_has_user(creds)) {
|
||||
/* Populate our identity structure */
|
||||
result = Curl_create_sspi_identity(user, password, &nego->identity);
|
||||
result = Curl_create_sspi_identity(creds->user, creds->passwd,
|
||||
&nego->identity);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "curl_setup.h"
|
||||
|
||||
#include "vauth/vauth.h"
|
||||
#include "creds.h"
|
||||
#include "curlx/multibyte.h"
|
||||
#include "url.h"
|
||||
|
||||
|
|
@ -111,15 +112,16 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
|
|||
*
|
||||
* Returns TRUE on success; otherwise FALSE.
|
||||
*/
|
||||
bool Curl_auth_user_contains_domain(const char *user)
|
||||
bool Curl_auth_user_contains_domain(struct Curl_creds *creds)
|
||||
{
|
||||
bool valid = FALSE;
|
||||
|
||||
if(user && *user) {
|
||||
if(Curl_creds_has_user(creds)) {
|
||||
/* Check we have a domain name or UPN present */
|
||||
const char *p = strpbrk(user, "\\/@");
|
||||
const char *p = strpbrk(creds->user, "\\/@");
|
||||
|
||||
valid = (p != NULL && p > user && p < user + strlen(user) - 1);
|
||||
valid = (p != NULL) && (p > creds->user) &&
|
||||
(p < (creds->user + strlen(creds->user) - 1));
|
||||
}
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
else
|
||||
|
|
@ -133,14 +135,12 @@ bool Curl_auth_user_contains_domain(const char *user)
|
|||
|
||||
/*
|
||||
* Curl_auth_allowed_to_host() tells if authentication, cookies or other
|
||||
* "sensitive data" can (still) be sent to this host.
|
||||
* "sensitive data" can be sent to the connection's origin.
|
||||
*/
|
||||
bool Curl_auth_allowed_to_host(struct Curl_easy *data)
|
||||
{
|
||||
return !data->state.this_is_a_follow ||
|
||||
data->set.allow_auth_to_other_hosts ||
|
||||
(data->state.first_origin &&
|
||||
Curl_peer_equal(data->state.first_origin, data->conn->origin));
|
||||
return data->set.allow_auth_to_other_hosts ||
|
||||
Curl_peer_equal(data->state.initial_origin, data->conn->origin);
|
||||
}
|
||||
|
||||
#ifdef USE_NTLM
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "urldata.h"
|
||||
|
||||
struct Curl_easy;
|
||||
struct Curl_creds;
|
||||
struct connectdata;
|
||||
|
||||
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||
|
|
@ -69,12 +70,10 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
|
|||
#endif
|
||||
|
||||
/* This is used to test if the user contains a Windows domain name */
|
||||
bool Curl_auth_user_contains_domain(const char *user);
|
||||
bool Curl_auth_user_contains_domain(struct Curl_creds *creds);
|
||||
|
||||
/* This is used to generate a PLAIN cleartext message */
|
||||
CURLcode Curl_auth_create_plain_message(const char *authzid,
|
||||
const char *authcid,
|
||||
const char *passwd,
|
||||
CURLcode Curl_auth_create_plain_message(struct Curl_creds *creds,
|
||||
struct bufref *out);
|
||||
|
||||
/* This is used to generate a LOGIN cleartext message */
|
||||
|
|
@ -86,8 +85,7 @@ void Curl_auth_create_external_message(const char *user, struct bufref *out);
|
|||
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||
/* This is used to generate a CRAM-MD5 response message */
|
||||
CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
struct bufref *out);
|
||||
|
||||
/* This is used to evaluate if DIGEST is supported */
|
||||
|
|
@ -96,8 +94,7 @@ bool Curl_auth_is_digest_supported(void);
|
|||
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
||||
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
const struct bufref *chlg,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
struct bufref *out);
|
||||
|
||||
|
|
@ -107,8 +104,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
|||
|
||||
/* This is used to generate an HTTP DIGEST response message */
|
||||
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uripath,
|
||||
struct digestdata *digest,
|
||||
|
|
@ -140,8 +136,7 @@ bool Curl_auth_gsasl_is_supported(struct Curl_easy *data,
|
|||
struct gsasldata *gsasl);
|
||||
/* This is used to start a gsasl method */
|
||||
CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
struct gsasldata *gsasl);
|
||||
|
||||
/* This is used to process and generate a new SASL token */
|
||||
|
|
@ -197,8 +192,7 @@ void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm);
|
|||
|
||||
/* This is used to generate a base64 encoded NTLM type-1 message */
|
||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
struct ntlmdata *ntlm,
|
||||
|
|
@ -211,8 +205,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
|
|||
|
||||
/* This is used to generate a base64 encoded NTLM type-3 message */
|
||||
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
struct ntlmdata *ntlm,
|
||||
struct bufref *out);
|
||||
|
||||
|
|
@ -221,15 +214,13 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||
#endif /* USE_NTLM */
|
||||
|
||||
/* This is used to generate a base64 encoded OAuth 2.0 message */
|
||||
CURLcode Curl_auth_create_oauth_bearer_message(const char *user,
|
||||
CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_creds *creds,
|
||||
const char *host,
|
||||
const long port,
|
||||
const char *bearer,
|
||||
struct bufref *out);
|
||||
|
||||
/* This is used to generate a base64 encoded XOAuth 2.0 message */
|
||||
CURLcode Curl_auth_create_xoauth_bearer_message(const char *user,
|
||||
const char *bearer,
|
||||
CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_creds *creds,
|
||||
struct bufref *out);
|
||||
|
||||
#ifdef USE_KERBEROS5
|
||||
|
|
@ -260,8 +251,7 @@ bool Curl_auth_is_gssapi_supported(void);
|
|||
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
|
||||
message */
|
||||
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
const bool mutual_auth,
|
||||
|
|
@ -330,8 +320,7 @@ Curl_auth_nego_get(struct connectdata *conn, bool proxy);
|
|||
/* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge
|
||||
message */
|
||||
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||
const char *user,
|
||||
const char *password,
|
||||
struct Curl_creds *creds,
|
||||
const char *service,
|
||||
const char *host,
|
||||
const char *chlg64,
|
||||
|
|
|
|||
|
|
@ -633,7 +633,8 @@ restart:
|
|||
if(nprompts != 1)
|
||||
return SSH_ERROR;
|
||||
|
||||
rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd);
|
||||
rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0,
|
||||
Curl_creds_passwd(conn->creds));
|
||||
if(rc < 0)
|
||||
return SSH_ERROR;
|
||||
|
||||
|
|
@ -920,7 +921,8 @@ static int myssh_in_AUTH_PASS_INIT(struct Curl_easy *data,
|
|||
static int myssh_in_AUTH_PASS(struct Curl_easy *data,
|
||||
struct ssh_conn *sshc)
|
||||
{
|
||||
int rc = ssh_userauth_password(sshc->ssh_session, NULL, data->conn->passwd);
|
||||
int rc = ssh_userauth_password(sshc->ssh_session, NULL,
|
||||
Curl_creds_passwd(data->conn->creds));
|
||||
if(rc == SSH_AUTH_AGAIN)
|
||||
return SSH_AGAIN;
|
||||
else if(rc == SSH_AUTH_SUCCESS) {
|
||||
|
|
@ -2571,9 +2573,10 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
|
|||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
if(conn->user && conn->user[0] != '\0') {
|
||||
infof(data, "User: %s", conn->user);
|
||||
rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_USER, conn->user);
|
||||
if(Curl_creds_has_user(conn->creds)) {
|
||||
infof(data, "User: %s", conn->creds->user);
|
||||
rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_USER,
|
||||
conn->creds->user);
|
||||
if(rc != SSH_OK) {
|
||||
failf(data, "Could not set user");
|
||||
return CURLE_FAILED_INIT;
|
||||
|
|
|
|||
|
|
@ -148,11 +148,12 @@ static void kbd_callback(const char *name, int name_len,
|
|||
#endif /* CURL_LIBSSH2_DEBUG */
|
||||
if(num_prompts == 1) {
|
||||
struct connectdata *conn = data->conn;
|
||||
const char *passwd = Curl_creds_passwd(conn->creds);
|
||||
/* this function must allocate memory that can be freed by libssh2, which
|
||||
uses the LIBSSH2_FREE_FUNC callback */
|
||||
responses[0].text = Curl_cstrdup(conn->passwd);
|
||||
responses[0].text = Curl_cstrdup(passwd);
|
||||
responses[0].length =
|
||||
responses[0].text == NULL ? 0 : curlx_uztoui(strlen(conn->passwd));
|
||||
responses[0].text == NULL ? 0 : curlx_uztoui(strlen(passwd));
|
||||
}
|
||||
(void)prompts;
|
||||
} /* kbd_callback */
|
||||
|
|
@ -1496,9 +1497,9 @@ static CURLcode ssh_state_authlist(struct Curl_easy *data,
|
|||
* Therefore always specify it here.
|
||||
*/
|
||||
struct connectdata *conn = data->conn;
|
||||
const char *user = Curl_creds_user(conn->creds);
|
||||
sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
|
||||
conn->user,
|
||||
curlx_uztoui(strlen(conn->user)));
|
||||
user, curlx_uztoui(strlen(user)));
|
||||
|
||||
if(!sshc->authlist) {
|
||||
int rc;
|
||||
|
|
@ -1527,11 +1528,11 @@ static CURLcode ssh_state_auth_pkey(struct Curl_easy *data,
|
|||
/* The function below checks if the files exists, no need to stat() here.
|
||||
*/
|
||||
struct connectdata *conn = data->conn;
|
||||
const char *user = Curl_creds_user(conn->creds);
|
||||
int rc =
|
||||
libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
|
||||
conn->user,
|
||||
curlx_uztoui(
|
||||
strlen(conn->user)),
|
||||
user,
|
||||
curlx_uztoui(strlen(user)),
|
||||
sshc->rsa_pub,
|
||||
sshc->rsa, sshc->passphrase);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
|
|
@ -1579,11 +1580,13 @@ static CURLcode ssh_state_auth_pass(struct Curl_easy *data,
|
|||
struct ssh_conn *sshc)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
const char *user = Curl_creds_user(conn->creds);
|
||||
const char *passwd = Curl_creds_passwd(conn->creds);
|
||||
int rc =
|
||||
libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
|
||||
curlx_uztoui(strlen(conn->user)),
|
||||
conn->passwd,
|
||||
curlx_uztoui(strlen(conn->passwd)),
|
||||
libssh2_userauth_password_ex(sshc->ssh_session, user,
|
||||
curlx_uztoui(strlen(user)),
|
||||
passwd,
|
||||
curlx_uztoui(strlen(passwd)),
|
||||
NULL);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return CURLE_AGAIN;
|
||||
|
|
@ -1680,7 +1683,7 @@ static CURLcode ssh_state_auth_agent(struct Curl_easy *data,
|
|||
|
||||
if(rc == 0) {
|
||||
struct connectdata *conn = data->conn;
|
||||
rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
|
||||
rc = libssh2_agent_userauth(sshc->ssh_agent, Curl_creds_user(conn->creds),
|
||||
sshc->sshagent_identity);
|
||||
|
||||
if(rc < 0) {
|
||||
|
|
@ -1727,11 +1730,10 @@ static CURLcode ssh_state_auth_key(struct Curl_easy *data,
|
|||
{
|
||||
/* Authentication failed. Continue with keyboard-interactive now. */
|
||||
struct connectdata *conn = data->conn;
|
||||
const char *user = Curl_creds_user(conn->creds);
|
||||
int rc =
|
||||
libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
|
||||
conn->user,
|
||||
curlx_uztoui(
|
||||
strlen(conn->user)),
|
||||
user, curlx_uztoui(strlen(user)),
|
||||
&kbd_callback);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return CURLE_AGAIN;
|
||||
|
|
@ -3452,9 +3454,9 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
|
|||
if(!sshc)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
infof(data, "User: '%s'", conn->user);
|
||||
infof(data, "User: '%s'", Curl_creds_user(conn->creds));
|
||||
#ifdef CURL_LIBSSH2_DEBUG
|
||||
infof(data, "Password: %s", conn->passwd);
|
||||
infof(data, "Password: %s", Curl_creds_passwd(conn->creds));
|
||||
sock = conn->sock[FIRSTSOCKET];
|
||||
#endif /* CURL_LIBSSH2_DEBUG */
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ static CURLcode test_lib1978(const char *URL)
|
|||
test_setopt(curl, CURLOPT_INFILESIZE, 0L);
|
||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3");
|
||||
test_setopt(curl, CURLOPT_USERPWD, "xxx");
|
||||
test_setopt(curl, CURLOPT_HEADER, 0L);
|
||||
test_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,17 +25,37 @@
|
|||
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
#include "netrc.h"
|
||||
#include "creds.h"
|
||||
|
||||
static void t1304_stop(char **password, char **login)
|
||||
static void t1304_stop(struct Curl_creds **pc1, struct Curl_creds **pc2)
|
||||
{
|
||||
curlx_safefree(*password);
|
||||
curlx_safefree(*login);
|
||||
Curl_creds_unlink(pc1);
|
||||
Curl_creds_unlink(pc2);
|
||||
}
|
||||
|
||||
static bool t1304_set_creds(const char *user, const char *passwd,
|
||||
struct Curl_creds **pcreds)
|
||||
{
|
||||
Curl_creds_unlink(pcreds);
|
||||
if(user || passwd)
|
||||
return !Curl_creds_create(user, passwd, NULL, NULL, CREDS_NONE, pcreds);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool t1304_no_user(struct Curl_creds *creds)
|
||||
{
|
||||
return !creds || !creds->user[0];
|
||||
}
|
||||
|
||||
static bool t1304_no_passwd(struct Curl_creds *creds)
|
||||
{
|
||||
return !creds || !creds->passwd[0];
|
||||
}
|
||||
|
||||
static CURLcode test_unit1304(const char *arg)
|
||||
{
|
||||
char *login = NULL;
|
||||
char *password = NULL;
|
||||
struct Curl_creds *cr_out = NULL, *cr_in = NULL;
|
||||
|
||||
UNITTEST_BEGIN_SIMPLE
|
||||
|
||||
|
|
@ -46,126 +66,119 @@ static CURLcode test_unit1304(const char *arg)
|
|||
* Test a non existent host in our netrc file.
|
||||
*/
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "test.example.com", &login, &password, arg);
|
||||
fail_unless(result == 1, "Host not found should return 1");
|
||||
abort_unless(password == NULL, "password did not return NULL!");
|
||||
abort_unless(login == NULL, "user did not return NULL!");
|
||||
result = Curl_parsenetrc(&store, "test.example.com", NULL, arg, &cr_out);
|
||||
fail_unless(result == 1, "expected no match");
|
||||
abort_unless(cr_out == NULL, "creds did not return NULL!");
|
||||
Curl_netrc_cleanup(&store);
|
||||
|
||||
/*
|
||||
* Test a non existent login in our netrc file.
|
||||
*/
|
||||
login = curlx_strdup("me");
|
||||
fail_unless(t1304_set_creds("me", NULL, &cr_in), "err set creds");
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "example.com", &login, &password, arg);
|
||||
fail_unless(result == 0, "Host should have been found");
|
||||
abort_unless(password == NULL, "password is not NULL!");
|
||||
result = Curl_parsenetrc(&store, "example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 1, "expected no match");
|
||||
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||
Curl_netrc_cleanup(&store);
|
||||
curlx_free(login);
|
||||
|
||||
/*
|
||||
* Test a non existent login and host in our netrc file.
|
||||
*/
|
||||
login = curlx_strdup("me");
|
||||
fail_unless(t1304_set_creds("me", NULL, &cr_in), "err set creds");
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "test.example.com", &login, &password, arg);
|
||||
fail_unless(result == 1, "Host not found should return 1");
|
||||
abort_unless(password == NULL, "password is not NULL!");
|
||||
result = Curl_parsenetrc(&store, "test.example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 1, "expected no match");
|
||||
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||
Curl_netrc_cleanup(&store);
|
||||
curlx_free(login);
|
||||
|
||||
/*
|
||||
* Test a non existent login (substring of an existing one) in our
|
||||
* netrc file.
|
||||
*/
|
||||
login = curlx_strdup("admi"); /* spellchecker:disable-line */
|
||||
fail_unless(t1304_set_creds(
|
||||
"admi", NULL, &cr_in), "err set creds"); /* spellchecker:disable-line */
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "example.com", &login, &password, arg);
|
||||
fail_unless(result == 0, "Host should have been found");
|
||||
abort_unless(password == NULL, "password is not NULL!");
|
||||
result = Curl_parsenetrc(&store, "example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 1, "expected no match");
|
||||
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||
Curl_netrc_cleanup(&store);
|
||||
curlx_free(login);
|
||||
|
||||
/*
|
||||
* Test a non existent login (superstring of an existing one)
|
||||
* in our netrc file.
|
||||
*/
|
||||
login = curlx_strdup("adminn");
|
||||
fail_unless(t1304_set_creds("adminn", NULL, &cr_in), "err set creds");
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "example.com", &login, &password, arg);
|
||||
fail_unless(result == 0, "Host should have been found");
|
||||
abort_unless(password == NULL, "password is not NULL!");
|
||||
result = Curl_parsenetrc(&store, "example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 1, "expected no match");
|
||||
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||
Curl_netrc_cleanup(&store);
|
||||
curlx_free(login);
|
||||
|
||||
/*
|
||||
* Test for the first existing host in our netrc file
|
||||
* with login[0] = 0.
|
||||
*/
|
||||
login = NULL;
|
||||
Curl_creds_unlink(&cr_in);
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "example.com", &login, &password, arg);
|
||||
result = Curl_parsenetrc(&store, "example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 0, "Host should have been found");
|
||||
abort_unless(password != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(password, "passwd", 6) == 0,
|
||||
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_passwd(cr_out), "passwd", 6) == 0,
|
||||
"password should be 'passwd'");
|
||||
abort_unless(login != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(login, "admin", 5) == 0, "login should be 'admin'");
|
||||
abort_unless(!t1304_no_user(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_user(cr_out), "admin", 5) == 0,
|
||||
"login should be 'admin'");
|
||||
Curl_netrc_cleanup(&store);
|
||||
|
||||
/*
|
||||
* Test for the first existing host in our netrc file
|
||||
* with login[0] != 0.
|
||||
*/
|
||||
curlx_free(password);
|
||||
curlx_free(login);
|
||||
password = NULL;
|
||||
login = NULL;
|
||||
Curl_creds_unlink(&cr_in);
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "example.com", &login, &password, arg);
|
||||
result = Curl_parsenetrc(&store, "example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 0, "Host should have been found");
|
||||
abort_unless(password != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(password, "passwd", 6) == 0,
|
||||
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_passwd(cr_out), "passwd", 6) == 0,
|
||||
"password should be 'passwd'");
|
||||
abort_unless(login != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(login, "admin", 5) == 0, "login should be 'admin'");
|
||||
abort_unless(!t1304_no_user(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_user(cr_out), "admin", 5) == 0,
|
||||
"login should be 'admin'");
|
||||
Curl_netrc_cleanup(&store);
|
||||
|
||||
/*
|
||||
* Test for the second existing host in our netrc file
|
||||
* with login[0] = 0.
|
||||
*/
|
||||
curlx_free(password);
|
||||
password = NULL;
|
||||
curlx_free(login);
|
||||
login = NULL;
|
||||
Curl_creds_unlink(&cr_in);
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "curl.example.com", &login, &password, arg);
|
||||
result = Curl_parsenetrc(&store, "curl.example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 0, "Host should have been found");
|
||||
abort_unless(password != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(password, "none", 4) == 0, "password should be 'none'");
|
||||
abort_unless(login != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(login, "none", 4) == 0, "login should be 'none'");
|
||||
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_passwd(cr_out), "none", 4) == 0,
|
||||
"password should be 'none'");
|
||||
abort_unless(!t1304_no_user(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_user(cr_out), "none", 4) == 0,
|
||||
"login should be 'none'");
|
||||
Curl_netrc_cleanup(&store);
|
||||
|
||||
/*
|
||||
* Test for the second existing host in our netrc file
|
||||
* with login[0] != 0.
|
||||
*/
|
||||
curlx_free(password);
|
||||
password = NULL;
|
||||
curlx_free(login);
|
||||
login = NULL;
|
||||
Curl_creds_unlink(&cr_in);
|
||||
Curl_netrc_init(&store);
|
||||
result = Curl_parsenetrc(&store, "curl.example.com", &login, &password, arg);
|
||||
result = Curl_parsenetrc(&store, "curl.example.com", cr_in, arg, &cr_out);
|
||||
fail_unless(result == 0, "Host should have been found");
|
||||
abort_unless(password != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(password, "none", 4) == 0, "password should be 'none'");
|
||||
abort_unless(login != NULL, "returned NULL!");
|
||||
fail_unless(strncmp(login, "none", 4) == 0, "login should be 'none'");
|
||||
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_passwd(cr_out), "none", 4) == 0,
|
||||
"password should be 'none'");
|
||||
abort_unless(!t1304_no_user(cr_out), "returned NULL!");
|
||||
fail_unless(strncmp(Curl_creds_user(cr_out), "none", 4) == 0,
|
||||
"login should be 'none'");
|
||||
Curl_netrc_cleanup(&store);
|
||||
|
||||
UNITTEST_END(t1304_stop(&password, &login))
|
||||
UNITTEST_END(t1304_stop(&cr_in, &cr_out))
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue