#include "../curl_setup.h"
#include <curl/curl.h>
#include "vauth.h"
#include "../strdup.h"
#include "../urldata.h"
#include "../curlx/multibyte.h"
#include "../url.h"
#include "../curl_memory.h"
#include "../memdebug.h"
#ifndef USE_WINDOWS_SSPI
char *Curl_auth_build_spn(const char *service, const char *host,
const char *realm)
{
char *spn = NULL;
if(host && realm)
spn = curl_maprintf("%s/%s@%s", service, host, realm);
else if(host)
spn = curl_maprintf("%s/%s", service, host);
else if(realm)
spn = curl_maprintf("%s@%s", service, realm);
return spn;
}
#else
TCHAR *Curl_auth_build_spn(const char *service, const char *host,
const char *realm)
{
char *utf8_spn = NULL;
TCHAR *tchar_spn = NULL;
TCHAR *dupe_tchar_spn = NULL;
(void)realm;
utf8_spn = curl_maprintf("%s/%s", service, host);
if(!utf8_spn)
return NULL;
tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn);
free(utf8_spn);
if(!tchar_spn)
return NULL;
dupe_tchar_spn = Curl_tcsdup(tchar_spn);
curlx_unicodefree(tchar_spn);
return dupe_tchar_spn;
}
#endif
bool Curl_auth_user_contains_domain(const char *user)
{
bool valid = FALSE;
if(user && *user) {
char *p = strpbrk(user, "\\/@");
valid = (p != NULL && p > user && p < user + strlen(user) - 1);
}
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
else
valid = TRUE;
#endif
return valid;
}
bool Curl_auth_allowed_to_host(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
return !data->state.this_is_a_follow ||
data->set.allow_auth_to_other_hosts ||
(data->state.first_host &&
curl_strequal(data->state.first_host, conn->host.name) &&
(data->state.first_remote_port == conn->remote_port) &&
(data->state.first_remote_protocol == conn->handler->protocol));
}
#ifdef USE_NTLM
static void ntlm_conn_dtor(void *key, size_t klen, void *entry)
{
struct ntlmdata *ntlm = entry;
(void)key;
(void)klen;
DEBUGASSERT(ntlm);
Curl_auth_cleanup_ntlm(ntlm);
free(ntlm);
}
struct ntlmdata *Curl_auth_ntlm_get(struct connectdata *conn, bool proxy)
{
const char *key = proxy ? CURL_META_NTLM_PROXY_CONN :
CURL_META_NTLM_CONN;
struct ntlmdata *ntlm = Curl_conn_meta_get(conn, key);
if(!ntlm) {
ntlm = calloc(1, sizeof(*ntlm));
if(!ntlm ||
Curl_conn_meta_set(conn, key, ntlm, ntlm_conn_dtor))
return NULL;
}
return ntlm;
}
void Curl_auth_ntlm_remove(struct connectdata *conn, bool proxy)
{
Curl_conn_meta_remove(conn, proxy ?
CURL_META_NTLM_PROXY_CONN : CURL_META_NTLM_CONN);
}
#endif
#ifdef USE_KERBEROS5
static void krb5_conn_dtor(void *key, size_t klen, void *entry)
{
struct kerberos5data *krb5 = entry;
(void)key;
(void)klen;
DEBUGASSERT(krb5);
Curl_auth_cleanup_gssapi(krb5);
free(krb5);
}
struct kerberos5data *Curl_auth_krb5_get(struct connectdata *conn)
{
struct kerberos5data *krb5 = Curl_conn_meta_get(conn, CURL_META_KRB5_CONN);
if(!krb5) {
krb5 = calloc(1, sizeof(*krb5));
if(!krb5 ||
Curl_conn_meta_set(conn, CURL_META_KRB5_CONN, krb5, krb5_conn_dtor))
return NULL;
}
return krb5;
}
#endif
#ifdef USE_GSASL
static void gsasl_conn_dtor(void *key, size_t klen, void *entry)
{
struct gsasldata *gsasl = entry;
(void)key;
(void)klen;
DEBUGASSERT(gsasl);
Curl_auth_gsasl_cleanup(gsasl);
free(gsasl);
}
struct gsasldata *Curl_auth_gsasl_get(struct connectdata *conn)
{
struct gsasldata *gsasl = Curl_conn_meta_get(conn, CURL_META_GSASL_CONN);
if(!gsasl) {
gsasl = calloc(1, sizeof(*gsasl));
if(!gsasl ||
Curl_conn_meta_set(conn, CURL_META_GSASL_CONN, gsasl, gsasl_conn_dtor))
return NULL;
}
return gsasl;
}
#endif
#ifdef USE_SPNEGO
static void nego_conn_dtor(void *key, size_t klen, void *entry)
{
struct negotiatedata *nego = entry;
(void)key;
(void)klen;
DEBUGASSERT(nego);
Curl_auth_cleanup_spnego(nego);
free(nego);
}
struct negotiatedata *Curl_auth_nego_get(struct connectdata *conn, bool proxy)
{
const char *key = proxy ? CURL_META_NEGO_PROXY_CONN :
CURL_META_NEGO_CONN;
struct negotiatedata *nego = Curl_conn_meta_get(conn, key);
if(!nego) {
nego = calloc(1, sizeof(*nego));
if(!nego ||
Curl_conn_meta_set(conn, key, nego, nego_conn_dtor))
return NULL;
}
return nego;
}
#endif