1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Steve Holme, <[email protected]>.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
26*6236dae4SAndroid Build Coastguard Worker
27*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
28*6236dae4SAndroid Build Coastguard Worker
29*6236dae4SAndroid Build Coastguard Worker #include "vauth.h"
30*6236dae4SAndroid Build Coastguard Worker #include "urldata.h"
31*6236dae4SAndroid Build Coastguard Worker #include "strcase.h"
32*6236dae4SAndroid Build Coastguard Worker #include "curl_multibyte.h"
33*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
34*6236dae4SAndroid Build Coastguard Worker
35*6236dae4SAndroid Build Coastguard Worker /* The last #include files should be: */
36*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
37*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Worker /*
40*6236dae4SAndroid Build Coastguard Worker * Curl_auth_build_spn()
41*6236dae4SAndroid Build Coastguard Worker *
42*6236dae4SAndroid Build Coastguard Worker * This is used to build a SPN string in the following formats:
43*6236dae4SAndroid Build Coastguard Worker *
44*6236dae4SAndroid Build Coastguard Worker * service/host@realm (Not currently used)
45*6236dae4SAndroid Build Coastguard Worker * service/host (Not used by GSS-API)
46*6236dae4SAndroid Build Coastguard Worker * service@realm (Not used by Windows SSPI)
47*6236dae4SAndroid Build Coastguard Worker *
48*6236dae4SAndroid Build Coastguard Worker * Parameters:
49*6236dae4SAndroid Build Coastguard Worker *
50*6236dae4SAndroid Build Coastguard Worker * service [in] - The service type such as http, smtp, pop or imap.
51*6236dae4SAndroid Build Coastguard Worker * host [in] - The hostname.
52*6236dae4SAndroid Build Coastguard Worker * realm [in] - The realm.
53*6236dae4SAndroid Build Coastguard Worker *
54*6236dae4SAndroid Build Coastguard Worker * Returns a pointer to the newly allocated SPN.
55*6236dae4SAndroid Build Coastguard Worker */
56*6236dae4SAndroid Build Coastguard Worker #if !defined(USE_WINDOWS_SSPI)
Curl_auth_build_spn(const char * service,const char * host,const char * realm)57*6236dae4SAndroid Build Coastguard Worker char *Curl_auth_build_spn(const char *service, const char *host,
58*6236dae4SAndroid Build Coastguard Worker const char *realm)
59*6236dae4SAndroid Build Coastguard Worker {
60*6236dae4SAndroid Build Coastguard Worker char *spn = NULL;
61*6236dae4SAndroid Build Coastguard Worker
62*6236dae4SAndroid Build Coastguard Worker /* Generate our SPN */
63*6236dae4SAndroid Build Coastguard Worker if(host && realm)
64*6236dae4SAndroid Build Coastguard Worker spn = aprintf("%s/%s@%s", service, host, realm);
65*6236dae4SAndroid Build Coastguard Worker else if(host)
66*6236dae4SAndroid Build Coastguard Worker spn = aprintf("%s/%s", service, host);
67*6236dae4SAndroid Build Coastguard Worker else if(realm)
68*6236dae4SAndroid Build Coastguard Worker spn = aprintf("%s@%s", service, realm);
69*6236dae4SAndroid Build Coastguard Worker
70*6236dae4SAndroid Build Coastguard Worker /* Return our newly allocated SPN */
71*6236dae4SAndroid Build Coastguard Worker return spn;
72*6236dae4SAndroid Build Coastguard Worker }
73*6236dae4SAndroid Build Coastguard Worker #else
Curl_auth_build_spn(const char * service,const char * host,const char * realm)74*6236dae4SAndroid Build Coastguard Worker TCHAR *Curl_auth_build_spn(const char *service, const char *host,
75*6236dae4SAndroid Build Coastguard Worker const char *realm)
76*6236dae4SAndroid Build Coastguard Worker {
77*6236dae4SAndroid Build Coastguard Worker char *utf8_spn = NULL;
78*6236dae4SAndroid Build Coastguard Worker TCHAR *tchar_spn = NULL;
79*6236dae4SAndroid Build Coastguard Worker TCHAR *dupe_tchar_spn = NULL;
80*6236dae4SAndroid Build Coastguard Worker
81*6236dae4SAndroid Build Coastguard Worker (void) realm;
82*6236dae4SAndroid Build Coastguard Worker
83*6236dae4SAndroid Build Coastguard Worker /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather
84*6236dae4SAndroid Build Coastguard Worker than doing this ourselves but the first is only available in Windows XP
85*6236dae4SAndroid Build Coastguard Worker and Windows Server 2003 and the latter is only available in Windows 2000
86*6236dae4SAndroid Build Coastguard Worker but not Windows95/98/ME or Windows NT4.0 unless the Active Directory
87*6236dae4SAndroid Build Coastguard Worker Client Extensions are installed. As such it is far simpler for us to
88*6236dae4SAndroid Build Coastguard Worker formulate the SPN instead. */
89*6236dae4SAndroid Build Coastguard Worker
90*6236dae4SAndroid Build Coastguard Worker /* Generate our UTF8 based SPN */
91*6236dae4SAndroid Build Coastguard Worker utf8_spn = aprintf("%s/%s", service, host);
92*6236dae4SAndroid Build Coastguard Worker if(!utf8_spn)
93*6236dae4SAndroid Build Coastguard Worker return NULL;
94*6236dae4SAndroid Build Coastguard Worker
95*6236dae4SAndroid Build Coastguard Worker /* Allocate and return a TCHAR based SPN. Since curlx_convert_UTF8_to_tchar
96*6236dae4SAndroid Build Coastguard Worker must be freed by curlx_unicodefree we will dupe the result so that the
97*6236dae4SAndroid Build Coastguard Worker pointer this function returns can be normally free'd. */
98*6236dae4SAndroid Build Coastguard Worker tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn);
99*6236dae4SAndroid Build Coastguard Worker free(utf8_spn);
100*6236dae4SAndroid Build Coastguard Worker if(!tchar_spn)
101*6236dae4SAndroid Build Coastguard Worker return NULL;
102*6236dae4SAndroid Build Coastguard Worker dupe_tchar_spn = _tcsdup(tchar_spn);
103*6236dae4SAndroid Build Coastguard Worker curlx_unicodefree(tchar_spn);
104*6236dae4SAndroid Build Coastguard Worker return dupe_tchar_spn;
105*6236dae4SAndroid Build Coastguard Worker }
106*6236dae4SAndroid Build Coastguard Worker #endif /* USE_WINDOWS_SSPI */
107*6236dae4SAndroid Build Coastguard Worker
108*6236dae4SAndroid Build Coastguard Worker /*
109*6236dae4SAndroid Build Coastguard Worker * Curl_auth_user_contains_domain()
110*6236dae4SAndroid Build Coastguard Worker *
111*6236dae4SAndroid Build Coastguard Worker * This is used to test if the specified user contains a Windows domain name as
112*6236dae4SAndroid Build Coastguard Worker * follows:
113*6236dae4SAndroid Build Coastguard Worker *
114*6236dae4SAndroid Build Coastguard Worker * Domain\User (Down-level Logon Name)
115*6236dae4SAndroid Build Coastguard Worker * Domain/User (curl Down-level format - for compatibility with existing code)
116*6236dae4SAndroid Build Coastguard Worker * User@Domain (User Principal Name)
117*6236dae4SAndroid Build Coastguard Worker *
118*6236dae4SAndroid Build Coastguard Worker * Note: The username may be empty when using a GSS-API library or Windows
119*6236dae4SAndroid Build Coastguard Worker * SSPI as the user and domain are either obtained from the credentials cache
120*6236dae4SAndroid Build Coastguard Worker * when using GSS-API or via the currently logged in user's credentials when
121*6236dae4SAndroid Build Coastguard Worker * using Windows SSPI.
122*6236dae4SAndroid Build Coastguard Worker *
123*6236dae4SAndroid Build Coastguard Worker * Parameters:
124*6236dae4SAndroid Build Coastguard Worker *
125*6236dae4SAndroid Build Coastguard Worker * user [in] - The username.
126*6236dae4SAndroid Build Coastguard Worker *
127*6236dae4SAndroid Build Coastguard Worker * Returns TRUE on success; otherwise FALSE.
128*6236dae4SAndroid Build Coastguard Worker */
Curl_auth_user_contains_domain(const char * user)129*6236dae4SAndroid Build Coastguard Worker bool Curl_auth_user_contains_domain(const char *user)
130*6236dae4SAndroid Build Coastguard Worker {
131*6236dae4SAndroid Build Coastguard Worker bool valid = FALSE;
132*6236dae4SAndroid Build Coastguard Worker
133*6236dae4SAndroid Build Coastguard Worker if(user && *user) {
134*6236dae4SAndroid Build Coastguard Worker /* Check we have a domain name or UPN present */
135*6236dae4SAndroid Build Coastguard Worker char *p = strpbrk(user, "\\/@");
136*6236dae4SAndroid Build Coastguard Worker
137*6236dae4SAndroid Build Coastguard Worker valid = (p != NULL && p > user && p < user + strlen(user) - 1);
138*6236dae4SAndroid Build Coastguard Worker }
139*6236dae4SAndroid Build Coastguard Worker #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
140*6236dae4SAndroid Build Coastguard Worker else
141*6236dae4SAndroid Build Coastguard Worker /* User and domain are obtained from the GSS-API credentials cache or the
142*6236dae4SAndroid Build Coastguard Worker currently logged in user from Windows */
143*6236dae4SAndroid Build Coastguard Worker valid = TRUE;
144*6236dae4SAndroid Build Coastguard Worker #endif
145*6236dae4SAndroid Build Coastguard Worker
146*6236dae4SAndroid Build Coastguard Worker return valid;
147*6236dae4SAndroid Build Coastguard Worker }
148*6236dae4SAndroid Build Coastguard Worker
149*6236dae4SAndroid Build Coastguard Worker /*
150*6236dae4SAndroid Build Coastguard Worker * Curl_auth_ollowed_to_host() tells if authentication, cookies or other
151*6236dae4SAndroid Build Coastguard Worker * "sensitive data" can (still) be sent to this host.
152*6236dae4SAndroid Build Coastguard Worker */
Curl_auth_allowed_to_host(struct Curl_easy * data)153*6236dae4SAndroid Build Coastguard Worker bool Curl_auth_allowed_to_host(struct Curl_easy *data)
154*6236dae4SAndroid Build Coastguard Worker {
155*6236dae4SAndroid Build Coastguard Worker struct connectdata *conn = data->conn;
156*6236dae4SAndroid Build Coastguard Worker return (!data->state.this_is_a_follow ||
157*6236dae4SAndroid Build Coastguard Worker data->set.allow_auth_to_other_hosts ||
158*6236dae4SAndroid Build Coastguard Worker (data->state.first_host &&
159*6236dae4SAndroid Build Coastguard Worker strcasecompare(data->state.first_host, conn->host.name) &&
160*6236dae4SAndroid Build Coastguard Worker (data->state.first_remote_port == conn->remote_port) &&
161*6236dae4SAndroid Build Coastguard Worker (data->state.first_remote_protocol == conn->handler->protocol)));
162*6236dae4SAndroid Build Coastguard Worker }
163