mirror of
https://github.com/curl/curl.git
synced 2026-07-10 14:37:16 +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/CLIENT-WRITERS.md \
|
||||||
internals/CODE_STYLE.md \
|
internals/CODE_STYLE.md \
|
||||||
internals/CONNECTION-FILTERS.md \
|
internals/CONNECTION-FILTERS.md \
|
||||||
|
internals/CREDENTIALS.md \
|
||||||
internals/CURLX.md \
|
internals/CURLX.md \
|
||||||
internals/DYNBUF.md \
|
internals/DYNBUF.md \
|
||||||
internals/HASH.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 \
|
connect.c \
|
||||||
content_encoding.c \
|
content_encoding.c \
|
||||||
cookie.c \
|
cookie.c \
|
||||||
|
creds.c \
|
||||||
cshutdn.c \
|
cshutdn.c \
|
||||||
curl_addrinfo.c \
|
curl_addrinfo.c \
|
||||||
curl_endian.c \
|
curl_endian.c \
|
||||||
|
|
@ -293,6 +294,7 @@ LIB_HFILES = \
|
||||||
connect.h \
|
connect.h \
|
||||||
content_encoding.h \
|
content_encoding.h \
|
||||||
cookie.h \
|
cookie.h \
|
||||||
|
creds.h \
|
||||||
curl_addrinfo.h \
|
curl_addrinfo.h \
|
||||||
curl_ctype.h \
|
curl_ctype.h \
|
||||||
curl_endian.h \
|
curl_endian.h \
|
||||||
|
|
|
||||||
|
|
@ -387,8 +387,7 @@ connect_sub_chain:
|
||||||
result = Curl_cf_socks_proxy_insert_after(
|
result = Curl_cf_socks_proxy_insert_after(
|
||||||
cf, data, dest, cf->conn->ip_version,
|
cf, data, dest, cf->conn->ip_version,
|
||||||
cf->conn->socks_proxy.proxytype,
|
cf->conn->socks_proxy.proxytype,
|
||||||
cf->conn->socks_proxy.user,
|
cf->conn->socks_proxy.creds);
|
||||||
cf->conn->socks_proxy.passwd);
|
|
||||||
|
|
||||||
CURL_TRC_CF(data, cf, "added SOCKS filter to %s:%u -> %d",
|
CURL_TRC_CF(data, cf, "added SOCKS filter to %s:%u -> %d",
|
||||||
dest->hostname, dest->port, result);
|
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)
|
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
/* Have credentials been provided? */
|
/* Have credentials been provided? */
|
||||||
if(data->conn->user[0])
|
if(data->conn->creds)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* EXTERNAL can authenticate without a username and/or password */
|
/* 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)
|
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->mech = SASL_MECH_STRING_EXTERNAL;
|
||||||
sctx->state1 = SASL_EXTERNAL;
|
sctx->state1 = SASL_EXTERNAL;
|
||||||
sctx->sasl->authused = SASL_MECH_EXTERNAL;
|
sctx->sasl->authused = SASL_MECH_EXTERNAL;
|
||||||
|
|
||||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
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 TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
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) &&
|
if((sctx->enabledmechs & SASL_MECH_GSSAPI) &&
|
||||||
Curl_auth_is_gssapi_supported() &&
|
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] ?
|
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||||
data->set.str[STRING_SERVICE_NAME] :
|
data->set.str[STRING_SERVICE_NAME] :
|
||||||
sctx->sasl->params->service;
|
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) {
|
if(sctx->sasl->force_ir || data->set.sasl_ir) {
|
||||||
struct kerberos5data *krb5 = Curl_auth_krb5_get(sctx->conn);
|
struct kerberos5data *krb5 = Curl_auth_krb5_get(sctx->conn);
|
||||||
sctx->result = !krb5 ? CURLE_OUT_OF_MEMORY :
|
sctx->result = !krb5 ? CURLE_OUT_OF_MEMORY :
|
||||||
Curl_auth_create_gssapi_user_message(data, sctx->conn->user,
|
Curl_auth_create_gssapi_user_message(data, sctx->conn->creds,
|
||||||
sctx->conn->passwd,
|
|
||||||
service,
|
service,
|
||||||
sctx->conn->origin->hostname,
|
sctx->conn->origin->hostname,
|
||||||
(bool)sctx->sasl->mutual_auth,
|
(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);
|
Curl_bufref_init(&nullmsg);
|
||||||
sctx->state1 = SASL_GSASL;
|
sctx->state1 = SASL_GSASL;
|
||||||
sctx->state2 = SASL_GSASL;
|
sctx->state2 = SASL_GSASL;
|
||||||
sctx->result = Curl_auth_gsasl_start(data, sctx->conn->user,
|
sctx->result = Curl_auth_gsasl_start(data, sctx->conn->creds, gsasl);
|
||||||
sctx->conn->passwd, gsasl);
|
|
||||||
if(!sctx->result && (sctx->sasl->force_ir || data->set.sasl_ir))
|
if(!sctx->result && (sctx->sasl->force_ir || data->set.sasl_ir))
|
||||||
sctx->result = Curl_auth_gsasl_token(data, &nullmsg, gsasl, &sctx->resp);
|
sctx->result = Curl_auth_gsasl_token(data, &nullmsg, gsasl, &sctx->resp);
|
||||||
return TRUE;
|
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) {
|
if(sctx->sasl->force_ir || data->set.sasl_ir) {
|
||||||
struct ntlmdata *ntlm = Curl_auth_ntlm_get(sctx->conn, FALSE);
|
struct ntlmdata *ntlm = Curl_auth_ntlm_get(sctx->conn, FALSE);
|
||||||
sctx->result = !ntlm ? CURLE_OUT_OF_MEMORY :
|
sctx->result = !ntlm ? CURLE_OUT_OF_MEMORY :
|
||||||
Curl_auth_create_ntlm_type1_message(data,
|
Curl_auth_create_ntlm_type1_message(data, sctx->conn->creds,
|
||||||
sctx->conn->user,
|
|
||||||
sctx->conn->passwd,
|
|
||||||
service, hostname,
|
service, hostname,
|
||||||
ntlm, &sctx->resp);
|
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)
|
static bool sasl_choose_oauth(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||||
{
|
{
|
||||||
const char *oauth_bearer =
|
if(Curl_creds_has_oauth_bearer(data->state.creds) &&
|
||||||
(!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
|
(sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) {
|
||||||
data->set.str[STRING_BEARER] : NULL;
|
|
||||||
|
|
||||||
if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_OAUTHBEARER)) {
|
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
int port;
|
int port;
|
||||||
Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &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)
|
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||||
sctx->result =
|
sctx->result =
|
||||||
Curl_auth_create_oauth_bearer_message(sctx->conn->user,
|
Curl_auth_create_oauth_bearer_message(sctx->conn->creds,
|
||||||
hostname, port,
|
hostname, port, &sctx->resp);
|
||||||
oauth_bearer, &sctx->resp);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
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)
|
static bool sasl_choose_oauth2(struct Curl_easy *data, struct sasl_ctx *sctx)
|
||||||
{
|
{
|
||||||
const char *oauth_bearer =
|
if(Curl_creds_has_oauth_bearer(sctx->conn->creds) &&
|
||||||
(!data->state.this_is_a_follow || data->set.allow_auth_to_other_hosts) ?
|
(sctx->enabledmechs & SASL_MECH_XOAUTH2)) {
|
||||||
data->set.str[STRING_BEARER] : NULL;
|
|
||||||
|
|
||||||
if(oauth_bearer && (sctx->enabledmechs & SASL_MECH_XOAUTH2)) {
|
|
||||||
sctx->mech = SASL_MECH_STRING_XOAUTH2;
|
sctx->mech = SASL_MECH_STRING_XOAUTH2;
|
||||||
sctx->state1 = SASL_OAUTH2;
|
sctx->state1 = SASL_OAUTH2;
|
||||||
sctx->sasl->authused = SASL_MECH_XOAUTH2;
|
sctx->sasl->authused = SASL_MECH_XOAUTH2;
|
||||||
|
|
||||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||||
sctx->result = Curl_auth_create_xoauth_bearer_message(sctx->conn->user,
|
sctx->result = Curl_auth_create_xoauth_bearer_message(
|
||||||
oauth_bearer,
|
sctx->conn->creds, &sctx->resp);
|
||||||
&sctx->resp);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
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)
|
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
||||||
sctx->result =
|
sctx->result =
|
||||||
Curl_auth_create_plain_message(sctx->conn->sasl_authzid,
|
Curl_auth_create_plain_message(sctx->conn->creds, &sctx->resp);
|
||||||
sctx->conn->user, sctx->conn->passwd,
|
|
||||||
&sctx->resp);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
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;
|
sctx->sasl->authused = SASL_MECH_LOGIN;
|
||||||
|
|
||||||
if(sctx->sasl->force_ir || data->set.sasl_ir)
|
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 TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -606,7 +595,6 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
data->set.str[STRING_SERVICE_NAME] :
|
data->set.str[STRING_SERVICE_NAME] :
|
||||||
sasl->params->service;
|
sasl->params->service;
|
||||||
#endif
|
#endif
|
||||||
const char *oauth_bearer = data->set.str[STRING_BEARER];
|
|
||||||
struct bufref serverdata;
|
struct bufref serverdata;
|
||||||
|
|
||||||
Curl_conn_get_current_host(data, FIRSTSOCKET, &hostname, &port);
|
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;
|
*progress = SASL_DONE;
|
||||||
return result;
|
return result;
|
||||||
case SASL_PLAIN:
|
case SASL_PLAIN:
|
||||||
result = Curl_auth_create_plain_message(conn->sasl_authzid,
|
result = Curl_auth_create_plain_message(conn->creds, &resp);
|
||||||
conn->user, conn->passwd, &resp);
|
|
||||||
break;
|
break;
|
||||||
case SASL_LOGIN:
|
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;
|
newstate = SASL_LOGIN_PASSWD;
|
||||||
break;
|
break;
|
||||||
case SASL_LOGIN_PASSWD:
|
case SASL_LOGIN_PASSWD:
|
||||||
Curl_auth_create_login_message(conn->passwd, &resp);
|
Curl_auth_create_login_message(Curl_creds_passwd(conn->creds), &resp);
|
||||||
break;
|
break;
|
||||||
case SASL_EXTERNAL:
|
case SASL_EXTERNAL:
|
||||||
Curl_auth_create_external_message(conn->user, &resp);
|
Curl_auth_create_external_message(Curl_creds_user(conn->creds), &resp);
|
||||||
break;
|
break;
|
||||||
#ifdef USE_GSASL
|
#ifdef USE_GSASL
|
||||||
case SASL_GSASL:
|
case SASL_GSASL:
|
||||||
|
|
@ -663,15 +650,15 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
case SASL_CRAMMD5:
|
case SASL_CRAMMD5:
|
||||||
result = get_server_message(sasl, data, &serverdata);
|
result = get_server_message(sasl, data, &serverdata);
|
||||||
if(!result)
|
if(!result)
|
||||||
result = Curl_auth_create_cram_md5_message(&serverdata, conn->user,
|
result = Curl_auth_create_cram_md5_message(&serverdata, conn->creds,
|
||||||
conn->passwd, &resp);
|
&resp);
|
||||||
break;
|
break;
|
||||||
case SASL_DIGESTMD5:
|
case SASL_DIGESTMD5:
|
||||||
result = get_server_message(sasl, data, &serverdata);
|
result = get_server_message(sasl, data, &serverdata);
|
||||||
if(!result)
|
if(!result)
|
||||||
result = Curl_auth_create_digest_md5_message(data, &serverdata,
|
result = Curl_auth_create_digest_md5_message(data, &serverdata,
|
||||||
conn->user, conn->passwd,
|
conn->creds, service,
|
||||||
service, &resp);
|
&resp);
|
||||||
if(!result && (sasl->params->flags & SASL_FLAG_BASE64))
|
if(!result && (sasl->params->flags & SASL_FLAG_BASE64))
|
||||||
newstate = SASL_DIGESTMD5_RESP;
|
newstate = SASL_DIGESTMD5_RESP;
|
||||||
break;
|
break;
|
||||||
|
|
@ -685,8 +672,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
/* Create the type-1 message */
|
/* Create the type-1 message */
|
||||||
struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE);
|
struct ntlmdata *ntlm = Curl_auth_ntlm_get(conn, FALSE);
|
||||||
result = !ntlm ? CURLE_OUT_OF_MEMORY :
|
result = !ntlm ? CURLE_OUT_OF_MEMORY :
|
||||||
Curl_auth_create_ntlm_type1_message(data,
|
Curl_auth_create_ntlm_type1_message(data, conn->creds,
|
||||||
conn->user, conn->passwd,
|
|
||||||
service, hostname,
|
service, hostname,
|
||||||
ntlm, &resp);
|
ntlm, &resp);
|
||||||
newstate = SASL_NTLM_TYPE2MSG;
|
newstate = SASL_NTLM_TYPE2MSG;
|
||||||
|
|
@ -700,9 +686,8 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
if(!result)
|
if(!result)
|
||||||
result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, ntlm);
|
result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, ntlm);
|
||||||
if(!result)
|
if(!result)
|
||||||
result = Curl_auth_create_ntlm_type3_message(data, conn->user,
|
result = Curl_auth_create_ntlm_type3_message(data, conn->creds,
|
||||||
conn->passwd, ntlm,
|
ntlm, &resp);
|
||||||
&resp);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -711,7 +696,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
case SASL_GSSAPI: {
|
case SASL_GSSAPI: {
|
||||||
struct kerberos5data *krb5 = Curl_auth_krb5_get(conn);
|
struct kerberos5data *krb5 = Curl_auth_krb5_get(conn);
|
||||||
result = !krb5 ? CURLE_OUT_OF_MEMORY :
|
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,
|
service, conn->origin->hostname,
|
||||||
(bool)sasl->mutual_auth, NULL,
|
(bool)sasl->mutual_auth, NULL,
|
||||||
krb5, &resp);
|
krb5, &resp);
|
||||||
|
|
@ -727,7 +712,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
else if(sasl->mutual_auth) {
|
else if(sasl->mutual_auth) {
|
||||||
/* Decode the user token challenge and create the optional response
|
/* Decode the user token challenge and create the optional response
|
||||||
message */
|
message */
|
||||||
result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
|
result = Curl_auth_create_gssapi_user_message(data, NULL,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
(bool)sasl->mutual_auth,
|
(bool)sasl->mutual_auth,
|
||||||
&serverdata,
|
&serverdata,
|
||||||
|
|
@ -736,10 +721,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Decode the security challenge and create the response message */
|
/* Decode the security challenge and create the response message */
|
||||||
result = Curl_auth_create_gssapi_security_message(data,
|
result = Curl_auth_create_gssapi_security_message(
|
||||||
conn->sasl_authzid,
|
data, Curl_creds_sasl_authzid(conn->creds), &serverdata,
|
||||||
&serverdata,
|
krb5, &resp);
|
||||||
krb5, &resp);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SASL_GSSAPI_NO_DATA:
|
case SASL_GSSAPI_NO_DATA:
|
||||||
|
|
@ -750,10 +734,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
if(!krb5)
|
if(!krb5)
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
else
|
else
|
||||||
result = Curl_auth_create_gssapi_security_message(data,
|
result = Curl_auth_create_gssapi_security_message(
|
||||||
conn->sasl_authzid,
|
data, Curl_creds_sasl_authzid(conn->creds), &serverdata,
|
||||||
&serverdata,
|
krb5, &resp);
|
||||||
krb5, &resp);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -761,18 +744,16 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
case SASL_OAUTH2:
|
case SASL_OAUTH2:
|
||||||
/* Create the authorization message */
|
/* Create the authorization message */
|
||||||
if(sasl->authused == SASL_MECH_OAUTHBEARER) {
|
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,
|
hostname,
|
||||||
port,
|
port,
|
||||||
oauth_bearer,
|
|
||||||
&resp);
|
&resp);
|
||||||
|
|
||||||
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
|
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
|
||||||
newstate = SASL_OAUTH2_RESP;
|
newstate = SASL_OAUTH2_RESP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = Curl_auth_create_xoauth_bearer_message(conn->user,
|
result = Curl_auth_create_xoauth_bearer_message(conn->creds,
|
||||||
oauth_bearer,
|
|
||||||
&resp);
|
&resp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -862,7 +843,7 @@ static void sasl_unchosen(struct Curl_easy *data, unsigned short mech,
|
||||||
else {
|
else {
|
||||||
if(param_missing)
|
if(param_missing)
|
||||||
infof(data, "SASL: %s is missing %s", mname, 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);
|
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");
|
"auth mechanisms");
|
||||||
else {
|
else {
|
||||||
infof(data, "SASL: no auth mechanism offered could be selected");
|
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");
|
infof(data, "SASL: auth EXTERNAL not chosen with password");
|
||||||
sasl_unchosen(data, SASL_MECH_GSSAPI, enabledmechs,
|
sasl_unchosen(data, SASL_MECH_GSSAPI, enabledmechs,
|
||||||
CURL_SASL_KERBEROS5, Curl_auth_is_gssapi_supported(), NULL);
|
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,
|
sasl_unchosen(data, SASL_MECH_NTLM, enabledmechs,
|
||||||
CURL_SASL_NTLM, Curl_auth_is_ntlm_supported(), NULL);
|
CURL_SASL_NTLM, Curl_auth_is_ntlm_supported(), NULL);
|
||||||
sasl_unchosen(data, SASL_MECH_OAUTHBEARER, enabledmechs, TRUE, TRUE,
|
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");
|
NULL : "CURLOPT_XOAUTH2_BEARER");
|
||||||
sasl_unchosen(data, SASL_MECH_XOAUTH2, enabledmechs, TRUE, TRUE,
|
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");
|
NULL : "CURLOPT_XOAUTH2_BEARER");
|
||||||
}
|
}
|
||||||
#endif /* CURLVERBOSE */
|
#endif /* CURLVERBOSE */
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,7 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
|
||||||
struct connectdata *conn)
|
struct connectdata *conn)
|
||||||
{
|
{
|
||||||
CURLcode result = Curl_pp_sendf(data, &ftpc->pp, "USER %s",
|
CURLcode result = Curl_pp_sendf(data, &ftpc->pp, "USER %s",
|
||||||
conn->user ? conn->user : "");
|
Curl_creds_user(conn->creds));
|
||||||
if(!result) {
|
if(!result) {
|
||||||
ftpc->ftp_trying_alternative = FALSE;
|
ftpc->ftp_trying_alternative = FALSE;
|
||||||
ftp_state(data, ftpc, FTP_USER);
|
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)) {
|
if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
|
||||||
/* 331 Password required for ...
|
/* 331 Password required for ...
|
||||||
(the server requires to send the user's password too) */
|
(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)
|
if(!result)
|
||||||
ftp_state(data, ftpc, FTP_PASS);
|
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.
|
* 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;
|
size_t size = 0;
|
||||||
char *authorization = NULL;
|
char *authorization = NULL;
|
||||||
char **p_hd;
|
char **p_hd;
|
||||||
const char *user;
|
|
||||||
const char *pwd;
|
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
struct Curl_creds *creds = NULL;
|
||||||
char *out;
|
char *out;
|
||||||
|
|
||||||
/* credentials are unique per transfer for HTTP, do not use the ones for the
|
/* 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) {
|
if(proxy) {
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
p_hd = &data->req.hd_proxy_auth;
|
p_hd = &data->req.hd_proxy_auth;
|
||||||
user = data->state.aptr.proxyuser;
|
creds = conn->http_proxy.creds;
|
||||||
pwd = data->state.aptr.proxypasswd;
|
|
||||||
#else
|
#else
|
||||||
|
(void)conn;
|
||||||
return CURLE_NOT_BUILT_IN;
|
return CURLE_NOT_BUILT_IN;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p_hd = &data->req.hd_auth;
|
p_hd = &data->req.hd_auth;
|
||||||
user = data->state.aptr.user;
|
creds = data->state.creds;
|
||||||
pwd = data->state.aptr.passwd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
if(!out)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
|
@ -320,10 +324,11 @@ static CURLcode http_output_bearer(struct Curl_easy *data)
|
||||||
char **userp;
|
char **userp;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(Curl_creds_has_oauth_bearer(data->state.creds));
|
||||||
userp = &data->req.hd_auth;
|
userp = &data->req.hd_auth;
|
||||||
curlx_free(*userp);
|
curlx_free(*userp);
|
||||||
*userp = curl_maprintf("Authorization: Bearer %s\r\n",
|
*userp = curl_maprintf("Authorization: Bearer %s\r\n",
|
||||||
data->set.str[STRING_BEARER]);
|
Curl_creds_oauth_bearer(data->state.creds));
|
||||||
|
|
||||||
if(!*userp) {
|
if(!*userp) {
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
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
|
* Either we are not authenticating, or we are supposed to be authenticating
|
||||||
* something else. This is an error.
|
* something else. This is an error.
|
||||||
*/
|
*/
|
||||||
if((httpcode == 401) && !data->state.aptr.user)
|
if((httpcode == 401) && !data->state.creds)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
if((httpcode == 407) && !data->conn->bits.proxy_user_passwd)
|
if((httpcode == 407) && !data->conn->http_proxy.creds)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -551,7 +556,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
unsigned long authmask = ~0UL;
|
unsigned long authmask = ~0UL;
|
||||||
|
|
||||||
if(!data->set.str[STRING_BEARER])
|
if(!Curl_creds_has_oauth_bearer(data->state.creds))
|
||||||
authmask &= (unsigned long)~CURLAUTH_BEARER;
|
authmask &= (unsigned long)~CURLAUTH_BEARER;
|
||||||
|
|
||||||
if(100 <= data->req.httpcode && data->req.httpcode <= 199)
|
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)
|
if(data->state.authproblem)
|
||||||
return data->set.http_fail_on_error ? CURLE_HTTP_RETURNED_ERROR : CURLE_OK;
|
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.httpcode == 401) ||
|
||||||
(data->req.authneg && data->req.httpcode < 300))) {
|
(data->req.authneg && data->req.httpcode < 300))) {
|
||||||
pickhost = pickoneauth(&data->state.authhost, authmask);
|
pickhost = pickoneauth(&data->state.authhost, authmask);
|
||||||
|
|
@ -578,7 +583,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
if(conn->bits.proxy_user_passwd &&
|
if(conn->http_proxy.creds &&
|
||||||
((data->req.httpcode == 407) ||
|
((data->req.httpcode == 407) ||
|
||||||
(data->req.authneg && data->req.httpcode < 300))) {
|
(data->req.authneg && data->req.httpcode < 300))) {
|
||||||
pickproxy = pickoneauth(&data->state.authproxy,
|
pickproxy = pickoneauth(&data->state.authproxy,
|
||||||
|
|
@ -694,14 +699,14 @@ static CURLcode output_auth_headers(struct Curl_easy *data,
|
||||||
/* Basic */
|
/* Basic */
|
||||||
if(
|
if(
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
(proxy && conn->bits.proxy_user_passwd &&
|
(proxy && conn->http_proxy.creds &&
|
||||||
!Curl_checkProxyheaders(data, conn,
|
!Curl_checkProxyheaders(data, conn,
|
||||||
STRCONST("Proxy-authorization"))) ||
|
STRCONST("Proxy-authorization"))) ||
|
||||||
#endif
|
#endif
|
||||||
(!proxy && data->state.aptr.user &&
|
(!proxy && data->state.creds &&
|
||||||
!Curl_checkheaders(data, STRCONST("Authorization")))) {
|
!Curl_checkheaders(data, STRCONST("Authorization")))) {
|
||||||
auth = "Basic";
|
auth = "Basic";
|
||||||
result = http_output_basic(data, proxy);
|
result = http_output_basic(data, conn, proxy);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -714,8 +719,7 @@ static CURLcode output_auth_headers(struct Curl_easy *data,
|
||||||
#ifndef CURL_DISABLE_BEARER_AUTH
|
#ifndef CURL_DISABLE_BEARER_AUTH
|
||||||
if(authstatus->picked == CURLAUTH_BEARER) {
|
if(authstatus->picked == CURLAUTH_BEARER) {
|
||||||
/* Bearer */
|
/* Bearer */
|
||||||
if(!proxy && data->set.str[STRING_BEARER] &&
|
if(!proxy && Curl_creds_has_oauth_bearer(data->state.creds) &&
|
||||||
Curl_auth_allowed_to_host(data) &&
|
|
||||||
!Curl_checkheaders(data, STRCONST("Authorization"))) {
|
!Curl_checkheaders(data, STRCONST("Authorization"))) {
|
||||||
auth = "Bearer";
|
auth = "Bearer";
|
||||||
result = http_output_bearer(data);
|
result = http_output_bearer(data);
|
||||||
|
|
@ -737,15 +741,15 @@ static CURLcode output_auth_headers(struct Curl_easy *data,
|
||||||
data->info.httpauthpicked = authstatus->picked;
|
data->info.httpauthpicked = authstatus->picked;
|
||||||
infof(data, "%s auth using %s with user '%s'",
|
infof(data, "%s auth using %s with user '%s'",
|
||||||
proxy ? "Proxy" : "Server", auth,
|
proxy ? "Proxy" : "Server", auth,
|
||||||
proxy ? (data->state.aptr.proxyuser ?
|
proxy ? (conn->http_proxy.creds ?
|
||||||
data->state.aptr.proxyuser : "") :
|
conn->http_proxy.creds->user : "") :
|
||||||
(data->state.aptr.user ?
|
(data->state.creds ?
|
||||||
data->state.aptr.user : ""));
|
data->state.creds->user : ""));
|
||||||
#else
|
#else
|
||||||
(void)proxy;
|
(void)proxy;
|
||||||
infof(data, "Server auth using %s with user '%s'",
|
infof(data, "Server auth using %s with user '%s'",
|
||||||
auth, data->state.aptr.user ?
|
auth, data->state.creds ?
|
||||||
data->state.aptr.user : "");
|
data->state.creds->user : "");
|
||||||
#endif
|
#endif
|
||||||
authstatus->multipass = !authstatus->done;
|
authstatus->multipass = !authstatus->done;
|
||||||
}
|
}
|
||||||
|
|
@ -780,14 +784,13 @@ CURLcode Curl_http_output_auth(struct Curl_easy *data,
|
||||||
|
|
||||||
if(
|
if(
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
(!conn->bits.httpproxy || !conn->bits.proxy_user_passwd) &&
|
(!conn->bits.httpproxy || !conn->http_proxy.creds) &&
|
||||||
#endif
|
#endif
|
||||||
!data->state.aptr.user &&
|
|
||||||
#ifdef USE_SPNEGO
|
#ifdef USE_SPNEGO
|
||||||
!(authhost->want & CURLAUTH_NEGOTIATE) &&
|
!(authhost->want & CURLAUTH_NEGOTIATE) &&
|
||||||
!(authproxy->want & CURLAUTH_NEGOTIATE) &&
|
!(authproxy->want & CURLAUTH_NEGOTIATE) &&
|
||||||
#endif
|
#endif
|
||||||
!data->set.str[STRING_BEARER]) {
|
!data->state.creds) {
|
||||||
/* no authentication with no user or password */
|
/* no authentication with no user or password */
|
||||||
authhost->done = TRUE;
|
authhost->done = TRUE;
|
||||||
authproxy->done = TRUE;
|
authproxy->done = TRUE;
|
||||||
|
|
@ -832,13 +835,9 @@ CURLcode Curl_http_output_auth(struct Curl_easy *data,
|
||||||
with it */
|
with it */
|
||||||
authproxy->done = TRUE;
|
authproxy->done = TRUE;
|
||||||
|
|
||||||
/* To prevent the user+password to get sent to other than the original host
|
/* Either we have credentials for the origin we talk to or
|
||||||
due to a location-follow */
|
performing authentication is allowed here */
|
||||||
if(Curl_auth_allowed_to_host(data)
|
if(data->state.creds || Curl_auth_allowed_to_host(data))
|
||||||
#ifndef CURL_DISABLE_NETRC
|
|
||||||
|| conn->bits.netrc
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
result = output_auth_headers(data, conn, authhost, request,
|
result = output_auth_headers(data, conn, authhost, request,
|
||||||
path_and_query, FALSE);
|
path_and_query, FALSE);
|
||||||
else
|
else
|
||||||
|
|
@ -1227,8 +1226,6 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bool same_origin;
|
|
||||||
CURLcode result;
|
|
||||||
CURLU *u = curl_url();
|
CURLU *u = curl_url();
|
||||||
if(!u)
|
if(!u)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
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);
|
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
|
#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
|
#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);
|
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;
|
struct dynamically_allocated_data *aptr = &data->state.aptr;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
|
|
||||||
if(!data->state.this_is_a_follow)
|
|
||||||
Curl_peer_link(&data->state.first_origin, conn->origin);
|
|
||||||
|
|
||||||
curlx_safefree(aptr->host);
|
curlx_safefree(aptr->host);
|
||||||
#ifndef CURL_DISABLE_COOKIES
|
#ifndef CURL_DISABLE_COOKIES
|
||||||
curlx_safefree(data->req.cookiehost);
|
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"));
|
ptr = Curl_checkheaders(data, STRCONST("Host"));
|
||||||
if(ptr && (!data->state.this_is_a_follow ||
|
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
|
#ifndef CURL_DISABLE_COOKIES
|
||||||
/* If we have a given custom Host: header, we extract the hostname in
|
/* 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
|
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;
|
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. */
|
/* Extract the URL to use in the request. */
|
||||||
uc = curl_url_get(h, CURLUPART_URL, &url, CURLU_NO_DEFAULT_PORT);
|
uc = curl_url_get(h, CURLUPART_URL, &url, CURLU_NO_DEFAULT_PORT);
|
||||||
if(uc) {
|
if(uc) {
|
||||||
|
|
|
||||||
|
|
@ -848,7 +848,8 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data)
|
||||||
char *request_type = NULL;
|
char *request_type = NULL;
|
||||||
char *credential_scope = NULL;
|
char *credential_scope = NULL;
|
||||||
char *str_to_sign = 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;
|
char *secret = NULL;
|
||||||
unsigned char sign0[CURL_SHA256_DIGEST_LENGTH] = { 0 };
|
unsigned char sign0[CURL_SHA256_DIGEST_LENGTH] = { 0 };
|
||||||
unsigned char sign1[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);
|
str_to_sign);
|
||||||
|
|
||||||
secret = curl_maprintf("%.*s4%s", (int)curlx_strlen(&provider0),
|
secret = curl_maprintf("%.*s4%s", (int)curlx_strlen(&provider0),
|
||||||
curlx_str(&provider0), data->state.aptr.passwd ?
|
curlx_str(&provider0), passwd);
|
||||||
data->state.aptr.passwd : "");
|
|
||||||
if(!secret)
|
if(!secret)
|
||||||
goto fail;
|
goto fail;
|
||||||
/* make provider0 part done uppercase */
|
/* make provider0 part done uppercase */
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,7 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
||||||
char **allocuserpwd;
|
char **allocuserpwd;
|
||||||
|
|
||||||
/* Point to the name and password for this */
|
/* Point to the name and password for this */
|
||||||
const char *userp;
|
struct Curl_creds *creds = NULL;
|
||||||
const char *passwdp;
|
|
||||||
|
|
||||||
/* Point to the correct struct with this */
|
/* Point to the correct struct with this */
|
||||||
struct digestdata *digest;
|
struct digestdata *digest;
|
||||||
|
|
@ -90,28 +89,19 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
||||||
#else
|
#else
|
||||||
digest = &data->state.proxydigest;
|
digest = &data->state.proxydigest;
|
||||||
allocuserpwd = &data->req.hd_proxy_auth;
|
allocuserpwd = &data->req.hd_proxy_auth;
|
||||||
userp = data->state.aptr.proxyuser;
|
creds = data->conn->http_proxy.creds;
|
||||||
passwdp = data->state.aptr.proxypasswd;
|
|
||||||
authp = &data->state.authproxy;
|
authp = &data->state.authproxy;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
digest = &data->state.digest;
|
digest = &data->state.digest;
|
||||||
allocuserpwd = &data->req.hd_auth;
|
allocuserpwd = &data->req.hd_auth;
|
||||||
userp = data->state.aptr.user;
|
creds = data->state.creds;
|
||||||
passwdp = data->state.aptr.passwd;
|
|
||||||
authp = &data->state.authhost;
|
authp = &data->state.authhost;
|
||||||
}
|
}
|
||||||
|
|
||||||
curlx_safefree(*allocuserpwd);
|
curlx_safefree(*allocuserpwd);
|
||||||
|
|
||||||
/* not set means empty */
|
|
||||||
if(!userp)
|
|
||||||
userp = "";
|
|
||||||
|
|
||||||
if(!passwdp)
|
|
||||||
passwdp = "";
|
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
have_chlg = !!digest->input_token;
|
have_chlg = !!digest->input_token;
|
||||||
#else
|
#else
|
||||||
|
|
@ -123,8 +113,8 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_auth_create_digest_http_message(data, userp, passwdp,
|
result = Curl_auth_create_digest_http_message(data, creds, request,
|
||||||
request, uripath, digest,
|
uripath, digest,
|
||||||
&response, &len);
|
&response, &len);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,10 @@ static void http_auth_nego_reset(struct connectdata *conn,
|
||||||
{
|
{
|
||||||
if(proxy)
|
if(proxy)
|
||||||
conn->proxy_negotiate_state = GSS_AUTHNONE;
|
conn->proxy_negotiate_state = GSS_AUTHNONE;
|
||||||
else
|
else {
|
||||||
conn->http_negotiate_state = GSS_AUTHNONE;
|
conn->http_negotiate_state = GSS_AUTHNONE;
|
||||||
|
Curl_creds_unlink(&conn->creds);
|
||||||
|
}
|
||||||
if(neg_ctx)
|
if(neg_ctx)
|
||||||
Curl_auth_cleanup_spnego(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;
|
size_t len;
|
||||||
|
|
||||||
/* Point to the username, password, service and host */
|
/* Point to the username, password, service and host */
|
||||||
const char *userp;
|
struct Curl_creds *creds = NULL;
|
||||||
const char *passwdp;
|
|
||||||
const char *service;
|
const char *service;
|
||||||
const char *host;
|
const char *host;
|
||||||
|
|
||||||
|
|
@ -64,8 +65,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
||||||
|
|
||||||
if(proxy) {
|
if(proxy) {
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
userp = conn->http_proxy.user;
|
creds = conn->http_proxy.creds;
|
||||||
passwdp = conn->http_proxy.passwd;
|
|
||||||
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||||
host = conn->http_proxy.peer->hostname;
|
host = conn->http_proxy.peer->hostname;
|
||||||
|
|
@ -75,8 +75,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
userp = conn->user;
|
creds = data->state.creds;
|
||||||
passwdp = conn->passwd;
|
|
||||||
service = data->set.str[STRING_SERVICE_NAME] ?
|
service = data->set.str[STRING_SERVICE_NAME] ?
|
||||||
data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
||||||
host = conn->origin->hostname;
|
host = conn->origin->hostname;
|
||||||
|
|
@ -87,13 +86,6 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
||||||
if(!neg_ctx)
|
if(!neg_ctx)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Not set means empty */
|
|
||||||
if(!userp)
|
|
||||||
userp = "";
|
|
||||||
|
|
||||||
if(!passwdp)
|
|
||||||
passwdp = "";
|
|
||||||
|
|
||||||
/* Obtain the input token, if any */
|
/* Obtain the input token, if any */
|
||||||
header += strlen("Negotiate");
|
header += strlen("Negotiate");
|
||||||
curlx_str_passblanks(&header);
|
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 */
|
#endif /* GSS_C_CHANNEL_BOUND_FLAG */
|
||||||
|
|
||||||
/* Initialize the security context and decode our challenge */
|
/* 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);
|
host, header, neg_ctx);
|
||||||
|
|
||||||
#ifdef GSS_C_CHANNEL_BOUND_FLAG
|
#ifdef GSS_C_CHANNEL_BOUND_FLAG
|
||||||
|
|
@ -145,6 +137,16 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
|
||||||
if(result)
|
if(result)
|
||||||
http_auth_nego_reset(conn, neg_ctx, proxy);
|
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;
|
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 */
|
server, which is for a plain host or for an HTTP proxy */
|
||||||
char **allocuserpwd;
|
char **allocuserpwd;
|
||||||
|
|
||||||
/* point to the username, password, service and host */
|
/* point to credentials, service and host */
|
||||||
const char *userp;
|
struct Curl_creds *creds = NULL;
|
||||||
const char *passwdp;
|
|
||||||
const char *service = NULL;
|
const char *service = NULL;
|
||||||
const char *hostname = NULL;
|
const char *hostname = NULL;
|
||||||
|
|
||||||
|
|
@ -140,8 +139,7 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
||||||
if(proxy) {
|
if(proxy) {
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
allocuserpwd = &data->req.hd_proxy_auth;
|
allocuserpwd = &data->req.hd_proxy_auth;
|
||||||
userp = data->state.aptr.proxyuser;
|
creds = conn->http_proxy.creds;
|
||||||
passwdp = data->state.aptr.proxypasswd;
|
|
||||||
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||||
hostname = conn->http_proxy.peer->hostname;
|
hostname = conn->http_proxy.peer->hostname;
|
||||||
|
|
@ -153,26 +151,19 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
allocuserpwd = &data->req.hd_auth;
|
allocuserpwd = &data->req.hd_auth;
|
||||||
userp = data->state.aptr.user;
|
creds = data->state.creds;
|
||||||
passwdp = data->state.aptr.passwd;
|
|
||||||
service = data->set.str[STRING_SERVICE_NAME] ?
|
service = data->set.str[STRING_SERVICE_NAME] ?
|
||||||
data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
||||||
hostname = conn->origin->hostname;
|
hostname = conn->origin->hostname;
|
||||||
state = &conn->http_ntlm_state;
|
state = &conn->http_ntlm_state;
|
||||||
authp = &data->state.authhost;
|
authp = &data->state.authhost;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntlm = Curl_auth_ntlm_get(conn, proxy);
|
ntlm = Curl_auth_ntlm_get(conn, proxy);
|
||||||
if(!ntlm)
|
if(!ntlm)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
authp->done = FALSE;
|
authp->done = FALSE;
|
||||||
|
|
||||||
/* not set means empty */
|
|
||||||
if(!userp)
|
|
||||||
userp = "";
|
|
||||||
|
|
||||||
if(!passwdp)
|
|
||||||
passwdp = "";
|
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
if(!Curl_pSecFn) {
|
if(!Curl_pSecFn) {
|
||||||
/* not thread-safe and leaks - use curl_global_init() to avoid */
|
/* 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) {
|
switch(*state) {
|
||||||
case NTLMSTATE_TYPE1:
|
case NTLMSTATE_TYPE1:
|
||||||
default: /* for the weird cases we (re)start here */
|
default: /* for the weird cases we (re)start here */
|
||||||
/* Create a type-1 message */
|
if(!proxy) {
|
||||||
result = Curl_auth_create_ntlm_type1_message(data, userp, passwdp, service,
|
/* 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);
|
hostname, ntlm, &ntlmmsg);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0);
|
DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0);
|
||||||
|
|
@ -215,8 +214,7 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
||||||
|
|
||||||
case NTLMSTATE_TYPE2:
|
case NTLMSTATE_TYPE2:
|
||||||
/* We already received the type-2 message, create a type-3 message */
|
/* We already received the type-2 message, create a type-3 message */
|
||||||
result = Curl_auth_create_ntlm_type3_message(data, userp, passwdp,
|
result = Curl_auth_create_ntlm_type3_message(data, creds, ntlm, &ntlmmsg);
|
||||||
ntlm, &ntlmmsg);
|
|
||||||
if(!result && Curl_bufref_len(&ntlmmsg)) {
|
if(!result && Curl_bufref_len(&ntlmmsg)) {
|
||||||
result = curlx_base64_encode(Curl_bufref_uptr(&ntlmmsg),
|
result = curlx_base64_encode(Curl_bufref_uptr(&ntlmmsg),
|
||||||
Curl_bufref_len(&ntlmmsg), &base64, &len);
|
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
|
/* Check we have a username and password to authenticate with and end the
|
||||||
connect phase if we do not */
|
connect phase if we do not */
|
||||||
if(!data->state.aptr.user) {
|
if(!data->state.creds) {
|
||||||
imap_state(data, imapc, IMAP_STOP);
|
imap_state(data, imapc, IMAP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the username and password are in the correct atom format */
|
/* Make sure the username and password are in the correct atom format */
|
||||||
user = imap_atom(conn->user, FALSE);
|
user = imap_atom(Curl_creds_user(conn->creds), FALSE);
|
||||||
passwd = imap_atom(conn->passwd, FALSE);
|
passwd = imap_atom(Curl_creds_passwd(conn->creds), FALSE);
|
||||||
|
|
||||||
/* Send the LOGIN command */
|
/* Send the LOGIN command */
|
||||||
result = imap_sendf(data, imapc, "LOGIN %s %s", user ? user : "",
|
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 */
|
/* Calculate the SASL login details */
|
||||||
result = Curl_sasl_start(&imapc->sasl, data, (bool)imapc->ir_supported,
|
result = Curl_sasl_start(&imapc->sasl, data, (bool)imapc->ir_supported,
|
||||||
&progress);
|
&progress);
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
if(progress == SASL_INPROGRESS)
|
if(progress == SASL_INPROGRESS)
|
||||||
imap_state(data, imapc, IMAP_AUTHENTICATE);
|
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
|
#else
|
||||||
char *host = NULL;
|
char *host = NULL;
|
||||||
#endif
|
#endif
|
||||||
char *user = NULL;
|
const char *user = Curl_creds_has_user(data->state.creds) ?
|
||||||
char *passwd = NULL;
|
data->state.creds->user : NULL;
|
||||||
|
const char *passwd = Curl_creds_has_passwd(data->state.creds) ?
|
||||||
|
data->state.creds->passwd : NULL;
|
||||||
struct ip_quadruple ipquad;
|
struct ip_quadruple ipquad;
|
||||||
bool is_ipv6;
|
bool is_ipv6;
|
||||||
BerElement *ber = NULL;
|
BerElement *ber = NULL;
|
||||||
|
|
@ -295,11 +297,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
|
||||||
host = conn->origin->hostname;
|
host = conn->origin->hostname;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(data->state.aptr.user) {
|
|
||||||
user = conn->user;
|
|
||||||
passwd = conn->passwd;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_WIN32_LDAP
|
#ifdef USE_WIN32_LDAP
|
||||||
if(ldap_ssl)
|
if(ldap_ssl)
|
||||||
server = ldap_sslinit(host, (curl_ldap_num_t)ipquad.remote_port, 1);
|
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;
|
char *packet = NULL;
|
||||||
|
|
||||||
/* extracting username from request */
|
/* extracting username from request */
|
||||||
const char *username = data->state.aptr.user ? data->state.aptr.user : "";
|
struct Curl_creds *creds = data->state.creds;
|
||||||
const size_t ulen = strlen(username);
|
const size_t ulen = creds ? strlen(creds->user) : 0;
|
||||||
/* extracting password from request */
|
const size_t plen = creds ? strlen(creds->passwd) : 0;
|
||||||
const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : "";
|
|
||||||
const size_t plen = strlen(passwd);
|
|
||||||
const size_t payloadlen = ulen + plen + MQTT_CLIENTID_LEN + 2 +
|
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
|
/* 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 */
|
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) {
|
if(ulen) {
|
||||||
start_pwd += 2;
|
start_pwd += 2;
|
||||||
|
|
||||||
rc = add_user(username, ulen,
|
rc = add_user(creds->user, ulen,
|
||||||
(unsigned char *)packet, start_user, remain_pos);
|
(unsigned char *)packet, start_user, remain_pos);
|
||||||
if(rc) {
|
if(rc) {
|
||||||
failf(data, "Username too long: [%zu]", ulen);
|
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 passwd was provided, add it to the packet */
|
||||||
if(plen) {
|
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) {
|
if(rc) {
|
||||||
failf(data, "Password too long: [%zu]", plen);
|
failf(data, "Password too long: [%zu]", plen);
|
||||||
result = CURLE_WEIRD_SERVER_REPLY;
|
result = CURLE_WEIRD_SERVER_REPLY;
|
||||||
|
|
@ -351,8 +349,7 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
|
||||||
end:
|
end:
|
||||||
if(packet)
|
if(packet)
|
||||||
curlx_free(packet);
|
curlx_free(packet);
|
||||||
curlx_safefree(data->state.aptr.user);
|
Curl_creds_unlink(&data->state.creds);
|
||||||
curlx_safefree(data->state.aptr.passwd);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
95
lib/netrc.c
95
lib/netrc.c
|
|
@ -36,6 +36,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "netrc.h"
|
#include "netrc.h"
|
||||||
|
#include "creds.h"
|
||||||
#include "strcase.h"
|
#include "strcase.h"
|
||||||
#include "curl_get_line.h"
|
#include "curl_get_line.h"
|
||||||
#include "curlx/fopen.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 */
|
/* bundled parser state to keep function signatures compact */
|
||||||
struct netrc_state {
|
struct netrc_state {
|
||||||
|
struct Curl_creds *existing;
|
||||||
char *login;
|
char *login;
|
||||||
char *password;
|
char *password;
|
||||||
enum host_lookup_state state;
|
enum host_lookup_state state;
|
||||||
|
|
@ -116,7 +118,6 @@ struct netrc_state {
|
||||||
unsigned char found; /* FOUND_LOGIN | FOUND_PASSWORD bits */
|
unsigned char found; /* FOUND_LOGIN | FOUND_PASSWORD bits */
|
||||||
bool our_login;
|
bool our_login;
|
||||||
bool done;
|
bool done;
|
||||||
bool specific_login;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -250,8 +251,7 @@ static void netrc_new_machine(struct netrc_state *ns)
|
||||||
ns->found = 0;
|
ns->found = 0;
|
||||||
ns->our_login = FALSE;
|
ns->our_login = FALSE;
|
||||||
curlx_safefree(ns->password);
|
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)
|
static NETRCcode netrc_hostvalid(struct netrc_state *ns, const char *tok)
|
||||||
{
|
{
|
||||||
if(ns->keyword == LOGIN) {
|
if(ns->keyword == LOGIN) {
|
||||||
if(ns->specific_login)
|
if(Curl_creds_has_user(ns->existing))
|
||||||
ns->our_login = !Curl_timestrcmp(ns->login, tok);
|
ns->our_login = !Curl_timestrcmp(ns->existing->user, tok);
|
||||||
else {
|
else {
|
||||||
ns->our_login = TRUE;
|
ns->our_login = TRUE;
|
||||||
curlx_free(ns->login);
|
curlx_free(ns->login);
|
||||||
|
|
@ -289,15 +289,15 @@ static NETRCcode netrc_hostvalid(struct netrc_state *ns, const char *tok)
|
||||||
ns->keyword = PASSWORD;
|
ns->keyword = PASSWORD;
|
||||||
else if(curl_strequal("machine", tok)) {
|
else if(curl_strequal("machine", tok)) {
|
||||||
/* a new machine here */
|
/* 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 */
|
/* a password was provided for this host */
|
||||||
|
(!specific_login || ns->our_login ||
|
||||||
((!ns->specific_login || ns->our_login) ||
|
/* and found a login that is suitable
|
||||||
/* either there was no specific login to search for, or this
|
(either matched specific one or simply present) */
|
||||||
is the specific one we wanted */
|
(specific_login && !(ns->found & FOUND_LOGIN)))) {
|
||||||
(ns->specific_login && !(ns->found & FOUND_LOGIN)))) {
|
/* or we look for a specific login, but no login was not specified */
|
||||||
/* or we look for a specific login, but that was not specified */
|
|
||||||
|
|
||||||
ns->done = TRUE;
|
ns->done = TRUE;
|
||||||
return NETRC_OK;
|
return NETRC_OK;
|
||||||
|
|
@ -361,38 +361,48 @@ static NETRCcode netrc_handle_token(struct netrc_state *ns,
|
||||||
* resources on error.
|
* resources on error.
|
||||||
*/
|
*/
|
||||||
static NETRCcode netrc_finalize(struct netrc_state *ns,
|
static NETRCcode netrc_finalize(struct netrc_state *ns,
|
||||||
char **loginp,
|
struct store_netrc *store,
|
||||||
char **passwordp,
|
struct Curl_creds **pcreds)
|
||||||
struct store_netrc *store)
|
|
||||||
{
|
{
|
||||||
NETRCcode retcode = ns->retcode;
|
NETRCcode retcode = ns->retcode;
|
||||||
if(!retcode) {
|
if(!retcode) {
|
||||||
if(!ns->password && ns->our_login) {
|
if(!ns->password && ns->our_login) {
|
||||||
/* success without a password, set a blank one */
|
/* success without a password, set a blank one */
|
||||||
ns->password = curlx_strdup("");
|
ns->password = curlx_strdup("");
|
||||||
if(!ns->password)
|
if(!ns->password) {
|
||||||
retcode = NETRC_OUT_OF_MEMORY;
|
retcode = NETRC_OUT_OF_MEMORY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(!ns->login && !ns->password)
|
else if(!ns->login && !ns->password) {
|
||||||
/* a default with no credentials */
|
/* a default with no credentials */
|
||||||
retcode = NETRC_NO_MATCH;
|
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
|
but our_login is false (e.g., host matched but the requested login
|
||||||
never matched). See test 685. */
|
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);
|
curlx_dyn_free(&store->filebuf);
|
||||||
store->loaded = FALSE;
|
store->loaded = FALSE;
|
||||||
if(!ns->specific_login)
|
|
||||||
curlx_free(ns->login);
|
|
||||||
curlx_free(ns->password);
|
|
||||||
}
|
}
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
@ -402,21 +412,20 @@ static NETRCcode netrc_finalize(struct netrc_state *ns,
|
||||||
*/
|
*/
|
||||||
static NETRCcode parsenetrc(struct store_netrc *store,
|
static NETRCcode parsenetrc(struct store_netrc *store,
|
||||||
const char *host,
|
const char *host,
|
||||||
char **loginp,
|
struct Curl_creds *existing,
|
||||||
char **passwordp,
|
const char *netrcfile,
|
||||||
const char *netrcfile)
|
struct Curl_creds **pcreds)
|
||||||
{
|
{
|
||||||
const char *netrcbuffer;
|
const char *netrcbuffer;
|
||||||
struct dynbuf token;
|
struct dynbuf token;
|
||||||
struct dynbuf *filebuf = &store->filebuf;
|
struct dynbuf *filebuf = &store->filebuf;
|
||||||
struct netrc_state ns;
|
struct netrc_state ns;
|
||||||
|
|
||||||
|
DEBUGASSERT(!existing || !Curl_creds_has_passwd(existing));
|
||||||
memset(&ns, 0, sizeof(ns));
|
memset(&ns, 0, sizeof(ns));
|
||||||
ns.retcode = NETRC_NO_MATCH;
|
ns.retcode = NETRC_NO_MATCH;
|
||||||
ns.login = *loginp;
|
ns.existing = existing;
|
||||||
ns.specific_login = !!ns.login;
|
|
||||||
|
|
||||||
DEBUGASSERT(!*passwordp);
|
|
||||||
curlx_dyn_init(&token, MAX_NETRC_TOKEN);
|
curlx_dyn_init(&token, MAX_NETRC_TOKEN);
|
||||||
|
|
||||||
if(!store->loaded) {
|
if(!store->loaded) {
|
||||||
|
|
@ -466,7 +475,7 @@ static NETRCcode parsenetrc(struct store_netrc *store,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
curlx_dyn_free(&token);
|
curlx_dyn_free(&token);
|
||||||
return netrc_finalize(&ns, loginp, passwordp, store);
|
return netrc_finalize(&ns, store, pcreds);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Curl_netrc_strerror(NETRCcode ret)
|
const char *Curl_netrc_strerror(NETRCcode ret)
|
||||||
|
|
@ -493,12 +502,14 @@ const char *Curl_netrc_strerror(NETRCcode ret)
|
||||||
* in.
|
* in.
|
||||||
*/
|
*/
|
||||||
NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
||||||
char **loginp, char **passwordp,
|
struct Curl_creds *existing,
|
||||||
const char *netrcfile)
|
const char *netrcfile,
|
||||||
|
struct Curl_creds **pcreds)
|
||||||
{
|
{
|
||||||
NETRCcode retcode = NETRC_OK;
|
NETRCcode retcode = NETRC_OK;
|
||||||
char *filealloc = NULL;
|
char *filealloc = NULL;
|
||||||
|
|
||||||
|
Curl_creds_unlink(pcreds);
|
||||||
if(!netrcfile) {
|
if(!netrcfile) {
|
||||||
char *home = NULL;
|
char *home = NULL;
|
||||||
char *homea = 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);
|
filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR);
|
||||||
if(!filealloc) {
|
if(!filealloc) {
|
||||||
curlx_free(homea);
|
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);
|
curlx_free(filealloc);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if(retcode == NETRC_FILE_MISSING) {
|
if(retcode == NETRC_FILE_MISSING) {
|
||||||
|
|
@ -556,14 +568,17 @@ NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
||||||
curlx_free(homea);
|
curlx_free(homea);
|
||||||
return NETRC_OUT_OF_MEMORY;
|
return NETRC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
|
retcode = parsenetrc(store, host, existing, filealloc, pcreds);
|
||||||
curlx_free(filealloc);
|
curlx_free(filealloc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
curlx_free(homea);
|
curlx_free(homea);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
retcode = parsenetrc(store, host, loginp, passwordp, netrcfile);
|
retcode = parsenetrc(store, host, existing, netrcfile, pcreds);
|
||||||
|
out:
|
||||||
|
if(retcode)
|
||||||
|
Curl_creds_unlink(pcreds);
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include "curlx/dynbuf.h"
|
#include "curlx/dynbuf.h"
|
||||||
|
|
||||||
|
struct Curl_creds;
|
||||||
|
|
||||||
struct store_netrc {
|
struct store_netrc {
|
||||||
struct dynbuf filebuf;
|
struct dynbuf filebuf;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
@ -49,8 +51,9 @@ void Curl_netrc_init(struct store_netrc *store);
|
||||||
void Curl_netrc_cleanup(struct store_netrc *store);
|
void Curl_netrc_cleanup(struct store_netrc *store);
|
||||||
|
|
||||||
NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
|
||||||
char **loginp, char **passwordp,
|
struct Curl_creds *existing,
|
||||||
const char *netrcfile);
|
const char *netrcfile,
|
||||||
|
struct Curl_creds **pcreds);
|
||||||
/* Assume: (*passwordp)[0]=0, host[0] != 0.
|
/* Assume: (*passwordp)[0]=0, host[0] != 0.
|
||||||
* If (*loginp)[0] = 0, search for login and password within a machine
|
* If (*loginp)[0] = 0, search for login and password within a machine
|
||||||
* section in the netrc.
|
* 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_val = NULL;
|
||||||
passwd.bv_len = 0;
|
passwd.bv_len = 0;
|
||||||
|
|
||||||
if(data->state.aptr.user) {
|
if(data->state.creds) {
|
||||||
binddn = conn->user;
|
binddn = Curl_creds_user(conn->creds);
|
||||||
passwd.bv_val = conn->passwd;
|
passwd.bv_val = CURL_UNCONST(Curl_creds_passwd(conn->creds));
|
||||||
passwd.bv_len = strlen(passwd.bv_val);
|
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);
|
NULL, NULL, &li->msgid);
|
||||||
if(rc != LDAP_SUCCESS)
|
if(rc != LDAP_SUCCESS)
|
||||||
return oldap_map_error(rc,
|
return oldap_map_error(rc,
|
||||||
data->state.aptr.user ?
|
data->state.creds ?
|
||||||
CURLE_LOGIN_DENIED : CURLE_LDAP_CANNOT_BIND);
|
CURLE_LOGIN_DENIED : CURLE_LDAP_CANNOT_BIND);
|
||||||
oldap_state(data, li, newstate);
|
oldap_state(data, li, newstate);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
@ -911,7 +911,7 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
|
||||||
else if(ssl_installed(conn)) {
|
else if(ssl_installed(conn)) {
|
||||||
if(li->sasl.prefmech != SASL_AUTH_NONE)
|
if(li->sasl.prefmech != SASL_AUTH_NONE)
|
||||||
result = oldap_perform_mechs(data);
|
result = oldap_perform_mechs(data);
|
||||||
else if(data->state.aptr.user)
|
else if(data->state.creds)
|
||||||
result = oldap_perform_bind(data, OLDAP_BIND);
|
result = oldap_perform_bind(data, OLDAP_BIND);
|
||||||
else {
|
else {
|
||||||
/* Version 3 supported: no bind required */
|
/* 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
|
/* Check we have a username and password to authenticate with and end the
|
||||||
connect phase if we do not */
|
connect phase if we do not */
|
||||||
if(!data->state.aptr.user) {
|
if(!data->state.creds) {
|
||||||
pop3_state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -535,7 +535,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
|
||||||
|
|
||||||
/* Send the USER command */
|
/* Send the USER command */
|
||||||
result = Curl_pp_sendf(data, &pop3c->pp, "USER %s",
|
result = Curl_pp_sendf(data, &pop3c->pp, "USER %s",
|
||||||
conn->user ? conn->user : "");
|
Curl_creds_user(conn->creds));
|
||||||
if(!result)
|
if(!result)
|
||||||
pop3_state(data, POP3_USER);
|
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
|
/* Check we have a username and password to authenticate with and end the
|
||||||
connect phase if we do not */
|
connect phase if we do not */
|
||||||
if(!data->state.aptr.user) {
|
if(!data->state.creds) {
|
||||||
pop3_state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -578,8 +578,8 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
||||||
Curl_MD5_update(ctxt, (const unsigned char *)pop3c->apoptimestamp,
|
Curl_MD5_update(ctxt, (const unsigned char *)pop3c->apoptimestamp,
|
||||||
curlx_uztoui(strlen(pop3c->apoptimestamp)));
|
curlx_uztoui(strlen(pop3c->apoptimestamp)));
|
||||||
|
|
||||||
Curl_MD5_update(ctxt, (const unsigned char *)conn->passwd,
|
Curl_MD5_update(ctxt, (const unsigned char *)Curl_creds_passwd(conn->creds),
|
||||||
curlx_uztoui(strlen(conn->passwd)));
|
curlx_uztoui(strlen(Curl_creds_passwd(conn->creds))));
|
||||||
|
|
||||||
/* Finalise the digest */
|
/* Finalise the digest */
|
||||||
Curl_MD5_final(ctxt, 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++)
|
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
||||||
curl_msnprintf(&secret[2 * i], 3, "%02x", digest[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)
|
if(!result)
|
||||||
pop3_state(data, POP3_APOP);
|
pop3_state(data, POP3_APOP);
|
||||||
|
|
@ -1038,7 +1039,8 @@ static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Send the PASS command */
|
/* 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)
|
if(!result)
|
||||||
pop3_state(data, POP3_PASS);
|
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_sent = data->state.rtsp_next_client_CSeq;
|
||||||
rtsp->CSeq_recv = 0;
|
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
|
/* Setup the 'p_request' pointer to the proper p_request string
|
||||||
* Since all RTSP requests are included here, there is no need to
|
* Since all RTSP requests are included here, there is no need to
|
||||||
* support custom requests like HTTP.
|
* 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 */
|
/* SMB connection data, kept at connection */
|
||||||
struct smb_conn {
|
struct smb_conn {
|
||||||
enum smb_conn_state state;
|
enum smb_conn_state state;
|
||||||
char *user;
|
const char *user;
|
||||||
char *domain;
|
char *domain;
|
||||||
char *share;
|
char *share;
|
||||||
unsigned char challenge[8];
|
unsigned char challenge[8];
|
||||||
|
|
@ -468,13 +468,14 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
|
||||||
struct connectdata *conn = data->conn;
|
struct connectdata *conn = data->conn;
|
||||||
struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
|
struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
|
||||||
char *slash;
|
char *slash;
|
||||||
|
const char *user = Curl_creds_user(conn->creds);
|
||||||
|
|
||||||
(void)done;
|
(void)done;
|
||||||
if(!smbc)
|
if(!smbc)
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
/* Check we have a username and password to authenticate with */
|
/* 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;
|
return CURLE_LOGIN_DENIED;
|
||||||
|
|
||||||
/* Initialize the connection state */
|
/* Initialize the connection state */
|
||||||
|
|
@ -487,19 +488,19 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Parse the username, domain, and password */
|
/* Parse the username, domain, and password */
|
||||||
slash = strchr(conn->user, '/');
|
slash = strchr(user, '/');
|
||||||
if(!slash)
|
if(!slash)
|
||||||
slash = strchr(conn->user, '\\');
|
slash = strchr(user, '\\');
|
||||||
|
|
||||||
if(slash) {
|
if(slash) {
|
||||||
smbc->user = slash + 1;
|
smbc->user = slash + 1;
|
||||||
smbc->domain = curlx_strdup(conn->user);
|
smbc->domain = curlx_strdup(user);
|
||||||
if(!smbc->domain)
|
if(!smbc->domain)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
smbc->domain[slash - conn->user] = 0;
|
smbc->domain[slash - user] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
smbc->user = conn->user;
|
smbc->user = user;
|
||||||
smbc->domain = curlx_strdup(conn->origin->hostname);
|
smbc->domain = curlx_strdup(conn->origin->hostname);
|
||||||
if(!smbc->domain)
|
if(!smbc->domain)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
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_hash[21];
|
||||||
unsigned char nt[24];
|
unsigned char nt[24];
|
||||||
size_t byte_count;
|
size_t byte_count;
|
||||||
|
const char *passwd = Curl_creds_passwd(conn->creds);
|
||||||
|
|
||||||
if(!smbc || !req)
|
if(!smbc || !req)
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
@ -680,9 +682,9 @@ static CURLcode smb_send_setup(struct Curl_easy *data)
|
||||||
if(byte_count > sizeof(msg.bytes))
|
if(byte_count > sizeof(msg.bytes))
|
||||||
return CURLE_FILESIZE_EXCEEDED;
|
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_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);
|
Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg) - sizeof(msg.bytes));
|
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;
|
enum socks_state_t state;
|
||||||
struct bufq iobuf;
|
struct bufq iobuf;
|
||||||
struct Curl_peer *dest;
|
struct Curl_peer *dest;
|
||||||
const char *user;
|
struct Curl_creds *creds;
|
||||||
const char *passwd;
|
|
||||||
CURLproxycode presult;
|
CURLproxycode presult;
|
||||||
uint32_t resolv_id;
|
uint32_t resolv_id;
|
||||||
uint8_t ip_version;
|
uint8_t ip_version;
|
||||||
|
|
@ -287,8 +286,8 @@ static CURLproxycode socks4_req_add_user(struct socks_ctx *sx,
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
size_t nwritten;
|
size_t nwritten;
|
||||||
|
|
||||||
if(sx->user) {
|
if(sx->creds) {
|
||||||
size_t plen = strlen(sx->user);
|
size_t plen = strlen(sx->creds->user);
|
||||||
if(plen > 255) {
|
if(plen > 255) {
|
||||||
/* there is no real size limit to this field in the protocol, but
|
/* 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
|
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;
|
return CURLPX_LONG_USER;
|
||||||
}
|
}
|
||||||
/* add proxy name WITH trailing zero */
|
/* 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);
|
&nwritten);
|
||||||
if(result || (nwritten != (plen + 1)))
|
if(result || (nwritten != (plen + 1)))
|
||||||
return CURLPX_SEND_REQUEST;
|
return CURLPX_SEND_REQUEST;
|
||||||
|
|
@ -603,7 +602,7 @@ static CURLproxycode socks5_req0_init(struct Curl_cfilter *cf,
|
||||||
"CURLOPT_SOCKS5_AUTH: %u", auth);
|
"CURLOPT_SOCKS5_AUTH: %u", auth);
|
||||||
if(!(auth & CURLAUTH_BASIC))
|
if(!(auth & CURLAUTH_BASIC))
|
||||||
/* disable username/password auth */
|
/* disable username/password auth */
|
||||||
sx->user = NULL;
|
Curl_creds_unlink(&sx->creds);
|
||||||
|
|
||||||
req[0] = 5; /* version */
|
req[0] = 5; /* version */
|
||||||
nauths = 1;
|
nauths = 1;
|
||||||
|
|
@ -614,7 +613,7 @@ static CURLproxycode socks5_req0_init(struct Curl_cfilter *cf,
|
||||||
req[1 + nauths] = 1; /* GSS-API */
|
req[1 + nauths] = 1; /* GSS-API */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(sx->user) {
|
if(sx->creds) {
|
||||||
++nauths;
|
++nauths;
|
||||||
req[1 + nauths] = 2; /* username/password */
|
req[1 + nauths] = 2; /* username/password */
|
||||||
}
|
}
|
||||||
|
|
@ -687,9 +686,9 @@ static CURLproxycode socks5_auth_init(struct Curl_cfilter *cf,
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
if(sx->user && sx->passwd) {
|
if(sx->creds) {
|
||||||
ulen = strlen(sx->user);
|
ulen = strlen(sx->creds->user);
|
||||||
plen = strlen(sx->passwd);
|
plen = strlen(sx->creds->passwd);
|
||||||
/* the lengths must fit in a single byte */
|
/* the lengths must fit in a single byte */
|
||||||
if(ulen > 255) {
|
if(ulen > 255) {
|
||||||
failf(data, "Excessive username length for proxy auth");
|
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))
|
if(result || (nwritten != 2))
|
||||||
return CURLPX_SEND_REQUEST;
|
return CURLPX_SEND_REQUEST;
|
||||||
if(ulen) {
|
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))
|
if(result || (nwritten != ulen))
|
||||||
return CURLPX_SEND_REQUEST;
|
return CURLPX_SEND_REQUEST;
|
||||||
}
|
}
|
||||||
|
|
@ -723,7 +723,8 @@ static CURLproxycode socks5_auth_init(struct Curl_cfilter *cf,
|
||||||
if(result || (nwritten != 1))
|
if(result || (nwritten != 1))
|
||||||
return CURLPX_SEND_REQUEST;
|
return CURLPX_SEND_REQUEST;
|
||||||
if(plen) {
|
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))
|
if(result || (nwritten != plen))
|
||||||
return CURLPX_SEND_REQUEST;
|
return CURLPX_SEND_REQUEST;
|
||||||
}
|
}
|
||||||
|
|
@ -1185,6 +1186,7 @@ static void socks_proxy_ctx_free(struct socks_ctx *ctx)
|
||||||
{
|
{
|
||||||
if(ctx) {
|
if(ctx) {
|
||||||
Curl_peer_unlink(&ctx->dest);
|
Curl_peer_unlink(&ctx->dest);
|
||||||
|
Curl_creds_unlink(&ctx->creds);
|
||||||
Curl_bufq_free(&ctx->iobuf);
|
Curl_bufq_free(&ctx->iobuf);
|
||||||
curlx_free(ctx);
|
curlx_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -1259,10 +1261,8 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
*done = (bool)cf->connected;
|
*done = (bool)cf->connected;
|
||||||
if(*done || result) {
|
if(*done || result)
|
||||||
ctx->user = NULL;
|
Curl_creds_unlink(&ctx->creds);
|
||||||
ctx->passwd = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1361,8 +1361,7 @@ CURLcode Curl_cf_socks_proxy_insert_after(struct Curl_cfilter *cf_at,
|
||||||
struct Curl_peer *dest,
|
struct Curl_peer *dest,
|
||||||
uint8_t ip_version,
|
uint8_t ip_version,
|
||||||
uint8_t proxy_type,
|
uint8_t proxy_type,
|
||||||
const char *user,
|
struct Curl_creds *creds)
|
||||||
const char *passwd)
|
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf;
|
struct Curl_cfilter *cf;
|
||||||
struct socks_ctx *ctx;
|
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);
|
Curl_peer_link(&ctx->dest, dest);
|
||||||
ctx->ip_version = ip_version;
|
ctx->ip_version = ip_version;
|
||||||
ctx->proxy_type = proxy_type;
|
ctx->proxy_type = proxy_type;
|
||||||
ctx->user = user;
|
Curl_creds_link(&ctx->creds, creds);
|
||||||
ctx->passwd = passwd;
|
|
||||||
Curl_bufq_init2(&ctx->iobuf, SOCKS_CHUNK_SIZE, SOCKS_CHUNKS,
|
Curl_bufq_init2(&ctx->iobuf, SOCKS_CHUNK_SIZE, SOCKS_CHUNKS,
|
||||||
BUFQ_OPT_SOFT_LIMIT);
|
BUFQ_OPT_SOFT_LIMIT);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
|
|
||||||
struct Curl_peer;
|
struct Curl_peer;
|
||||||
|
struct Curl_creds;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper read-from-socket functions. Does the same as Curl_read() but it
|
* 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,
|
struct Curl_peer *dest,
|
||||||
uint8_t ip_version,
|
uint8_t ip_version,
|
||||||
uint8_t proxy_type,
|
uint8_t proxy_type,
|
||||||
const char *user,
|
struct Curl_creds *creds);
|
||||||
const char *passwd);
|
|
||||||
|
|
||||||
extern struct Curl_cftype Curl_cft_socks_proxy;
|
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
|
/* Add the username as an environment variable if it
|
||||||
was given on the command line */
|
was given on the command line */
|
||||||
if(data->state.aptr.user) {
|
if(data->state.creds) {
|
||||||
char buffer[256];
|
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"));
|
DEBUGF(infof(data, "set a non ASCII username in telnet"));
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
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);
|
beg = curl_slist_append(tn->telnet_vars, buffer);
|
||||||
if(!beg) {
|
if(!beg) {
|
||||||
curl_slist_free_all(tn->telnet_vars);
|
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);
|
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
|
* 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
|
* 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
|
#endif
|
||||||
data->state.httpreq = data->set.method;
|
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.requests = 0;
|
||||||
data->state.followlocation = 0; /* reset the location-follow counter */
|
data->state.followlocation = 0; /* reset the location-follow counter */
|
||||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
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;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!result)
|
|
||||||
result = Curl_reset_userpwd(data);
|
|
||||||
if(!result)
|
|
||||||
result = Curl_reset_proxypwd(data);
|
|
||||||
|
|
||||||
data->req.headerbytecount = 0;
|
data->req.headerbytecount = 0;
|
||||||
Curl_headers_cleanup(data);
|
Curl_headers_cleanup(data);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@ char *Curl_checkheaders(const struct Curl_easy *data,
|
||||||
|
|
||||||
void Curl_init_CONNECT(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_pretransfer(struct Curl_easy *data);
|
||||||
|
|
||||||
CURLcode Curl_sendrecv(struct Curl_easy *data);
|
CURLcode Curl_sendrecv(struct Curl_easy *data);
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@
|
||||||
|
|
||||||
#include "asyn.h"
|
#include "asyn.h"
|
||||||
#include "cookie.h"
|
#include "cookie.h"
|
||||||
|
#include "creds.h"
|
||||||
#include "psl.h"
|
#include "psl.h"
|
||||||
#include "formdata.h"
|
#include "formdata.h"
|
||||||
#include "http_chunks.h" /* for the structs and enum stuff */
|
#include "http_chunks.h" /* for the structs and enum stuff */
|
||||||
|
|
@ -206,10 +207,9 @@ struct digestdata {
|
||||||
BYTE *input_token;
|
BYTE *input_token;
|
||||||
size_t input_token_len;
|
size_t input_token_len;
|
||||||
CtxtHandle *http_context;
|
CtxtHandle *http_context;
|
||||||
/* copy of user/passwd used to make the identity for http_context.
|
/* linked credentials used to make the identity for http_context.
|
||||||
either may be NULL. */
|
may be NULL. */
|
||||||
char *user;
|
struct Curl_creds *creds;
|
||||||
char *passwd;
|
|
||||||
#else
|
#else
|
||||||
char *nonce;
|
char *nonce;
|
||||||
char *cnonce;
|
char *cnonce;
|
||||||
|
|
@ -249,7 +249,6 @@ struct ConnectBits {
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
BIT(httpproxy); /* if set, this transfer is done through an HTTP 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(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.
|
BIT(tunnel_proxy); /* if CONNECT is used to "tunnel" through the proxy.
|
||||||
This is implicit when SSL-protocols are used through
|
This is implicit when SSL-protocols are used through
|
||||||
proxies, but can also be enabled explicitly by
|
proxies, but can also be enabled explicitly by
|
||||||
|
|
@ -275,9 +274,6 @@ struct ConnectBits {
|
||||||
EPRT does not work we disable it for the forthcoming
|
EPRT does not work we disable it for the forthcoming
|
||||||
requests */
|
requests */
|
||||||
BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
|
BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
|
||||||
#endif
|
|
||||||
#ifndef CURL_DISABLE_NETRC
|
|
||||||
BIT(netrc); /* name+password provided by netrc */
|
|
||||||
#endif
|
#endif
|
||||||
BIT(bound); /* set true if bind() has already been done on this socket/
|
BIT(bound); /* set true if bind() has already been done on this socket/
|
||||||
connection */
|
connection */
|
||||||
|
|
@ -328,9 +324,8 @@ struct ip_quadruple {
|
||||||
|
|
||||||
struct proxy_info {
|
struct proxy_info {
|
||||||
struct Curl_peer *peer; /* proxy to this peer */
|
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 */
|
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 socks_proxy;
|
||||||
struct proxy_info http_proxy;
|
struct proxy_info http_proxy;
|
||||||
#endif
|
#endif
|
||||||
char *user; /* username string, allocated */
|
struct Curl_creds *creds; /* When connection itself is tied to credentials */
|
||||||
char *passwd; /* password string, allocated */
|
|
||||||
char *options; /* options string, allocated */
|
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 created; /* creation time */
|
||||||
struct curltime lastused; /* when returned to the connection pool as idle */
|
struct curltime lastused; /* when returned to the connection pool as idle */
|
||||||
|
|
||||||
|
|
@ -652,11 +644,6 @@ struct urlpieces {
|
||||||
char *query;
|
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 {
|
struct UrlState {
|
||||||
/* buffers to store authentication data in, as parsed from input options */
|
/* buffers to store authentication data in, as parsed from input options */
|
||||||
struct curltime keeps_speed; /* for the progress meter really */
|
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,
|
curl_off_t current_speed; /* the ProgressShow() function sets this,
|
||||||
bytes / second */
|
bytes / second */
|
||||||
|
|
||||||
/* origin of the first (not followed) request.
|
/* Origin of the initial (e.g. not followed) request of a transfer.
|
||||||
if set, this is the origin we sent authorization to, none else.
|
Credentials from CURLOPT_* are only valid for this origin.
|
||||||
Used to make Location: following not keep sending user+password. */
|
Always set once a transfer starts searching for connections. */
|
||||||
struct Curl_peer *first_origin;
|
struct Curl_peer *initial_origin;
|
||||||
|
|
||||||
int os_errno; /* filled in with errno whenever an error occurs */
|
int os_errno; /* filled in with errno whenever an error occurs */
|
||||||
int requests; /* request counter: redirects + authentication retakes */
|
int requests; /* request counter: redirects + authentication retakes */
|
||||||
|
|
@ -765,6 +752,8 @@ struct UrlState {
|
||||||
struct store_netrc netrc;
|
struct store_netrc netrc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct Curl_creds *creds; /* Credentials for the origin only */
|
||||||
|
|
||||||
/* Dynamically allocated strings, MUST be freed before this struct is
|
/* Dynamically allocated strings, MUST be freed before this struct is
|
||||||
killed. */
|
killed. */
|
||||||
struct dynamically_allocated_data {
|
struct dynamically_allocated_data {
|
||||||
|
|
@ -776,14 +765,6 @@ struct UrlState {
|
||||||
#ifndef CURL_DISABLE_RTSP
|
#ifndef CURL_DISABLE_RTSP
|
||||||
char *rtsp_transport;
|
char *rtsp_transport;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* transfer credentials */
|
|
||||||
char *user;
|
|
||||||
char *passwd;
|
|
||||||
#ifndef CURL_DISABLE_PROXY
|
|
||||||
char *proxyuser;
|
|
||||||
char *proxypasswd;
|
|
||||||
#endif
|
|
||||||
} aptr;
|
} aptr;
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
struct http_negotiation http_neg;
|
struct http_negotiation http_neg;
|
||||||
|
|
@ -793,8 +774,6 @@ struct UrlState {
|
||||||
CONN_MAX_RETRIES */
|
CONN_MAX_RETRIES */
|
||||||
uint8_t httpreq; /* Curl_HttpReq; what kind of HTTP request (if any)
|
uint8_t httpreq; /* Curl_HttpReq; what kind of HTTP request (if any)
|
||||||
is this */
|
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
|
/* 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
|
the easy handle so curl_easy_cleanup() on such an easy handle will
|
||||||
|
|
|
||||||
|
|
@ -40,24 +40,21 @@
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* authzid [in] - The authorization identity.
|
* creds [in] - The credentials.
|
||||||
* authcid [in] - The authentication identity.
|
|
||||||
* passwd [in] - The password.
|
* passwd [in] - The password.
|
||||||
* out [out] - The result storage.
|
* out [out] - The result storage.
|
||||||
*
|
*
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_plain_message(const char *authzid,
|
CURLcode Curl_auth_create_plain_message(struct Curl_creds *creds,
|
||||||
const char *authcid,
|
|
||||||
const char *passwd,
|
|
||||||
struct bufref *out)
|
struct bufref *out)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
char *auth;
|
char *auth;
|
||||||
|
|
||||||
size_t zlen = (authzid == NULL ? 0 : strlen(authzid));
|
size_t zlen = strlen(Curl_creds_sasl_authzid(creds));
|
||||||
size_t clen = strlen(authcid);
|
size_t clen = strlen(Curl_creds_user(creds));
|
||||||
size_t plen = strlen(passwd);
|
size_t plen = strlen(Curl_creds_passwd(creds));
|
||||||
|
|
||||||
if((zlen > CURL_MAX_INPUT_LENGTH) || (clen > CURL_MAX_INPUT_LENGTH) ||
|
if((zlen > CURL_MAX_INPUT_LENGTH) || (clen > CURL_MAX_INPUT_LENGTH) ||
|
||||||
(plen > 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;
|
len = zlen + clen + plen + 2;
|
||||||
|
|
||||||
auth = curl_maprintf("%s%c%s%c%s", authzid ? authzid : "", '\0',
|
auth = curl_maprintf("%s%c%s%c%s",
|
||||||
authcid, '\0', passwd);
|
Curl_creds_sasl_authzid(creds), '\0',
|
||||||
|
Curl_creds_user(creds), '\0',
|
||||||
|
Curl_creds_passwd(creds));
|
||||||
if(!auth)
|
if(!auth)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_bufref_set(out, auth, len, curl_free);
|
Curl_bufref_set(out, auth, len, curl_free);
|
||||||
|
|
|
||||||
|
|
@ -47,18 +47,19 @@
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
struct bufref *out)
|
struct bufref *out)
|
||||||
{
|
{
|
||||||
struct HMAC_context *ctxt;
|
struct HMAC_context *ctxt;
|
||||||
unsigned char digest[MD5_DIGEST_LEN];
|
unsigned char digest[MD5_DIGEST_LEN];
|
||||||
char *response;
|
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 */
|
/* Compute the digest using the password as the key */
|
||||||
ctxt = Curl_HMAC_init(&Curl_HMAC_MD5,
|
ctxt = Curl_HMAC_init(&Curl_HMAC_MD5,
|
||||||
(const unsigned char *)passwdp,
|
(const unsigned char *)passwd,
|
||||||
curlx_uztoui(strlen(passwdp)));
|
curlx_uztoui(strlen(passwd)));
|
||||||
if(!ctxt)
|
if(!ctxt)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
|
@ -73,7 +74,7 @@ CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
||||||
/* Generate the response */
|
/* Generate the response */
|
||||||
response = curl_maprintf(
|
response = curl_maprintf(
|
||||||
"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
"%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[5], digest[6], digest[7], digest[8], digest[9], digest[10],
|
||||||
digest[11], digest[12], digest[13], digest[14], digest[15]);
|
digest[11], digest[12], digest[13], digest[14], digest[15]);
|
||||||
if(!response)
|
if(!response)
|
||||||
|
|
|
||||||
|
|
@ -332,13 +332,14 @@ bool Curl_auth_is_digest_supported(void)
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||||
const struct bufref *chlg,
|
const struct bufref *chlg,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
struct bufref *out)
|
struct bufref *out)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
struct MD5_context *ctxt;
|
struct MD5_context *ctxt;
|
||||||
|
const char *userp = Curl_creds_user(creds);
|
||||||
|
const char *passwdp = Curl_creds_passwd(creds);
|
||||||
char *response = NULL;
|
char *response = NULL;
|
||||||
unsigned char digest[MD5_DIGEST_LEN];
|
unsigned char digest[MD5_DIGEST_LEN];
|
||||||
char HA1_hex[(2 * MD5_DIGEST_LEN) + 1];
|
char HA1_hex[(2 * MD5_DIGEST_LEN) + 1];
|
||||||
|
|
@ -666,8 +667,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* userp [in] - The username.
|
* creds [in] - The credentials
|
||||||
* passwdp [in] - The user's password.
|
|
||||||
* request [in] - The HTTP request.
|
* request [in] - The HTTP request.
|
||||||
* uripath [in] - The path of the HTTP uri.
|
* uripath [in] - The path of the HTTP uri.
|
||||||
* digest [in/out] - The digest data struct being used and modified.
|
* 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(
|
static CURLcode auth_create_digest_http_message(
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const unsigned char *request,
|
const unsigned char *request,
|
||||||
const unsigned char *uripath,
|
const unsigned char *uripath,
|
||||||
struct digestdata *digest,
|
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 (*hash)(unsigned char *, const unsigned char *, const size_t))
|
||||||
{
|
{
|
||||||
CURLcode result;
|
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 hashbuf[32]; /* 32 bytes/256 bits */
|
||||||
unsigned char request_digest[65];
|
unsigned char request_digest[65];
|
||||||
unsigned char ha1[65]; /* 64 digits and 1 zero byte */
|
unsigned char ha1[65]; /* 64 digits and 1 zero byte */
|
||||||
|
|
@ -986,29 +987,28 @@ oom:
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const unsigned char *request,
|
const unsigned char *request,
|
||||||
const unsigned char *uripath,
|
const unsigned char *uripath,
|
||||||
struct digestdata *digest,
|
struct digestdata *digest,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
if(digest->algo <= ALGO_MD5SESS)
|
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,
|
request, uripath, digest,
|
||||||
outptr, outlen,
|
outptr, outlen,
|
||||||
auth_digest_md5_to_ascii,
|
auth_digest_md5_to_ascii,
|
||||||
Curl_md5it);
|
Curl_md5it);
|
||||||
|
|
||||||
if(digest->algo <= ALGO_SHA256SESS)
|
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,
|
request, uripath, digest,
|
||||||
outptr, outlen,
|
outptr, outlen,
|
||||||
auth_digest_sha256_to_ascii,
|
auth_digest_sha256_to_ascii,
|
||||||
Curl_sha256it);
|
Curl_sha256it);
|
||||||
#ifdef CURL_HAVE_SHA512_256
|
#ifdef CURL_HAVE_SHA512_256
|
||||||
if(digest->algo <= ALGO_SHA512_256SESS)
|
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,
|
request, uripath, digest,
|
||||||
outptr, outlen,
|
outptr, outlen,
|
||||||
auth_digest_sha256_to_ascii,
|
auth_digest_sha256_to_ascii,
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_DIGEST_AUTH)
|
#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_DIGEST_AUTH)
|
||||||
|
|
||||||
|
#include "creds.h"
|
||||||
#include "vauth/vauth.h"
|
#include "vauth/vauth.h"
|
||||||
#include "vauth/digest.h"
|
#include "vauth/digest.h"
|
||||||
#include "curlx/multibyte.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,
|
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||||
const struct bufref *chlg,
|
const struct bufref *chlg,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
struct bufref *out)
|
struct bufref *out)
|
||||||
{
|
{
|
||||||
|
|
@ -137,9 +137,10 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(userp && *userp) {
|
if(Curl_creds_has_user(creds)) {
|
||||||
/* Populate our identity structure */
|
/* Populate our identity structure */
|
||||||
result = Curl_create_sspi_identity(userp, passwdp, &identity);
|
result = Curl_create_sspi_identity(creds->user, creds->passwd,
|
||||||
|
&identity);
|
||||||
if(result) {
|
if(result) {
|
||||||
curlx_free(spn);
|
curlx_free(spn);
|
||||||
curlx_free(output_token);
|
curlx_free(output_token);
|
||||||
|
|
@ -381,8 +382,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const unsigned char *request,
|
const unsigned char *request,
|
||||||
const unsigned char *uripath,
|
const unsigned char *uripath,
|
||||||
struct digestdata *digest,
|
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
|
/* If the user/passwd that was used to make the identity for http_context
|
||||||
has changed then delete that context. */
|
has changed then delete that context. */
|
||||||
if((userp && !digest->user) || (!userp && digest->user) ||
|
if(!Curl_creds_same(creds, digest->creds)) {
|
||||||
(passwdp && !digest->passwd) || (!passwdp && digest->passwd) ||
|
|
||||||
(userp && digest->user && Curl_timestrcmp(userp, digest->user)) ||
|
|
||||||
(passwdp && digest->passwd && Curl_timestrcmp(passwdp, digest->passwd))) {
|
|
||||||
if(digest->http_context) {
|
if(digest->http_context) {
|
||||||
Curl_pSecFn->DeleteSecurityContext(digest->http_context);
|
Curl_pSecFn->DeleteSecurityContext(digest->http_context);
|
||||||
curlx_safefree(digest->http_context);
|
curlx_safefree(digest->http_context);
|
||||||
}
|
}
|
||||||
curlx_safefree(digest->user);
|
Curl_creds_unlink(&digest->creds);
|
||||||
curlx_safefree(digest->passwd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(digest->http_context) {
|
if(digest->http_context) {
|
||||||
|
|
@ -473,13 +469,13 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||||
unsigned long attrs;
|
unsigned long attrs;
|
||||||
TCHAR *spn;
|
TCHAR *spn;
|
||||||
|
|
||||||
/* free the copy of user/passwd used to make the previous identity */
|
/* free the credentials used to make the previous identity */
|
||||||
curlx_safefree(digest->user);
|
Curl_creds_unlink(&digest->creds);
|
||||||
curlx_safefree(digest->passwd);
|
|
||||||
|
|
||||||
if(userp && *userp) {
|
if(Curl_creds_has_user(creds)) {
|
||||||
/* Populate our identity structure */
|
/* 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);
|
curlx_free(output_token);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
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 */
|
/* Use the current Windows user */
|
||||||
p_identity = NULL;
|
p_identity = NULL;
|
||||||
|
|
||||||
if(userp) {
|
if(creds)
|
||||||
digest->user = curlx_strdup(userp);
|
Curl_creds_link(&digest->creds, creds);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Acquire our credentials handle */
|
/* Acquire our credentials handle */
|
||||||
status = Curl_pSecFn->AcquireCredentialsHandle(NULL,
|
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 */
|
/* Free the copy of user/passwd used to make the identity for http_context */
|
||||||
curlx_safefree(digest->user);
|
Curl_creds_unlink(&digest->creds);
|
||||||
curlx_safefree(digest->passwd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_DIGEST_AUTH */
|
#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,
|
CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
struct gsasldata *gsasl)
|
struct gsasldata *gsasl)
|
||||||
{
|
{
|
||||||
#if GSASL_VERSION_NUMBER >= 0x010b00
|
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||||
int res;
|
int res;
|
||||||
res =
|
res =
|
||||||
#endif
|
#endif
|
||||||
gsasl_property_set(gsasl->client, GSASL_AUTHID, userp);
|
gsasl_property_set(gsasl->client, GSASL_AUTHID, creds->user);
|
||||||
#if GSASL_VERSION_NUMBER >= 0x010b00
|
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||||
if(res != GSASL_OK) {
|
if(res != GSASL_OK) {
|
||||||
failf(data, "setting AUTHID failed: %s", gsasl_strerror(res));
|
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
|
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||||
res =
|
res =
|
||||||
#endif
|
#endif
|
||||||
gsasl_property_set(gsasl->client, GSASL_PASSWORD, passwdp);
|
gsasl_property_set(gsasl->client, GSASL_PASSWORD, creds->passwd);
|
||||||
#if GSASL_VERSION_NUMBER >= 0x010b00
|
#if GSASL_VERSION_NUMBER >= 0x010b00
|
||||||
if(res != GSASL_OK) {
|
if(res != GSASL_OK) {
|
||||||
failf(data, "setting PASSWORD failed: %s", gsasl_strerror(res));
|
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.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
const bool mutual_auth,
|
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 input_token = GSS_C_EMPTY_BUFFER;
|
||||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||||
|
|
||||||
(void)userp;
|
(void)creds;
|
||||||
(void)passwdp;
|
|
||||||
|
|
||||||
if(!krb5->spn) {
|
if(!krb5->spn) {
|
||||||
gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
|
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.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
const bool mutual_auth,
|
const bool mutual_auth,
|
||||||
|
|
@ -128,9 +127,10 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||||
|
|
||||||
if(!krb5->credentials) {
|
if(!krb5->credentials) {
|
||||||
/* Do we have credentials to use or are we using single sign-on? */
|
/* 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 */
|
/* 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)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -421,8 +421,7 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
struct ntlmdata *ntlm,
|
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
|
size_t domoff = hostoff + hostlen; /* This is 0: remember that host and
|
||||||
domain are empty */
|
domain are empty */
|
||||||
(void)data;
|
(void)data;
|
||||||
(void)userp;
|
(void)creds;
|
||||||
(void)passwdp;
|
|
||||||
(void)service;
|
(void)service;
|
||||||
(void)host;
|
(void)host;
|
||||||
|
|
||||||
|
|
@ -542,8 +540,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
struct bufref *out)
|
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
|
/* The fixed hostname we provide, in order to not leak our real local host
|
||||||
name. Copy the name used by Firefox. */
|
name. Copy the name used by Firefox. */
|
||||||
static const char host[] = "WORKSTATION";
|
static const char host[] = "WORKSTATION";
|
||||||
|
const char *userp = Curl_creds_user(creds);
|
||||||
|
const char *passwdp = Curl_creds_passwd(creds);
|
||||||
const char *user;
|
const char *user;
|
||||||
const char *domain = "";
|
const char *domain = "";
|
||||||
size_t hostoff = 0;
|
size_t hostoff = 0;
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,7 @@ bool Curl_auth_is_ntlm_supported(void)
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
|
|
@ -111,11 +110,12 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
if(!ntlm->output_token)
|
if(!ntlm->output_token)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
if(userp && *userp) {
|
if(Curl_creds_has_user(creds)) {
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
/* Populate our identity structure */
|
/* 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)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
@ -227,8 +227,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
struct bufref *out)
|
struct bufref *out)
|
||||||
{
|
{
|
||||||
|
|
@ -240,8 +239,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||||
SECURITY_STATUS status;
|
SECURITY_STATUS status;
|
||||||
unsigned long attrs;
|
unsigned long attrs;
|
||||||
|
|
||||||
(void)passwdp;
|
(void)creds;
|
||||||
(void)userp;
|
|
||||||
|
|
||||||
/* Setup the type-2 "input" security buffer */
|
/* Setup the type-2 "input" security buffer */
|
||||||
type_2_desc.ulVersion = SECBUFFER_VERSION;
|
type_2_desc.ulVersion = SECBUFFER_VERSION;
|
||||||
|
|
|
||||||
|
|
@ -47,21 +47,22 @@
|
||||||
*
|
*
|
||||||
* Returns CURLE_OK on success.
|
* 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 char *host,
|
||||||
const long port,
|
const long port,
|
||||||
const char *bearer,
|
|
||||||
struct bufref *out)
|
struct bufref *out)
|
||||||
{
|
{
|
||||||
char *oauth;
|
char *oauth;
|
||||||
|
|
||||||
/* Generate the message */
|
/* Generate the message */
|
||||||
if(port == 0 || port == 80)
|
if(port == 0 || port == 80)
|
||||||
oauth = curl_maprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host,
|
oauth = curl_maprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1",
|
||||||
bearer);
|
Curl_creds_user(creds), host,
|
||||||
|
Curl_creds_oauth_bearer(creds));
|
||||||
else
|
else
|
||||||
oauth = curl_maprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1",
|
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)
|
if(!oauth)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
|
@ -83,12 +84,13 @@ CURLcode Curl_auth_create_oauth_bearer_message(const char *user,
|
||||||
*
|
*
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_create_xoauth_bearer_message(const char *user,
|
CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_creds *creds,
|
||||||
const char *bearer,
|
|
||||||
struct bufref *out)
|
struct bufref *out)
|
||||||
{
|
{
|
||||||
/* Generate the message */
|
/* 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)
|
if(!xoauth)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,7 @@ bool Curl_auth_is_spnego_supported(void)
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||||
const char *user,
|
struct Curl_creds *creds,
|
||||||
const char *password,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
const char *chlg64,
|
const char *chlg64,
|
||||||
|
|
@ -90,8 +89,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||||
struct gss_channel_bindings_struct chan;
|
struct gss_channel_bindings_struct chan;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void)user;
|
(void)creds;
|
||||||
(void)password;
|
|
||||||
|
|
||||||
if(nego->context && nego->status == GSS_S_COMPLETE) {
|
if(nego->context && nego->status == GSS_S_COMPLETE) {
|
||||||
/* We finished successfully our part of authentication, but server
|
/* 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.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||||
const char *user,
|
struct Curl_creds *creds,
|
||||||
const char *password,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
const char *chlg64,
|
const char *chlg64,
|
||||||
|
|
@ -133,9 +132,10 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||||
|
|
||||||
if(!nego->credentials) {
|
if(!nego->credentials) {
|
||||||
/* Do we have credentials to use or are we using single sign-on? */
|
/* 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 */
|
/* 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)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#include "vauth/vauth.h"
|
#include "vauth/vauth.h"
|
||||||
|
#include "creds.h"
|
||||||
#include "curlx/multibyte.h"
|
#include "curlx/multibyte.h"
|
||||||
#include "url.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.
|
* 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;
|
bool valid = FALSE;
|
||||||
|
|
||||||
if(user && *user) {
|
if(Curl_creds_has_user(creds)) {
|
||||||
/* Check we have a domain name or UPN present */
|
/* 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)
|
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||||
else
|
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
|
* 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)
|
bool Curl_auth_allowed_to_host(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
return !data->state.this_is_a_follow ||
|
return data->set.allow_auth_to_other_hosts ||
|
||||||
data->set.allow_auth_to_other_hosts ||
|
Curl_peer_equal(data->state.initial_origin, data->conn->origin);
|
||||||
(data->state.first_origin &&
|
|
||||||
Curl_peer_equal(data->state.first_origin, data->conn->origin));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_NTLM
|
#ifdef USE_NTLM
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
|
|
||||||
struct Curl_easy;
|
struct Curl_easy;
|
||||||
|
struct Curl_creds;
|
||||||
struct connectdata;
|
struct connectdata;
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_DIGEST_AUTH
|
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||||
|
|
@ -69,12 +70,10 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is used to test if the user contains a Windows domain name */
|
/* 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 */
|
/* This is used to generate a PLAIN cleartext message */
|
||||||
CURLcode Curl_auth_create_plain_message(const char *authzid,
|
CURLcode Curl_auth_create_plain_message(struct Curl_creds *creds,
|
||||||
const char *authcid,
|
|
||||||
const char *passwd,
|
|
||||||
struct bufref *out);
|
struct bufref *out);
|
||||||
|
|
||||||
/* This is used to generate a LOGIN cleartext message */
|
/* 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
|
#ifndef CURL_DISABLE_DIGEST_AUTH
|
||||||
/* This is used to generate a CRAM-MD5 response message */
|
/* This is used to generate a CRAM-MD5 response message */
|
||||||
CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
struct bufref *out);
|
struct bufref *out);
|
||||||
|
|
||||||
/* This is used to evaluate if DIGEST is supported */
|
/* 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 */
|
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
||||||
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||||
const struct bufref *chlg,
|
const struct bufref *chlg,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
struct bufref *out);
|
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 */
|
/* This is used to generate an HTTP DIGEST response message */
|
||||||
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const unsigned char *request,
|
const unsigned char *request,
|
||||||
const unsigned char *uripath,
|
const unsigned char *uripath,
|
||||||
struct digestdata *digest,
|
struct digestdata *digest,
|
||||||
|
|
@ -140,8 +136,7 @@ bool Curl_auth_gsasl_is_supported(struct Curl_easy *data,
|
||||||
struct gsasldata *gsasl);
|
struct gsasldata *gsasl);
|
||||||
/* This is used to start a gsasl method */
|
/* This is used to start a gsasl method */
|
||||||
CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
|
CURLcode Curl_auth_gsasl_start(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
struct gsasldata *gsasl);
|
struct gsasldata *gsasl);
|
||||||
|
|
||||||
/* This is used to process and generate a new SASL token */
|
/* 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 */
|
/* This is used to generate a base64 encoded NTLM type-1 message */
|
||||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
struct ntlmdata *ntlm,
|
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 */
|
/* This is used to generate a base64 encoded NTLM type-3 message */
|
||||||
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
struct bufref *out);
|
struct bufref *out);
|
||||||
|
|
||||||
|
|
@ -221,15 +214,13 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||||
#endif /* USE_NTLM */
|
#endif /* USE_NTLM */
|
||||||
|
|
||||||
/* This is used to generate a base64 encoded OAuth 2.0 message */
|
/* 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 char *host,
|
||||||
const long port,
|
const long port,
|
||||||
const char *bearer,
|
|
||||||
struct bufref *out);
|
struct bufref *out);
|
||||||
|
|
||||||
/* This is used to generate a base64 encoded XOAuth 2.0 message */
|
/* This is used to generate a base64 encoded XOAuth 2.0 message */
|
||||||
CURLcode Curl_auth_create_xoauth_bearer_message(const char *user,
|
CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_creds *creds,
|
||||||
const char *bearer,
|
|
||||||
struct bufref *out);
|
struct bufref *out);
|
||||||
|
|
||||||
#ifdef USE_KERBEROS5
|
#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
|
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
|
||||||
message */
|
message */
|
||||||
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
struct Curl_creds *creds,
|
||||||
const char *passwdp,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
const bool mutual_auth,
|
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
|
/* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge
|
||||||
message */
|
message */
|
||||||
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||||
const char *user,
|
struct Curl_creds *creds,
|
||||||
const char *password,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *host,
|
const char *host,
|
||||||
const char *chlg64,
|
const char *chlg64,
|
||||||
|
|
|
||||||
|
|
@ -633,7 +633,8 @@ restart:
|
||||||
if(nprompts != 1)
|
if(nprompts != 1)
|
||||||
return SSH_ERROR;
|
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)
|
if(rc < 0)
|
||||||
return SSH_ERROR;
|
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,
|
static int myssh_in_AUTH_PASS(struct Curl_easy *data,
|
||||||
struct ssh_conn *sshc)
|
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)
|
if(rc == SSH_AUTH_AGAIN)
|
||||||
return SSH_AGAIN;
|
return SSH_AGAIN;
|
||||||
else if(rc == SSH_AUTH_SUCCESS) {
|
else if(rc == SSH_AUTH_SUCCESS) {
|
||||||
|
|
@ -2571,9 +2573,10 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->user && conn->user[0] != '\0') {
|
if(Curl_creds_has_user(conn->creds)) {
|
||||||
infof(data, "User: %s", conn->user);
|
infof(data, "User: %s", conn->creds->user);
|
||||||
rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_USER, conn->user);
|
rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_USER,
|
||||||
|
conn->creds->user);
|
||||||
if(rc != SSH_OK) {
|
if(rc != SSH_OK) {
|
||||||
failf(data, "Could not set user");
|
failf(data, "Could not set user");
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
|
||||||
|
|
@ -148,11 +148,12 @@ static void kbd_callback(const char *name, int name_len,
|
||||||
#endif /* CURL_LIBSSH2_DEBUG */
|
#endif /* CURL_LIBSSH2_DEBUG */
|
||||||
if(num_prompts == 1) {
|
if(num_prompts == 1) {
|
||||||
struct connectdata *conn = data->conn;
|
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
|
/* this function must allocate memory that can be freed by libssh2, which
|
||||||
uses the LIBSSH2_FREE_FUNC callback */
|
uses the LIBSSH2_FREE_FUNC callback */
|
||||||
responses[0].text = Curl_cstrdup(conn->passwd);
|
responses[0].text = Curl_cstrdup(passwd);
|
||||||
responses[0].length =
|
responses[0].length =
|
||||||
responses[0].text == NULL ? 0 : curlx_uztoui(strlen(conn->passwd));
|
responses[0].text == NULL ? 0 : curlx_uztoui(strlen(passwd));
|
||||||
}
|
}
|
||||||
(void)prompts;
|
(void)prompts;
|
||||||
} /* kbd_callback */
|
} /* kbd_callback */
|
||||||
|
|
@ -1496,9 +1497,9 @@ static CURLcode ssh_state_authlist(struct Curl_easy *data,
|
||||||
* Therefore always specify it here.
|
* Therefore always specify it here.
|
||||||
*/
|
*/
|
||||||
struct connectdata *conn = data->conn;
|
struct connectdata *conn = data->conn;
|
||||||
|
const char *user = Curl_creds_user(conn->creds);
|
||||||
sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
|
sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
|
||||||
conn->user,
|
user, curlx_uztoui(strlen(user)));
|
||||||
curlx_uztoui(strlen(conn->user)));
|
|
||||||
|
|
||||||
if(!sshc->authlist) {
|
if(!sshc->authlist) {
|
||||||
int rc;
|
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.
|
/* The function below checks if the files exists, no need to stat() here.
|
||||||
*/
|
*/
|
||||||
struct connectdata *conn = data->conn;
|
struct connectdata *conn = data->conn;
|
||||||
|
const char *user = Curl_creds_user(conn->creds);
|
||||||
int rc =
|
int rc =
|
||||||
libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
|
libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
|
||||||
conn->user,
|
user,
|
||||||
curlx_uztoui(
|
curlx_uztoui(strlen(user)),
|
||||||
strlen(conn->user)),
|
|
||||||
sshc->rsa_pub,
|
sshc->rsa_pub,
|
||||||
sshc->rsa, sshc->passphrase);
|
sshc->rsa, sshc->passphrase);
|
||||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||||
|
|
@ -1579,11 +1580,13 @@ static CURLcode ssh_state_auth_pass(struct Curl_easy *data,
|
||||||
struct ssh_conn *sshc)
|
struct ssh_conn *sshc)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = data->conn;
|
struct connectdata *conn = data->conn;
|
||||||
|
const char *user = Curl_creds_user(conn->creds);
|
||||||
|
const char *passwd = Curl_creds_passwd(conn->creds);
|
||||||
int rc =
|
int rc =
|
||||||
libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
|
libssh2_userauth_password_ex(sshc->ssh_session, user,
|
||||||
curlx_uztoui(strlen(conn->user)),
|
curlx_uztoui(strlen(user)),
|
||||||
conn->passwd,
|
passwd,
|
||||||
curlx_uztoui(strlen(conn->passwd)),
|
curlx_uztoui(strlen(passwd)),
|
||||||
NULL);
|
NULL);
|
||||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
return CURLE_AGAIN;
|
return CURLE_AGAIN;
|
||||||
|
|
@ -1680,7 +1683,7 @@ static CURLcode ssh_state_auth_agent(struct Curl_easy *data,
|
||||||
|
|
||||||
if(rc == 0) {
|
if(rc == 0) {
|
||||||
struct connectdata *conn = data->conn;
|
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);
|
sshc->sshagent_identity);
|
||||||
|
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
|
|
@ -1727,11 +1730,10 @@ static CURLcode ssh_state_auth_key(struct Curl_easy *data,
|
||||||
{
|
{
|
||||||
/* Authentication failed. Continue with keyboard-interactive now. */
|
/* Authentication failed. Continue with keyboard-interactive now. */
|
||||||
struct connectdata *conn = data->conn;
|
struct connectdata *conn = data->conn;
|
||||||
|
const char *user = Curl_creds_user(conn->creds);
|
||||||
int rc =
|
int rc =
|
||||||
libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
|
libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
|
||||||
conn->user,
|
user, curlx_uztoui(strlen(user)),
|
||||||
curlx_uztoui(
|
|
||||||
strlen(conn->user)),
|
|
||||||
&kbd_callback);
|
&kbd_callback);
|
||||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||||
return CURLE_AGAIN;
|
return CURLE_AGAIN;
|
||||||
|
|
@ -3452,9 +3454,9 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
|
||||||
if(!sshc)
|
if(!sshc)
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
infof(data, "User: '%s'", conn->user);
|
infof(data, "User: '%s'", Curl_creds_user(conn->creds));
|
||||||
#ifdef CURL_LIBSSH2_DEBUG
|
#ifdef CURL_LIBSSH2_DEBUG
|
||||||
infof(data, "Password: %s", conn->passwd);
|
infof(data, "Password: %s", Curl_creds_passwd(conn->creds));
|
||||||
sock = conn->sock[FIRSTSOCKET];
|
sock = conn->sock[FIRSTSOCKET];
|
||||||
#endif /* CURL_LIBSSH2_DEBUG */
|
#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_INFILESIZE, 0L);
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3");
|
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_HEADER, 0L);
|
||||||
test_setopt(curl, CURLOPT_URL, URL);
|
test_setopt(curl, CURLOPT_URL, URL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,17 +25,37 @@
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_NETRC
|
#ifndef CURL_DISABLE_NETRC
|
||||||
#include "netrc.h"
|
#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);
|
Curl_creds_unlink(pc1);
|
||||||
curlx_safefree(*login);
|
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)
|
static CURLcode test_unit1304(const char *arg)
|
||||||
{
|
{
|
||||||
char *login = NULL;
|
struct Curl_creds *cr_out = NULL, *cr_in = NULL;
|
||||||
char *password = NULL;
|
|
||||||
|
|
||||||
UNITTEST_BEGIN_SIMPLE
|
UNITTEST_BEGIN_SIMPLE
|
||||||
|
|
||||||
|
|
@ -46,126 +66,119 @@ static CURLcode test_unit1304(const char *arg)
|
||||||
* Test a non existent host in our netrc file.
|
* Test a non existent host in our netrc file.
|
||||||
*/
|
*/
|
||||||
Curl_netrc_init(&store);
|
Curl_netrc_init(&store);
|
||||||
result = Curl_parsenetrc(&store, "test.example.com", &login, &password, arg);
|
result = Curl_parsenetrc(&store, "test.example.com", NULL, arg, &cr_out);
|
||||||
fail_unless(result == 1, "Host not found should return 1");
|
fail_unless(result == 1, "expected no match");
|
||||||
abort_unless(password == NULL, "password did not return NULL!");
|
abort_unless(cr_out == NULL, "creds did not return NULL!");
|
||||||
abort_unless(login == NULL, "user did not return NULL!");
|
|
||||||
Curl_netrc_cleanup(&store);
|
Curl_netrc_cleanup(&store);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test a non existent login in our netrc file.
|
* 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);
|
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");
|
fail_unless(result == 1, "expected no match");
|
||||||
abort_unless(password == NULL, "password is not NULL!");
|
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||||
Curl_netrc_cleanup(&store);
|
Curl_netrc_cleanup(&store);
|
||||||
curlx_free(login);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test a non existent login and host in our netrc file.
|
* 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);
|
Curl_netrc_init(&store);
|
||||||
result = Curl_parsenetrc(&store, "test.example.com", &login, &password, arg);
|
result = Curl_parsenetrc(&store, "test.example.com", cr_in, arg, &cr_out);
|
||||||
fail_unless(result == 1, "Host not found should return 1");
|
fail_unless(result == 1, "expected no match");
|
||||||
abort_unless(password == NULL, "password is not NULL!");
|
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||||
Curl_netrc_cleanup(&store);
|
Curl_netrc_cleanup(&store);
|
||||||
curlx_free(login);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test a non existent login (substring of an existing one) in our
|
* Test a non existent login (substring of an existing one) in our
|
||||||
* netrc file.
|
* 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);
|
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");
|
fail_unless(result == 1, "expected no match");
|
||||||
abort_unless(password == NULL, "password is not NULL!");
|
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||||
Curl_netrc_cleanup(&store);
|
Curl_netrc_cleanup(&store);
|
||||||
curlx_free(login);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test a non existent login (superstring of an existing one)
|
* Test a non existent login (superstring of an existing one)
|
||||||
* in our netrc file.
|
* in our netrc file.
|
||||||
*/
|
*/
|
||||||
login = curlx_strdup("adminn");
|
fail_unless(t1304_set_creds("adminn", NULL, &cr_in), "err set creds");
|
||||||
Curl_netrc_init(&store);
|
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");
|
fail_unless(result == 1, "expected no match");
|
||||||
abort_unless(password == NULL, "password is not NULL!");
|
abort_unless(t1304_no_passwd(cr_out), "password is not NULL!");
|
||||||
Curl_netrc_cleanup(&store);
|
Curl_netrc_cleanup(&store);
|
||||||
curlx_free(login);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test for the first existing host in our netrc file
|
* Test for the first existing host in our netrc file
|
||||||
* with login[0] = 0.
|
* with login[0] = 0.
|
||||||
*/
|
*/
|
||||||
login = NULL;
|
Curl_creds_unlink(&cr_in);
|
||||||
Curl_netrc_init(&store);
|
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");
|
fail_unless(result == 0, "Host should have been found");
|
||||||
abort_unless(password != NULL, "returned NULL!");
|
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||||
fail_unless(strncmp(password, "passwd", 6) == 0,
|
fail_unless(strncmp(Curl_creds_passwd(cr_out), "passwd", 6) == 0,
|
||||||
"password should be 'passwd'");
|
"password should be 'passwd'");
|
||||||
abort_unless(login != NULL, "returned NULL!");
|
abort_unless(!t1304_no_user(cr_out), "returned NULL!");
|
||||||
fail_unless(strncmp(login, "admin", 5) == 0, "login should be 'admin'");
|
fail_unless(strncmp(Curl_creds_user(cr_out), "admin", 5) == 0,
|
||||||
|
"login should be 'admin'");
|
||||||
Curl_netrc_cleanup(&store);
|
Curl_netrc_cleanup(&store);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test for the first existing host in our netrc file
|
* Test for the first existing host in our netrc file
|
||||||
* with login[0] != 0.
|
* with login[0] != 0.
|
||||||
*/
|
*/
|
||||||
curlx_free(password);
|
Curl_creds_unlink(&cr_in);
|
||||||
curlx_free(login);
|
|
||||||
password = NULL;
|
|
||||||
login = NULL;
|
|
||||||
Curl_netrc_init(&store);
|
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");
|
fail_unless(result == 0, "Host should have been found");
|
||||||
abort_unless(password != NULL, "returned NULL!");
|
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||||
fail_unless(strncmp(password, "passwd", 6) == 0,
|
fail_unless(strncmp(Curl_creds_passwd(cr_out), "passwd", 6) == 0,
|
||||||
"password should be 'passwd'");
|
"password should be 'passwd'");
|
||||||
abort_unless(login != NULL, "returned NULL!");
|
abort_unless(!t1304_no_user(cr_out), "returned NULL!");
|
||||||
fail_unless(strncmp(login, "admin", 5) == 0, "login should be 'admin'");
|
fail_unless(strncmp(Curl_creds_user(cr_out), "admin", 5) == 0,
|
||||||
|
"login should be 'admin'");
|
||||||
Curl_netrc_cleanup(&store);
|
Curl_netrc_cleanup(&store);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test for the second existing host in our netrc file
|
* Test for the second existing host in our netrc file
|
||||||
* with login[0] = 0.
|
* with login[0] = 0.
|
||||||
*/
|
*/
|
||||||
curlx_free(password);
|
Curl_creds_unlink(&cr_in);
|
||||||
password = NULL;
|
|
||||||
curlx_free(login);
|
|
||||||
login = NULL;
|
|
||||||
Curl_netrc_init(&store);
|
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");
|
fail_unless(result == 0, "Host should have been found");
|
||||||
abort_unless(password != NULL, "returned NULL!");
|
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||||
fail_unless(strncmp(password, "none", 4) == 0, "password should be 'none'");
|
fail_unless(strncmp(Curl_creds_passwd(cr_out), "none", 4) == 0,
|
||||||
abort_unless(login != NULL, "returned NULL!");
|
"password should be 'none'");
|
||||||
fail_unless(strncmp(login, "none", 4) == 0, "login 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);
|
Curl_netrc_cleanup(&store);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test for the second existing host in our netrc file
|
* Test for the second existing host in our netrc file
|
||||||
* with login[0] != 0.
|
* with login[0] != 0.
|
||||||
*/
|
*/
|
||||||
curlx_free(password);
|
Curl_creds_unlink(&cr_in);
|
||||||
password = NULL;
|
|
||||||
curlx_free(login);
|
|
||||||
login = NULL;
|
|
||||||
Curl_netrc_init(&store);
|
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");
|
fail_unless(result == 0, "Host should have been found");
|
||||||
abort_unless(password != NULL, "returned NULL!");
|
abort_unless(!t1304_no_passwd(cr_out), "returned NULL!");
|
||||||
fail_unless(strncmp(password, "none", 4) == 0, "password should be 'none'");
|
fail_unless(strncmp(Curl_creds_passwd(cr_out), "none", 4) == 0,
|
||||||
abort_unless(login != NULL, "returned NULL!");
|
"password should be 'none'");
|
||||||
fail_unless(strncmp(login, "none", 4) == 0, "login 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);
|
Curl_netrc_cleanup(&store);
|
||||||
|
|
||||||
UNITTEST_END(t1304_stop(&password, &login))
|
UNITTEST_END(t1304_stop(&cr_in, &cr_out))
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue