113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Steve Holme, <steve_holme@hotmail.com>. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#include <curl/curl.h> 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci#include "vauth.h" 3013498266Sopenharmony_ci#include "urldata.h" 3113498266Sopenharmony_ci#include "strcase.h" 3213498266Sopenharmony_ci#include "curl_multibyte.h" 3313498266Sopenharmony_ci#include "curl_printf.h" 3413498266Sopenharmony_ci 3513498266Sopenharmony_ci/* The last #include files should be: */ 3613498266Sopenharmony_ci#include "curl_memory.h" 3713498266Sopenharmony_ci#include "memdebug.h" 3813498266Sopenharmony_ci 3913498266Sopenharmony_ci/* 4013498266Sopenharmony_ci * Curl_auth_build_spn() 4113498266Sopenharmony_ci * 4213498266Sopenharmony_ci * This is used to build a SPN string in the following formats: 4313498266Sopenharmony_ci * 4413498266Sopenharmony_ci * service/host@realm (Not currently used) 4513498266Sopenharmony_ci * service/host (Not used by GSS-API) 4613498266Sopenharmony_ci * service@realm (Not used by Windows SSPI) 4713498266Sopenharmony_ci * 4813498266Sopenharmony_ci * Parameters: 4913498266Sopenharmony_ci * 5013498266Sopenharmony_ci * service [in] - The service type such as http, smtp, pop or imap. 5113498266Sopenharmony_ci * host [in] - The host name. 5213498266Sopenharmony_ci * realm [in] - The realm. 5313498266Sopenharmony_ci * 5413498266Sopenharmony_ci * Returns a pointer to the newly allocated SPN. 5513498266Sopenharmony_ci */ 5613498266Sopenharmony_ci#if !defined(USE_WINDOWS_SSPI) 5713498266Sopenharmony_cichar *Curl_auth_build_spn(const char *service, const char *host, 5813498266Sopenharmony_ci const char *realm) 5913498266Sopenharmony_ci{ 6013498266Sopenharmony_ci char *spn = NULL; 6113498266Sopenharmony_ci 6213498266Sopenharmony_ci /* Generate our SPN */ 6313498266Sopenharmony_ci if(host && realm) 6413498266Sopenharmony_ci spn = aprintf("%s/%s@%s", service, host, realm); 6513498266Sopenharmony_ci else if(host) 6613498266Sopenharmony_ci spn = aprintf("%s/%s", service, host); 6713498266Sopenharmony_ci else if(realm) 6813498266Sopenharmony_ci spn = aprintf("%s@%s", service, realm); 6913498266Sopenharmony_ci 7013498266Sopenharmony_ci /* Return our newly allocated SPN */ 7113498266Sopenharmony_ci return spn; 7213498266Sopenharmony_ci} 7313498266Sopenharmony_ci#else 7413498266Sopenharmony_ciTCHAR *Curl_auth_build_spn(const char *service, const char *host, 7513498266Sopenharmony_ci const char *realm) 7613498266Sopenharmony_ci{ 7713498266Sopenharmony_ci char *utf8_spn = NULL; 7813498266Sopenharmony_ci TCHAR *tchar_spn = NULL; 7913498266Sopenharmony_ci TCHAR *dupe_tchar_spn = NULL; 8013498266Sopenharmony_ci 8113498266Sopenharmony_ci (void) realm; 8213498266Sopenharmony_ci 8313498266Sopenharmony_ci /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather 8413498266Sopenharmony_ci than doing this ourselves but the first is only available in Windows XP 8513498266Sopenharmony_ci and Windows Server 2003 and the latter is only available in Windows 2000 8613498266Sopenharmony_ci but not Windows95/98/ME or Windows NT4.0 unless the Active Directory 8713498266Sopenharmony_ci Client Extensions are installed. As such it is far simpler for us to 8813498266Sopenharmony_ci formulate the SPN instead. */ 8913498266Sopenharmony_ci 9013498266Sopenharmony_ci /* Generate our UTF8 based SPN */ 9113498266Sopenharmony_ci utf8_spn = aprintf("%s/%s", service, host); 9213498266Sopenharmony_ci if(!utf8_spn) 9313498266Sopenharmony_ci return NULL; 9413498266Sopenharmony_ci 9513498266Sopenharmony_ci /* Allocate and return a TCHAR based SPN. Since curlx_convert_UTF8_to_tchar 9613498266Sopenharmony_ci must be freed by curlx_unicodefree we'll dupe the result so that the 9713498266Sopenharmony_ci pointer this function returns can be normally free'd. */ 9813498266Sopenharmony_ci tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn); 9913498266Sopenharmony_ci free(utf8_spn); 10013498266Sopenharmony_ci if(!tchar_spn) 10113498266Sopenharmony_ci return NULL; 10213498266Sopenharmony_ci dupe_tchar_spn = _tcsdup(tchar_spn); 10313498266Sopenharmony_ci curlx_unicodefree(tchar_spn); 10413498266Sopenharmony_ci return dupe_tchar_spn; 10513498266Sopenharmony_ci} 10613498266Sopenharmony_ci#endif /* USE_WINDOWS_SSPI */ 10713498266Sopenharmony_ci 10813498266Sopenharmony_ci/* 10913498266Sopenharmony_ci * Curl_auth_user_contains_domain() 11013498266Sopenharmony_ci * 11113498266Sopenharmony_ci * This is used to test if the specified user contains a Windows domain name as 11213498266Sopenharmony_ci * follows: 11313498266Sopenharmony_ci * 11413498266Sopenharmony_ci * Domain\User (Down-level Logon Name) 11513498266Sopenharmony_ci * Domain/User (curl Down-level format - for compatibility with existing code) 11613498266Sopenharmony_ci * User@Domain (User Principal Name) 11713498266Sopenharmony_ci * 11813498266Sopenharmony_ci * Note: The user name may be empty when using a GSS-API library or Windows 11913498266Sopenharmony_ci * SSPI as the user and domain are either obtained from the credentials cache 12013498266Sopenharmony_ci * when using GSS-API or via the currently logged in user's credentials when 12113498266Sopenharmony_ci * using Windows SSPI. 12213498266Sopenharmony_ci * 12313498266Sopenharmony_ci * Parameters: 12413498266Sopenharmony_ci * 12513498266Sopenharmony_ci * user [in] - The user name. 12613498266Sopenharmony_ci * 12713498266Sopenharmony_ci * Returns TRUE on success; otherwise FALSE. 12813498266Sopenharmony_ci */ 12913498266Sopenharmony_cibool Curl_auth_user_contains_domain(const char *user) 13013498266Sopenharmony_ci{ 13113498266Sopenharmony_ci bool valid = FALSE; 13213498266Sopenharmony_ci 13313498266Sopenharmony_ci if(user && *user) { 13413498266Sopenharmony_ci /* Check we have a domain name or UPN present */ 13513498266Sopenharmony_ci char *p = strpbrk(user, "\\/@"); 13613498266Sopenharmony_ci 13713498266Sopenharmony_ci valid = (p != NULL && p > user && p < user + strlen(user) - 1 ? TRUE : 13813498266Sopenharmony_ci FALSE); 13913498266Sopenharmony_ci } 14013498266Sopenharmony_ci#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) 14113498266Sopenharmony_ci else 14213498266Sopenharmony_ci /* User and domain are obtained from the GSS-API credentials cache or the 14313498266Sopenharmony_ci currently logged in user from Windows */ 14413498266Sopenharmony_ci valid = TRUE; 14513498266Sopenharmony_ci#endif 14613498266Sopenharmony_ci 14713498266Sopenharmony_ci return valid; 14813498266Sopenharmony_ci} 14913498266Sopenharmony_ci 15013498266Sopenharmony_ci/* 15113498266Sopenharmony_ci * Curl_auth_ollowed_to_host() tells if authentication, cookies or other 15213498266Sopenharmony_ci * "sensitive data" can (still) be sent to this host. 15313498266Sopenharmony_ci */ 15413498266Sopenharmony_cibool Curl_auth_allowed_to_host(struct Curl_easy *data) 15513498266Sopenharmony_ci{ 15613498266Sopenharmony_ci struct connectdata *conn = data->conn; 15713498266Sopenharmony_ci return (!data->state.this_is_a_follow || 15813498266Sopenharmony_ci data->set.allow_auth_to_other_hosts || 15913498266Sopenharmony_ci (data->state.first_host && 16013498266Sopenharmony_ci strcasecompare(data->state.first_host, conn->host.name) && 16113498266Sopenharmony_ci (data->state.first_remote_port == conn->remote_port) && 16213498266Sopenharmony_ci (data->state.first_remote_protocol == conn->handler->protocol))); 16313498266Sopenharmony_ci} 164