michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef NSPROMPTUTILS_H_ michael@0: #define NSPROMPTUTILS_H_ michael@0: michael@0: #include "nsIHttpChannel.h" michael@0: michael@0: /** michael@0: * @file michael@0: * This file defines some helper functions that simplify interaction michael@0: * with authentication prompts. michael@0: */ michael@0: michael@0: /** michael@0: * Given a username (possibly in DOMAIN\user form) and password, parses the michael@0: * domain out of the username if necessary and sets domain, username and michael@0: * password on the auth information object. michael@0: */ michael@0: inline void michael@0: NS_SetAuthInfo(nsIAuthInformation* aAuthInfo, const nsString& user, michael@0: const nsString& password) michael@0: { michael@0: uint32_t flags; michael@0: aAuthInfo->GetFlags(&flags); michael@0: if (flags & nsIAuthInformation::NEED_DOMAIN) { michael@0: // Domain is separated from username by a backslash michael@0: int32_t idx = user.FindChar(char16_t('\\')); michael@0: if (idx == kNotFound) { michael@0: aAuthInfo->SetUsername(user); michael@0: } else { michael@0: aAuthInfo->SetDomain(Substring(user, 0, idx)); michael@0: aAuthInfo->SetUsername(Substring(user, idx + 1)); michael@0: } michael@0: } else { michael@0: aAuthInfo->SetUsername(user); michael@0: } michael@0: aAuthInfo->SetPassword(password); michael@0: } michael@0: michael@0: /** michael@0: * Gets the host and port from a channel and authentication info. This is the michael@0: * "logical" host and port for this authentication, i.e. for a proxy michael@0: * authentication it refers to the proxy, while for a host authentication it michael@0: * is the actual host. michael@0: * michael@0: * @param machineProcessing michael@0: * When this parameter is true, the host will be returned in ASCII michael@0: * (instead of UTF-8; this is relevant when IDN is used). In addition, michael@0: * the port will be returned as the real port even when it was not michael@0: * explicitly specified (when false, the port will be returned as -1 in michael@0: * this case) michael@0: */ michael@0: inline void michael@0: NS_GetAuthHostPort(nsIChannel* aChannel, nsIAuthInformation* aAuthInfo, michael@0: bool machineProcessing, nsCString& host, int32_t* port) michael@0: { michael@0: nsCOMPtr uri; michael@0: nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); michael@0: if (NS_FAILED(rv)) michael@0: return; michael@0: michael@0: // Have to distinguish proxy auth and host auth here... michael@0: uint32_t flags; michael@0: aAuthInfo->GetFlags(&flags); michael@0: if (flags & nsIAuthInformation::AUTH_PROXY) { michael@0: nsCOMPtr proxied(do_QueryInterface(aChannel)); michael@0: NS_ASSERTION(proxied, "proxy auth needs nsIProxiedChannel"); michael@0: michael@0: nsCOMPtr info; michael@0: proxied->GetProxyInfo(getter_AddRefs(info)); michael@0: NS_ASSERTION(info, "proxy auth needs nsIProxyInfo"); michael@0: michael@0: nsAutoCString idnhost; michael@0: info->GetHost(idnhost); michael@0: info->GetPort(port); michael@0: michael@0: if (machineProcessing) { michael@0: nsCOMPtr idnService = michael@0: do_GetService(NS_IDNSERVICE_CONTRACTID); michael@0: if (idnService) { michael@0: idnService->ConvertUTF8toACE(idnhost, host); michael@0: } else { michael@0: // Not much we can do here... michael@0: host = idnhost; michael@0: } michael@0: } else { michael@0: host = idnhost; michael@0: } michael@0: } else { michael@0: if (machineProcessing) { michael@0: uri->GetAsciiHost(host); michael@0: *port = NS_GetRealPort(uri); michael@0: } else { michael@0: uri->GetHost(host); michael@0: uri->GetPort(port); michael@0: } michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Creates the key for looking up passwords in the password manager. This michael@0: * function uses the same format that Gecko functions have always used, thus michael@0: * ensuring backwards compatibility. michael@0: */ michael@0: inline void michael@0: NS_GetAuthKey(nsIChannel* aChannel, nsIAuthInformation* aAuthInfo, michael@0: nsCString& key) michael@0: { michael@0: // HTTP does this differently from other protocols michael@0: nsCOMPtr http(do_QueryInterface(aChannel)); michael@0: if (!http) { michael@0: nsCOMPtr uri; michael@0: aChannel->GetURI(getter_AddRefs(uri)); michael@0: uri->GetPrePath(key); michael@0: return; michael@0: } michael@0: michael@0: // NOTE: For backwards-compatibility reasons, this must be the ASCII host. michael@0: nsCString host; michael@0: int32_t port = -1; michael@0: michael@0: NS_GetAuthHostPort(aChannel, aAuthInfo, true, host, &port); michael@0: michael@0: nsAutoString realm; michael@0: aAuthInfo->GetRealm(realm); michael@0: michael@0: // Now assemble the key: host:port (realm) michael@0: key.Append(host); michael@0: key.Append(':'); michael@0: key.AppendInt(port); michael@0: key.AppendLiteral(" ("); michael@0: AppendUTF16toUTF8(realm, key); michael@0: key.Append(')'); michael@0: } michael@0: michael@0: #endif michael@0: