Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/extensions/auth/./../../../extensions/auth/nsAuthGSSAPI.cpp
Warning:line 231, column 5
Value stored to 'ret' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_extensions_auth0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/extensions/auth -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/extensions/auth -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/extensions/auth -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/extensions/auth -I /root/firefox-clang/netwerk/dns -I /root/firefox-clang/security/manager/ssl -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-12-101221-999933-1 -x c++ Unified_cpp_extensions_auth0.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5//
6// GSSAPI Authentication Support Module
7//
8// Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt
9// (formerly draft-brezak-spnego-http-04.txt)
10//
11// Also described here:
12// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp
13//
14//
15
16#include "mozilla/IntegerPrintfMacros.h"
17
18#include "nsCOMPtr.h"
19#include "nsNativeCharsetUtils.h"
20#include "mozilla/Preferences.h"
21#include "mozilla/SharedLibrary.h"
22#include "mozilla/StaticPrefs_network.h"
23#include "mozilla/glean/SecurityManagerSslMetrics.h"
24
25#include "nsAuthGSSAPI.h"
26
27#ifdef XP_MACOSX
28# include <Kerberos/Kerberos.h>
29#endif
30
31#ifdef XP_MACOSX
32typedef KLStatus (*KLCacheHasValidTickets_type)(KLPrincipal, KLKerberosVersion,
33 KLBoolean*, KLPrincipal*,
34 char**);
35#endif
36
37#if defined(HAVE_RES_NINIT1)
38# include <sys/types.h>
39# include <netinet/in.h>
40# include <arpa/nameser.h>
41# include <resolv.h>
42#endif
43
44using namespace mozilla;
45
46//-----------------------------------------------------------------------------
47
48// We define GSS_C_NT_HOSTBASED_SERVICE explicitly since it may be referenced
49// by by a different name depending on the implementation of gss but always
50// has the same value
51
52static gss_OID_desc gss_c_nt_hostbased_service = {
53 10, (void*)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
54
55static const char kNegotiateAuthGssLib[] = "network.negotiate-auth.gsslib";
56
57static struct GSSFunction {
58 const char* str;
59 PRFuncPtr func;
60} gssFuncs[] = {{"gss_display_status", nullptr},
61 {"gss_init_sec_context", nullptr},
62 {"gss_indicate_mechs", nullptr},
63 {"gss_release_oid_set", nullptr},
64 {"gss_delete_sec_context", nullptr},
65 {"gss_import_name", nullptr},
66 {"gss_release_buffer", nullptr},
67 {"gss_release_name", nullptr},
68 {"gss_wrap", nullptr},
69 {"gss_unwrap", nullptr}};
70
71static PRLibrary* gssLibrary = nullptr;
72
73#define gss_display_status_ptr((gss_display_status_type) * gssFuncs[0].func) ((gss_display_status_type) * gssFuncs[0].func)
74#define gss_init_sec_context_ptr((gss_init_sec_context_type) * gssFuncs[1].func) \
75 ((gss_init_sec_context_type) * gssFuncs[1].func)
76#define gss_indicate_mechs_ptr((gss_indicate_mechs_type) * gssFuncs[2].func) ((gss_indicate_mechs_type) * gssFuncs[2].func)
77#define gss_release_oid_set_ptr((gss_release_oid_set_type) * gssFuncs[3].func) ((gss_release_oid_set_type) * gssFuncs[3].func)
78#define gss_delete_sec_context_ptr((gss_delete_sec_context_type) * gssFuncs[4].func) \
79 ((gss_delete_sec_context_type) * gssFuncs[4].func)
80#define gss_import_name_ptr((gss_import_name_type) * gssFuncs[5].func) ((gss_import_name_type) * gssFuncs[5].func)
81#define gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func) ((gss_release_buffer_type) * gssFuncs[6].func)
82#define gss_release_name_ptr((gss_release_name_type) * gssFuncs[7].func) ((gss_release_name_type) * gssFuncs[7].func)
83#define gss_wrap_ptr((gss_wrap_type) * gssFuncs[8].func) ((gss_wrap_type) * gssFuncs[8].func)
84#define gss_unwrap_ptr((gss_unwrap_type) * gssFuncs[9].func) ((gss_unwrap_type) * gssFuncs[9].func)
85
86#ifdef XP_MACOSX
87static PRFuncPtr KLCacheHasValidTicketsPtr;
88# define KLCacheHasValidTickets_ptr \
89 ((KLCacheHasValidTickets_type) * KLCacheHasValidTicketsPtr)
90#endif
91
92static nsresult gssInit() {
93#ifdef XP_WIN
94 nsAutoString libPathU;
95 Preferences::GetString(kNegotiateAuthGssLib, libPathU);
96 NS_ConvertUTF16toUTF8 libPath(libPathU);
97#else
98 nsAutoCString libPath;
99 Preferences::GetCString(kNegotiateAuthGssLib, libPath);
100#endif
101
102 PRLibrary* lib = nullptr;
103
104 if (!libPath.IsEmpty()) {
105 LOG(("Attempting to load user specified library [%s]\n", libPath.get()))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Attempting to load user specified library [%s]\n"
, libPath.get()); } } while (0)
;
106#ifdef XP_WIN
107 lib = LoadLibraryWithFlags(libPathU.get());
108#else
109 lib = LoadLibraryWithFlags(libPath.get());
110#endif
111 } else {
112#ifdef XP_WIN
113# ifdef _WIN64
114 constexpr auto kLibName = u"gssapi64.dll"_ns;
115# else
116 constexpr auto kLibName = u"gssapi32.dll"_ns;
117# endif
118
119 lib = LoadLibraryWithFlags(kLibName.get());
120#elif defined(__OpenBSD__)
121 /* OpenBSD doesn't register inter-library dependencies in basesystem
122 * libs therefor we need to load all the libraries gssapi depends on,
123 * in the correct order and with LD_GLOBAL for GSSAPI auth to work
124 * fine.
125 */
126
127 const char* const verLibNames[] = {
128 "libasn1.so", "libcrypto.so", "libroken.so", "libheimbase.so",
129 "libcom_err.so", "libkrb5.so", "libgssapi.so"};
130
131 PRLibSpec libSpec;
132 for (size_t i = 0; i < std::size(verLibNames); ++i) {
133 libSpec.type = PR_LibSpec_Pathname;
134 libSpec.value.pathname = verLibNames[i];
135 lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_GLOBAL0x4);
136 }
137
138#else
139
140 const char* const libNames[] = {"gss", "gssapi_krb5", "gssapi"};
141
142 const char* const verLibNames[] = {
143 "libgssapi_krb5.so.2", /* MIT - FC, Suse10, Debian */
144 "libgssapi.so.4", /* Heimdal - Suse10, MDK */
145 "libgssapi.so.1" /* Heimdal - Suse9, CITI - FC, MDK, Suse10*/
146 };
147
148 for (size_t i = 0; i < std::size(verLibNames) && !lib; ++i) {
149 lib = PR_LoadLibrary(verLibNames[i]);
150
151 /* The CITI libgssapi library calls exit() during
152 * initialization if it's not correctly configured. Try to
153 * ensure that we never use this library for our GSSAPI
154 * support, as its just a wrapper library, anyway.
155 * See Bugzilla #325433
156 */
157 if (lib && PR_FindFunctionSymbol(lib, "internal_krb5_gss_initialize") &&
158 PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
159 LOG(("CITI libgssapi found, which calls exit(). Skipping\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "CITI libgssapi found, which calls exit(). Skipping\n"
); } } while (0)
;
160 PR_UnloadLibrary(lib);
161 lib = nullptr;
162 }
163 }
164
165 for (size_t i = 0; i < std::size(libNames) && !lib; ++i) {
166 char* libName = PR_GetLibraryName(nullptr, libNames[i]);
167 if (libName) {
168 lib = PR_LoadLibrary(libName);
169 PR_FreeLibraryName(libName);
170
171 if (lib && PR_FindFunctionSymbol(lib, "internal_krb5_gss_initialize") &&
172 PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
173 LOG(("CITI libgssapi found, which calls exit(). Skipping\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "CITI libgssapi found, which calls exit(). Skipping\n"
); } } while (0)
;
174 PR_UnloadLibrary(lib);
175 lib = nullptr;
176 }
177 }
178 }
179#endif
180 }
181
182 if (!lib) {
183 LOG(("Fail to load gssapi library\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Fail to load gssapi library\n"
); } } while (0)
;
184 return NS_ERROR_FAILURE;
185 }
186
187 LOG(("Attempting to load gss functions\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Attempting to load gss functions\n"
); } } while (0)
;
188
189 for (auto& gssFunc : gssFuncs) {
190 gssFunc.func = PR_FindFunctionSymbol(lib, gssFunc.str);
191 if (!gssFunc.func) {
192 LOG(("Fail to load %s function from gssapi library\n", gssFunc.str))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Fail to load %s function from gssapi library\n"
, gssFunc.str); } } while (0)
;
193 PR_UnloadLibrary(lib);
194 return NS_ERROR_FAILURE;
195 }
196 }
197#ifdef XP_MACOSX
198 if (libPath.IsEmpty() &&
199 StaticPrefs::network_negotiate_auth_using_native_gsslib() &&
200 !(KLCacheHasValidTicketsPtr =
201 PR_FindFunctionSymbol(lib, "KLCacheHasValidTickets"))) {
202 LOG(("Fail to load KLCacheHasValidTickets function from gssapi library\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Fail to load KLCacheHasValidTickets function from gssapi library\n"
); } } while (0)
;
203 PR_UnloadLibrary(lib);
204 return NS_ERROR_FAILURE;
205 }
206#endif
207
208 gssLibrary = lib;
209 return NS_OK;
210}
211
212// Generate proper GSSAPI error messages from the major and
213// minor status codes.
214void LogGssError(OM_uint32 maj_stat, OM_uint32 min_stat, const char* prefix) {
215 if (!MOZ_LOG_TEST(gNegotiateLog, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gNegotiateLog,
LogLevel::Debug)), 0))
) {
216 return;
217 }
218
219 OM_uint32 new_stat;
220 OM_uint32 msg_ctx = 0;
221 gss_buffer_desc status1_string;
222 gss_buffer_desc status2_string;
223 OM_uint32 ret;
224 nsAutoCString errorStr;
225 errorStr.Assign(prefix);
226
227 if (!gssLibrary) return;
228
229 errorStr += ": ";
230 do {
231 ret = gss_display_status_ptr((gss_display_status_type) * gssFuncs[0].func)(&new_stat, maj_stat, GSS_C_GSS_CODE1,
Value stored to 'ret' is never read
232 GSS_C_NULL_OID((gss_OID)0), &msg_ctx, &status1_string);
233 errorStr.Append((const char*)status1_string.value, status1_string.length);
234 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&new_stat, &status1_string);
235
236 errorStr += '\n';
237 ret = gss_display_status_ptr((gss_display_status_type) * gssFuncs[0].func)(&new_stat, min_stat, GSS_C_MECH_CODE2,
238 GSS_C_NULL_OID((gss_OID)0), &msg_ctx, &status2_string);
239 errorStr.Append((const char*)status2_string.value, status2_string.length);
240 errorStr += '\n';
241 } while (!GSS_ERROR(ret)(ret & ((0377ul << 24) | (0377ul << 16))) && msg_ctx != 0);
242
243 LOG(("%s\n", errorStr.get()))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "%s\n", errorStr.
get()); } } while (0)
;
244}
245
246//-----------------------------------------------------------------------------
247
248nsAuthGSSAPI::nsAuthGSSAPI(pType package) : mServiceFlags(REQ_DEFAULT) {
249 OM_uint32 minstat;
250 OM_uint32 majstat;
251 gss_OID_set mech_set;
252 gss_OID item;
253
254 unsigned int i;
255 static gss_OID_desc gss_krb5_mech_oid_desc = {
256 9, (void*)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
257 static gss_OID_desc gss_spnego_mech_oid_desc = {
258 6, (void*)"\x2b\x06\x01\x05\x05\x02"};
259
260 LOG(("entering nsAuthGSSAPI::nsAuthGSSAPI()\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "entering nsAuthGSSAPI::nsAuthGSSAPI()\n"
); } } while (0)
;
261
262 mComplete = false;
263
264 if (!gssLibrary && NS_FAILED(gssInit())((bool)(__builtin_expect(!!(NS_FAILED_impl(gssInit())), 0)))) return;
265
266 mCtx = GSS_C_NO_CONTEXT((gss_ctx_id_t)0);
267 mMechOID = &gss_krb5_mech_oid_desc;
268
269 // if the type is kerberos we accept it as default
270 // and exit
271
272 if (package == PACKAGE_TYPE_KERBEROS) return;
273
274 // Now, look at the list of supported mechanisms,
275 // if SPNEGO is found, then use it.
276 // Otherwise, set the desired mechanism to
277 // GSS_C_NO_OID and let the system try to use
278 // the default mechanism.
279 //
280 // Using Kerberos directly (instead of negotiating
281 // with SPNEGO) may work in some cases depending
282 // on how smart the server side is.
283
284 majstat = gss_indicate_mechs_ptr((gss_indicate_mechs_type) * gssFuncs[2].func)(&minstat, &mech_set);
285 if (GSS_ERROR(majstat)(majstat & ((0377ul << 24) | (0377ul << 16)))) return;
286
287 if (mech_set) {
288 for (i = 0; i < mech_set->count; i++) {
289 item = &mech_set->elements[i];
290 if (item->length == gss_spnego_mech_oid_desc.length &&
291 !memcmp(item->elements, gss_spnego_mech_oid_desc.elements,
292 item->length)) {
293 // ok, we found it
294 mMechOID = &gss_spnego_mech_oid_desc;
295 break;
296 }
297 }
298 gss_release_oid_set_ptr((gss_release_oid_set_type) * gssFuncs[3].func)(&minstat, &mech_set);
299 }
300}
301
302void nsAuthGSSAPI::Reset() {
303 if (gssLibrary && mCtx != GSS_C_NO_CONTEXT((gss_ctx_id_t)0)) {
304 OM_uint32 minor_status;
305 gss_delete_sec_context_ptr((gss_delete_sec_context_type) * gssFuncs[4].func)(&minor_status, &mCtx, GSS_C_NO_BUFFER((gss_buffer_t)0));
306 }
307 mCtx = GSS_C_NO_CONTEXT((gss_ctx_id_t)0);
308 mComplete = false;
309}
310
311/* static */
312void nsAuthGSSAPI::Shutdown() {
313 if (gssLibrary) {
314 PR_UnloadLibrary(gssLibrary);
315 gssLibrary = nullptr;
316 }
317}
318
319/* Limitations apply to this class's thread safety. See the header file */
320NS_IMPL_ISUPPORTS(nsAuthGSSAPI, nsIAuthModule)MozExternalRefCountType nsAuthGSSAPI::AddRef(void) { static_assert
(!std::is_destructible_v<nsAuthGSSAPI>, "Reference-counted class "
"nsAuthGSSAPI" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../extensions/auth/nsAuthGSSAPI.cpp"
, 320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 320
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsAuthGSSAPI" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsAuthGSSAPI" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"nsAuthGSSAPI\" != nullptr"
" (" "Must specify a name" ")", "./../../../extensions/auth/nsAuthGSSAPI.cpp"
, 320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsAuthGSSAPI\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 320); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("nsAuthGSSAPI" " not thread-safe"); nsrefcnt count = ++mRefCnt
; NS_LogAddRef((this), (count), ("nsAuthGSSAPI"), (uint32_t)(
sizeof(*this))); return count; } MozExternalRefCountType nsAuthGSSAPI
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "./../../../extensions/auth/nsAuthGSSAPI.cpp"
, 320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 320
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsAuthGSSAPI" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsAuthGSSAPI" != nullptr)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"nsAuthGSSAPI\" != nullptr"
" (" "Must specify a name" ")", "./../../../extensions/auth/nsAuthGSSAPI.cpp"
, 320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsAuthGSSAPI\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 320); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("nsAuthGSSAPI" " not thread-safe"); const char* const nametmp
= "nsAuthGSSAPI"; nsrefcnt count = --mRefCnt; NS_LogRelease(
(this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete
(this); return 0; } return count; } nsresult nsAuthGSSAPI::QueryInterface
(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../extensions/auth/nsAuthGSSAPI.cpp"
, 320); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsAuthGSSAPI, nsIAuthModule>, int32_t
( reinterpret_cast<char*>(static_cast<nsIAuthModule*
>((nsAuthGSSAPI*)0x1000)) - reinterpret_cast<char*>(
(nsAuthGSSAPI*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsAuthGSSAPI, nsISupports>, int32_t(reinterpret_cast<
char*>(static_cast<nsISupports*>( static_cast<nsIAuthModule
*>((nsAuthGSSAPI*)0x1000))) - reinterpret_cast<char*>
((nsAuthGSSAPI*)0x1000))}, { nullptr, 0 } } ; static_assert(std
::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
321
322NS_IMETHODIMPnsresult
323nsAuthGSSAPI::Init(const nsACString& serviceName, uint32_t serviceFlags,
324 const nsAString& domain, const nsAString& username,
325 const nsAString& password) {
326 // we don't expect to be passed any user credentials
327 NS_ASSERTION(domain.IsEmpty() && username.IsEmpty() && password.IsEmpty(),do { if (!(domain.IsEmpty() && username.IsEmpty() &&
password.IsEmpty())) { NS_DebugBreak(NS_DEBUG_ASSERTION, "unexpected credentials"
, "domain.IsEmpty() && username.IsEmpty() && password.IsEmpty()"
, "./../../../extensions/auth/nsAuthGSSAPI.cpp", 328); MOZ_PretendNoReturn
(); } } while (0)
328 "unexpected credentials")do { if (!(domain.IsEmpty() && username.IsEmpty() &&
password.IsEmpty())) { NS_DebugBreak(NS_DEBUG_ASSERTION, "unexpected credentials"
, "domain.IsEmpty() && username.IsEmpty() && password.IsEmpty()"
, "./../../../extensions/auth/nsAuthGSSAPI.cpp", 328); MOZ_PretendNoReturn
(); } } while (0)
;
329
330 // it's critial that the caller supply a service name to be used
331 NS_ENSURE_TRUE(!serviceName.IsEmpty(), NS_ERROR_INVALID_ARG)do { if ((__builtin_expect(!!(!(!serviceName.IsEmpty())), 0))
) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!serviceName.IsEmpty()"
") failed", nullptr, "./../../../extensions/auth/nsAuthGSSAPI.cpp"
, 331); return NS_ERROR_INVALID_ARG; } } while (false)
;
332
333 LOG(("entering nsAuthGSSAPI::Init()\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "entering nsAuthGSSAPI::Init()\n"
); } } while (0)
;
334
335 if (!gssLibrary) return NS_ERROR_NOT_INITIALIZED;
336
337 mServiceName = serviceName;
338 mServiceFlags = serviceFlags;
339
340 static bool sTelemetrySent = false;
341 if (!sTelemetrySent) {
342 mozilla::glean::security::ntlm_module_used.AccumulateSingleSample(
343 serviceFlags & nsIAuthModule::REQ_PROXY_AUTH
344 ? NTLM_MODULE_KERBEROS_PROXY
345 : NTLM_MODULE_KERBEROS_DIRECT);
346 sTelemetrySent = true;
347 }
348
349 return NS_OK;
350}
351
352NS_IMETHODIMPnsresult
353nsAuthGSSAPI::GetNextToken(const void* inToken, uint32_t inTokenLen,
354 void** outToken, uint32_t* outTokenLen) {
355 OM_uint32 major_status, minor_status;
356 OM_uint32 req_flags = 0;
357 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER{0, nullptr};
358 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER{0, nullptr};
359 gss_buffer_t in_token_ptr = GSS_C_NO_BUFFER((gss_buffer_t)0);
360 gss_name_t server;
361 nsAutoCString userbuf;
362 nsresult rv;
363
364 LOG(("entering nsAuthGSSAPI::GetNextToken()\n"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "entering nsAuthGSSAPI::GetNextToken()\n"
); } } while (0)
;
365
366 if (!gssLibrary) return NS_ERROR_NOT_INITIALIZED;
367
368 // If they've called us again after we're complete, reset to start afresh.
369 if (mComplete) Reset();
370
371 if (mServiceFlags & REQ_DELEGATE) req_flags |= GSS_C_DELEG_FLAG1;
372
373 if (mServiceFlags & REQ_MUTUAL_AUTH) req_flags |= GSS_C_MUTUAL_FLAG2;
374
375 input_token.value = (void*)mServiceName.get();
376 input_token.length = mServiceName.Length() + 1;
377
378#if defined(HAVE_RES_NINIT1)
379 res_ninit__res_ninit(&_res(*__res_state()));
380#endif
381 major_status = gss_import_name_ptr((gss_import_name_type) * gssFuncs[5].func)(&minor_status, &input_token,
382 &gss_c_nt_hostbased_service, &server);
383 input_token.value = nullptr;
384 input_token.length = 0;
385 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
386 LogGssError(major_status, minor_status, "gss_import_name() failed");
387 return NS_ERROR_FAILURE;
388 }
389
390 if (inToken) {
391 input_token.length = inTokenLen;
392 input_token.value = (void*)inToken;
393 in_token_ptr = &input_token;
394 } else if (mCtx != GSS_C_NO_CONTEXT((gss_ctx_id_t)0)) {
395 // If there is no input token, then we are starting a new
396 // authentication sequence. If we have already initialized our
397 // security context, then we're in trouble because it means that the
398 // first sequence failed. We need to bail or else we might end up in
399 // an infinite loop.
400 LOG(("Cannot restart authentication sequence!"))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, "Cannot restart authentication sequence!"
); } } while (0)
;
401 return NS_ERROR_UNEXPECTED;
402 }
403
404#if defined(XP_MACOSX)
405 // Suppress Kerberos prompts to get credentials. See bug 240643.
406 // We can only use Mac OS X specific kerb functions if we are using
407 // the native lib
408 KLBoolean found;
409 bool doingMailTask = mServiceName.Find("imap@") ||
410 mServiceName.Find("pop@") ||
411 mServiceName.Find("smtp@") || mServiceName.Find("ldap@");
412
413 if (!doingMailTask &&
414 (KLCacheHasValidTicketsPtr &&
415 (KLCacheHasValidTickets_ptr(nullptr, kerberosVersion_V5, &found, nullptr,
416 nullptr) != klNoErr ||
417 !found))) {
418 major_status = GSS_S_FAILURE(13ul << 16);
419 minor_status = 0;
420 } else
421#endif /* XP_MACOSX */
422 major_status = gss_init_sec_context_ptr((gss_init_sec_context_type) * gssFuncs[1].func)(
423 &minor_status, GSS_C_NO_CREDENTIAL((gss_cred_id_t)0), &mCtx, server, mMechOID, req_flags,
424 GSS_C_INDEFINITE0xfffffffful, GSS_C_NO_CHANNEL_BINDINGS((gss_channel_bindings_t)0), in_token_ptr, nullptr,
425 &output_token, nullptr, nullptr);
426
427 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
428 LogGssError(major_status, minor_status, "gss_init_sec_context() failed");
429 Reset();
430 rv = NS_ERROR_FAILURE;
431 goto end;
432 }
433 if (major_status == GSS_S_COMPLETE0) {
434 // Mark ourselves as being complete, so that if we're called again
435 // we know to start afresh.
436 mComplete = true;
437 } else if (major_status == GSS_S_CONTINUE_NEEDED(1ul << (0 + 0))) {
438 //
439 // The important thing is that we do NOT reset the
440 // context here because it will be needed on the
441 // next call.
442 //
443 }
444
445 *outTokenLen = output_token.length;
446 if (output_token.length != 0) {
447 *outToken = moz_xmemdup(output_token.value, output_token.length);
448 } else {
449 *outToken = nullptr;
450 }
451
452 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
453
454 if (major_status == GSS_S_COMPLETE0) {
455 rv = NS_SUCCESS_AUTH_FINISHED;
456 } else {
457 rv = NS_OK;
458 }
459
460end:
461 gss_release_name_ptr((gss_release_name_type) * gssFuncs[7].func)(&minor_status, &server);
462
463 LOG((" leaving nsAuthGSSAPI::GetNextToken [rv=%" PRIx32 "]",do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, " leaving nsAuthGSSAPI::GetNextToken [rv=%"
"x" "]", static_cast<uint32_t>(rv)); } } while (0)
464 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = gNegotiateLog
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print
(moz_real_module, mozilla::LogLevel::Debug, " leaving nsAuthGSSAPI::GetNextToken [rv=%"
"x" "]", static_cast<uint32_t>(rv)); } } while (0)
;
465 return rv;
466}
467
468NS_IMETHODIMPnsresult
469nsAuthGSSAPI::Unwrap(const void* inToken, uint32_t inTokenLen, void** outToken,
470 uint32_t* outTokenLen) {
471 OM_uint32 major_status, minor_status;
472
473 gss_buffer_desc input_token;
474 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER{0, nullptr};
475
476 input_token.value = (void*)inToken;
477 input_token.length = inTokenLen;
478
479 major_status = gss_unwrap_ptr((gss_unwrap_type) * gssFuncs[9].func)(&minor_status, mCtx, &input_token,
480 &output_token, nullptr, nullptr);
481 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
482 LogGssError(major_status, minor_status, "gss_unwrap() failed");
483 Reset();
484 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
485 return NS_ERROR_FAILURE;
486 }
487
488 *outTokenLen = output_token.length;
489
490 if (output_token.length) {
491 *outToken = moz_xmemdup(output_token.value, output_token.length);
492 } else {
493 *outToken = nullptr;
494 }
495
496 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
497
498 return NS_OK;
499}
500
501NS_IMETHODIMPnsresult
502nsAuthGSSAPI::Wrap(const void* inToken, uint32_t inTokenLen, bool confidential,
503 void** outToken, uint32_t* outTokenLen) {
504 OM_uint32 major_status, minor_status;
505
506 gss_buffer_desc input_token;
507 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER{0, nullptr};
508
509 input_token.value = (void*)inToken;
510 input_token.length = inTokenLen;
511
512 major_status =
513 gss_wrap_ptr((gss_wrap_type) * gssFuncs[8].func)(&minor_status, mCtx, confidential, GSS_C_QOP_DEFAULT0,
514 &input_token, nullptr, &output_token);
515
516 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
517 LogGssError(major_status, minor_status, "gss_wrap() failed");
518 Reset();
519 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
520 return NS_ERROR_FAILURE;
521 }
522
523 *outTokenLen = output_token.length;
524
525 /* it is not possible for output_token.length to be zero */
526 *outToken = moz_xmemdup(output_token.value, output_token.length);
527 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
528
529 return NS_OK;
530}