Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/extensions/auth/./../../../extensions/auth/nsAuthGSSAPI.cpp
Warning:line 233, 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-01-224014-2642839-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/glean/SecurityManagerSslMetrics.h"
23
24#include "nsAuthGSSAPI.h"
25
26#ifdef XP_MACOSX
27# include <Kerberos/Kerberos.h>
28#endif
29
30#ifdef XP_MACOSX
31typedef KLStatus (*KLCacheHasValidTickets_type)(KLPrincipal, KLKerberosVersion,
32 KLBoolean*, KLPrincipal*,
33 char**);
34#endif
35
36#if defined(HAVE_RES_NINIT1)
37# include <sys/types.h>
38# include <netinet/in.h>
39# include <arpa/nameser.h>
40# include <resolv.h>
41#endif
42
43using namespace mozilla;
44
45//-----------------------------------------------------------------------------
46
47// We define GSS_C_NT_HOSTBASED_SERVICE explicitly since it may be referenced
48// by by a different name depending on the implementation of gss but always
49// has the same value
50
51static gss_OID_desc gss_c_nt_hostbased_service = {
52 10, (void*)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
53
54static const char kNegotiateAuthGssLib[] = "network.negotiate-auth.gsslib";
55static const char kNegotiateAuthNativeImp[] =
56 "network.negotiate-auth.using-native-gsslib";
57
58static struct GSSFunction {
59 const char* str;
60 PRFuncPtr func;
61} gssFuncs[] = {{"gss_display_status", nullptr},
62 {"gss_init_sec_context", nullptr},
63 {"gss_indicate_mechs", nullptr},
64 {"gss_release_oid_set", nullptr},
65 {"gss_delete_sec_context", nullptr},
66 {"gss_import_name", nullptr},
67 {"gss_release_buffer", nullptr},
68 {"gss_release_name", nullptr},
69 {"gss_wrap", nullptr},
70 {"gss_unwrap", nullptr}};
71
72static bool gssNativeImp = true;
73static PRLibrary* gssLibrary = nullptr;
74
75#define gss_display_status_ptr((gss_display_status_type) * gssFuncs[0].func) ((gss_display_status_type) * gssFuncs[0].func)
76#define gss_init_sec_context_ptr((gss_init_sec_context_type) * gssFuncs[1].func) \
77 ((gss_init_sec_context_type) * gssFuncs[1].func)
78#define gss_indicate_mechs_ptr((gss_indicate_mechs_type) * gssFuncs[2].func) ((gss_indicate_mechs_type) * gssFuncs[2].func)
79#define gss_release_oid_set_ptr((gss_release_oid_set_type) * gssFuncs[3].func) ((gss_release_oid_set_type) * gssFuncs[3].func)
80#define gss_delete_sec_context_ptr((gss_delete_sec_context_type) * gssFuncs[4].func) \
81 ((gss_delete_sec_context_type) * gssFuncs[4].func)
82#define gss_import_name_ptr((gss_import_name_type) * gssFuncs[5].func) ((gss_import_name_type) * gssFuncs[5].func)
83#define gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func) ((gss_release_buffer_type) * gssFuncs[6].func)
84#define gss_release_name_ptr((gss_release_name_type) * gssFuncs[7].func) ((gss_release_name_type) * gssFuncs[7].func)
85#define gss_wrap_ptr((gss_wrap_type) * gssFuncs[8].func) ((gss_wrap_type) * gssFuncs[8].func)
86#define gss_unwrap_ptr((gss_unwrap_type) * gssFuncs[9].func) ((gss_unwrap_type) * gssFuncs[9].func)
87
88#ifdef XP_MACOSX
89static PRFuncPtr KLCacheHasValidTicketsPtr;
90# define KLCacheHasValidTickets_ptr \
91 ((KLCacheHasValidTickets_type) * KLCacheHasValidTicketsPtr)
92#endif
93
94static nsresult gssInit() {
95#ifdef XP_WIN
96 nsAutoString libPathU;
97 Preferences::GetString(kNegotiateAuthGssLib, libPathU);
98 NS_ConvertUTF16toUTF8 libPath(libPathU);
99#else
100 nsAutoCString libPath;
101 Preferences::GetCString(kNegotiateAuthGssLib, libPath);
102#endif
103 gssNativeImp = Preferences::GetBool(kNegotiateAuthNativeImp);
104
105 PRLibrary* lib = nullptr;
106
107 if (!libPath.IsEmpty()) {
108 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)
;
109 gssNativeImp = false;
110#ifdef XP_WIN
111 lib = LoadLibraryWithFlags(libPathU.get());
112#else
113 lib = LoadLibraryWithFlags(libPath.get());
114#endif
115 } else {
116#ifdef XP_WIN
117# ifdef _WIN64
118 constexpr auto kLibName = u"gssapi64.dll"_ns;
119# else
120 constexpr auto kLibName = u"gssapi32.dll"_ns;
121# endif
122
123 lib = LoadLibraryWithFlags(kLibName.get());
124#elif defined(__OpenBSD__)
125 /* OpenBSD doesn't register inter-library dependencies in basesystem
126 * libs therefor we need to load all the libraries gssapi depends on,
127 * in the correct order and with LD_GLOBAL for GSSAPI auth to work
128 * fine.
129 */
130
131 const char* const verLibNames[] = {
132 "libasn1.so", "libcrypto.so", "libroken.so", "libheimbase.so",
133 "libcom_err.so", "libkrb5.so", "libgssapi.so"};
134
135 PRLibSpec libSpec;
136 for (size_t i = 0; i < std::size(verLibNames); ++i) {
137 libSpec.type = PR_LibSpec_Pathname;
138 libSpec.value.pathname = verLibNames[i];
139 lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_GLOBAL0x4);
140 }
141
142#else
143
144 const char* const libNames[] = {"gss", "gssapi_krb5", "gssapi"};
145
146 const char* const verLibNames[] = {
147 "libgssapi_krb5.so.2", /* MIT - FC, Suse10, Debian */
148 "libgssapi.so.4", /* Heimdal - Suse10, MDK */
149 "libgssapi.so.1" /* Heimdal - Suse9, CITI - FC, MDK, Suse10*/
150 };
151
152 for (size_t i = 0; i < std::size(verLibNames) && !lib; ++i) {
153 lib = PR_LoadLibrary(verLibNames[i]);
154
155 /* The CITI libgssapi library calls exit() during
156 * initialization if it's not correctly configured. Try to
157 * ensure that we never use this library for our GSSAPI
158 * support, as its just a wrapper library, anyway.
159 * See Bugzilla #325433
160 */
161 if (lib && PR_FindFunctionSymbol(lib, "internal_krb5_gss_initialize") &&
162 PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
163 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)
;
164 PR_UnloadLibrary(lib);
165 lib = nullptr;
166 }
167 }
168
169 for (size_t i = 0; i < std::size(libNames) && !lib; ++i) {
170 char* libName = PR_GetLibraryName(nullptr, libNames[i]);
171 if (libName) {
172 lib = PR_LoadLibrary(libName);
173 PR_FreeLibraryName(libName);
174
175 if (lib && PR_FindFunctionSymbol(lib, "internal_krb5_gss_initialize") &&
176 PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
177 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)
;
178 PR_UnloadLibrary(lib);
179 lib = nullptr;
180 }
181 }
182 }
183#endif
184 }
185
186 if (!lib) {
187 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)
;
188 return NS_ERROR_FAILURE;
189 }
190
191 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)
;
192
193 for (auto& gssFunc : gssFuncs) {
194 gssFunc.func = PR_FindFunctionSymbol(lib, gssFunc.str);
195 if (!gssFunc.func) {
196 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)
;
197 PR_UnloadLibrary(lib);
198 return NS_ERROR_FAILURE;
199 }
200 }
201#ifdef XP_MACOSX
202 if (gssNativeImp && !(KLCacheHasValidTicketsPtr = PR_FindFunctionSymbol(
203 lib, "KLCacheHasValidTickets"))) {
204 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)
;
205 PR_UnloadLibrary(lib);
206 return NS_ERROR_FAILURE;
207 }
208#endif
209
210 gssLibrary = lib;
211 return NS_OK;
212}
213
214// Generate proper GSSAPI error messages from the major and
215// minor status codes.
216void LogGssError(OM_uint32 maj_stat, OM_uint32 min_stat, const char* prefix) {
217 if (!MOZ_LOG_TEST(gNegotiateLog, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gNegotiateLog,
LogLevel::Debug)), 0))
) {
218 return;
219 }
220
221 OM_uint32 new_stat;
222 OM_uint32 msg_ctx = 0;
223 gss_buffer_desc status1_string;
224 gss_buffer_desc status2_string;
225 OM_uint32 ret;
226 nsAutoCString errorStr;
227 errorStr.Assign(prefix);
228
229 if (!gssLibrary) return;
230
231 errorStr += ": ";
232 do {
233 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
234 GSS_C_NULL_OID((gss_OID)0), &msg_ctx, &status1_string);
235 errorStr.Append((const char*)status1_string.value, status1_string.length);
236 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&new_stat, &status1_string);
237
238 errorStr += '\n';
239 ret = gss_display_status_ptr((gss_display_status_type) * gssFuncs[0].func)(&new_stat, min_stat, GSS_C_MECH_CODE2,
240 GSS_C_NULL_OID((gss_OID)0), &msg_ctx, &status2_string);
241 errorStr.Append((const char*)status2_string.value, status2_string.length);
242 errorStr += '\n';
243 } while (!GSS_ERROR(ret)(ret & ((0377ul << 24) | (0377ul << 16))) && msg_ctx != 0);
244
245 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)
;
246}
247
248//-----------------------------------------------------------------------------
249
250nsAuthGSSAPI::nsAuthGSSAPI(pType package) : mServiceFlags(REQ_DEFAULT) {
251 OM_uint32 minstat;
252 OM_uint32 majstat;
253 gss_OID_set mech_set;
254 gss_OID item;
255
256 unsigned int i;
257 static gss_OID_desc gss_krb5_mech_oid_desc = {
258 9, (void*)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
259 static gss_OID_desc gss_spnego_mech_oid_desc = {
260 6, (void*)"\x2b\x06\x01\x05\x05\x02"};
261
262 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)
;
263
264 mComplete = false;
265
266 if (!gssLibrary && NS_FAILED(gssInit())((bool)(__builtin_expect(!!(NS_FAILED_impl(gssInit())), 0)))) return;
267
268 mCtx = GSS_C_NO_CONTEXT((gss_ctx_id_t)0);
269 mMechOID = &gss_krb5_mech_oid_desc;
270
271 // if the type is kerberos we accept it as default
272 // and exit
273
274 if (package == PACKAGE_TYPE_KERBEROS) return;
275
276 // Now, look at the list of supported mechanisms,
277 // if SPNEGO is found, then use it.
278 // Otherwise, set the desired mechanism to
279 // GSS_C_NO_OID and let the system try to use
280 // the default mechanism.
281 //
282 // Using Kerberos directly (instead of negotiating
283 // with SPNEGO) may work in some cases depending
284 // on how smart the server side is.
285
286 majstat = gss_indicate_mechs_ptr((gss_indicate_mechs_type) * gssFuncs[2].func)(&minstat, &mech_set);
287 if (GSS_ERROR(majstat)(majstat & ((0377ul << 24) | (0377ul << 16)))) return;
288
289 if (mech_set) {
290 for (i = 0; i < mech_set->count; i++) {
291 item = &mech_set->elements[i];
292 if (item->length == gss_spnego_mech_oid_desc.length &&
293 !memcmp(item->elements, gss_spnego_mech_oid_desc.elements,
294 item->length)) {
295 // ok, we found it
296 mMechOID = &gss_spnego_mech_oid_desc;
297 break;
298 }
299 }
300 gss_release_oid_set_ptr((gss_release_oid_set_type) * gssFuncs[3].func)(&minstat, &mech_set);
301 }
302}
303
304void nsAuthGSSAPI::Reset() {
305 if (gssLibrary && mCtx != GSS_C_NO_CONTEXT((gss_ctx_id_t)0)) {
306 OM_uint32 minor_status;
307 gss_delete_sec_context_ptr((gss_delete_sec_context_type) * gssFuncs[4].func)(&minor_status, &mCtx, GSS_C_NO_BUFFER((gss_buffer_t)0));
308 }
309 mCtx = GSS_C_NO_CONTEXT((gss_ctx_id_t)0);
310 mComplete = false;
311}
312
313/* static */
314void nsAuthGSSAPI::Shutdown() {
315 if (gssLibrary) {
316 PR_UnloadLibrary(gssLibrary);
317 gssLibrary = nullptr;
318 }
319}
320
321/* Limitations apply to this class's thread safety. See the header file */
322NS_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"
, 322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 322
); __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"
, 322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsAuthGSSAPI\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 322); __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"
, 322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 322
); __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"
, 322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsAuthGSSAPI\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 322); __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"
, 322); 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; }
323
324NS_IMETHODIMPnsresult
325nsAuthGSSAPI::Init(const nsACString& serviceName, uint32_t serviceFlags,
326 const nsAString& domain, const nsAString& username,
327 const nsAString& password) {
328 // we don't expect to be passed any user credentials
329 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", 330); MOZ_PretendNoReturn
(); } } while (0)
330 "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", 330); MOZ_PretendNoReturn
(); } } while (0)
;
331
332 // it's critial that the caller supply a service name to be used
333 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"
, 333); return NS_ERROR_INVALID_ARG; } } while (false)
;
334
335 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)
;
336
337 if (!gssLibrary) return NS_ERROR_NOT_INITIALIZED;
338
339 mServiceName = serviceName;
340 mServiceFlags = serviceFlags;
341
342 static bool sTelemetrySent = false;
343 if (!sTelemetrySent) {
344 mozilla::glean::security::ntlm_module_used.AccumulateSingleSample(
345 serviceFlags & nsIAuthModule::REQ_PROXY_AUTH
346 ? NTLM_MODULE_KERBEROS_PROXY
347 : NTLM_MODULE_KERBEROS_DIRECT);
348 sTelemetrySent = true;
349 }
350
351 return NS_OK;
352}
353
354NS_IMETHODIMPnsresult
355nsAuthGSSAPI::GetNextToken(const void* inToken, uint32_t inTokenLen,
356 void** outToken, uint32_t* outTokenLen) {
357 OM_uint32 major_status, minor_status;
358 OM_uint32 req_flags = 0;
359 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER{0, nullptr};
360 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER{0, nullptr};
361 gss_buffer_t in_token_ptr = GSS_C_NO_BUFFER((gss_buffer_t)0);
362 gss_name_t server;
363 nsAutoCString userbuf;
364 nsresult rv;
365
366 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)
;
367
368 if (!gssLibrary) return NS_ERROR_NOT_INITIALIZED;
369
370 // If they've called us again after we're complete, reset to start afresh.
371 if (mComplete) Reset();
372
373 if (mServiceFlags & REQ_DELEGATE) req_flags |= GSS_C_DELEG_FLAG1;
374
375 if (mServiceFlags & REQ_MUTUAL_AUTH) req_flags |= GSS_C_MUTUAL_FLAG2;
376
377 input_token.value = (void*)mServiceName.get();
378 input_token.length = mServiceName.Length() + 1;
379
380#if defined(HAVE_RES_NINIT1)
381 res_ninit__res_ninit(&_res(*__res_state()));
382#endif
383 major_status = gss_import_name_ptr((gss_import_name_type) * gssFuncs[5].func)(&minor_status, &input_token,
384 &gss_c_nt_hostbased_service, &server);
385 input_token.value = nullptr;
386 input_token.length = 0;
387 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
388 LogGssError(major_status, minor_status, "gss_import_name() failed");
389 return NS_ERROR_FAILURE;
390 }
391
392 if (inToken) {
393 input_token.length = inTokenLen;
394 input_token.value = (void*)inToken;
395 in_token_ptr = &input_token;
396 } else if (mCtx != GSS_C_NO_CONTEXT((gss_ctx_id_t)0)) {
397 // If there is no input token, then we are starting a new
398 // authentication sequence. If we have already initialized our
399 // security context, then we're in trouble because it means that the
400 // first sequence failed. We need to bail or else we might end up in
401 // an infinite loop.
402 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)
;
403 return NS_ERROR_UNEXPECTED;
404 }
405
406#if defined(XP_MACOSX)
407 // Suppress Kerberos prompts to get credentials. See bug 240643.
408 // We can only use Mac OS X specific kerb functions if we are using
409 // the native lib
410 KLBoolean found;
411 bool doingMailTask = mServiceName.Find("imap@") ||
412 mServiceName.Find("pop@") ||
413 mServiceName.Find("smtp@") || mServiceName.Find("ldap@");
414
415 if (!doingMailTask &&
416 (gssNativeImp &&
417 (KLCacheHasValidTickets_ptr(nullptr, kerberosVersion_V5, &found, nullptr,
418 nullptr) != klNoErr ||
419 !found))) {
420 major_status = GSS_S_FAILURE(13ul << 16);
421 minor_status = 0;
422 } else
423#endif /* XP_MACOSX */
424 major_status = gss_init_sec_context_ptr((gss_init_sec_context_type) * gssFuncs[1].func)(
425 &minor_status, GSS_C_NO_CREDENTIAL((gss_cred_id_t)0), &mCtx, server, mMechOID, req_flags,
426 GSS_C_INDEFINITE0xfffffffful, GSS_C_NO_CHANNEL_BINDINGS((gss_channel_bindings_t)0), in_token_ptr, nullptr,
427 &output_token, nullptr, nullptr);
428
429 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
430 LogGssError(major_status, minor_status, "gss_init_sec_context() failed");
431 Reset();
432 rv = NS_ERROR_FAILURE;
433 goto end;
434 }
435 if (major_status == GSS_S_COMPLETE0) {
436 // Mark ourselves as being complete, so that if we're called again
437 // we know to start afresh.
438 mComplete = true;
439 } else if (major_status == GSS_S_CONTINUE_NEEDED(1ul << (0 + 0))) {
440 //
441 // The important thing is that we do NOT reset the
442 // context here because it will be needed on the
443 // next call.
444 //
445 }
446
447 *outTokenLen = output_token.length;
448 if (output_token.length != 0) {
449 *outToken = moz_xmemdup(output_token.value, output_token.length);
450 } else {
451 *outToken = nullptr;
452 }
453
454 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
455
456 if (major_status == GSS_S_COMPLETE0) {
457 rv = NS_SUCCESS_AUTH_FINISHED;
458 } else {
459 rv = NS_OK;
460 }
461
462end:
463 gss_release_name_ptr((gss_release_name_type) * gssFuncs[7].func)(&minor_status, &server);
464
465 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)
466 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)
;
467 return rv;
468}
469
470NS_IMETHODIMPnsresult
471nsAuthGSSAPI::Unwrap(const void* inToken, uint32_t inTokenLen, void** outToken,
472 uint32_t* outTokenLen) {
473 OM_uint32 major_status, minor_status;
474
475 gss_buffer_desc input_token;
476 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER{0, nullptr};
477
478 input_token.value = (void*)inToken;
479 input_token.length = inTokenLen;
480
481 major_status = gss_unwrap_ptr((gss_unwrap_type) * gssFuncs[9].func)(&minor_status, mCtx, &input_token,
482 &output_token, nullptr, nullptr);
483 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
484 LogGssError(major_status, minor_status, "gss_unwrap() failed");
485 Reset();
486 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
487 return NS_ERROR_FAILURE;
488 }
489
490 *outTokenLen = output_token.length;
491
492 if (output_token.length) {
493 *outToken = moz_xmemdup(output_token.value, output_token.length);
494 } else {
495 *outToken = nullptr;
496 }
497
498 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
499
500 return NS_OK;
501}
502
503NS_IMETHODIMPnsresult
504nsAuthGSSAPI::Wrap(const void* inToken, uint32_t inTokenLen, bool confidential,
505 void** outToken, uint32_t* outTokenLen) {
506 OM_uint32 major_status, minor_status;
507
508 gss_buffer_desc input_token;
509 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER{0, nullptr};
510
511 input_token.value = (void*)inToken;
512 input_token.length = inTokenLen;
513
514 major_status =
515 gss_wrap_ptr((gss_wrap_type) * gssFuncs[8].func)(&minor_status, mCtx, confidential, GSS_C_QOP_DEFAULT0,
516 &input_token, nullptr, &output_token);
517
518 if (GSS_ERROR(major_status)(major_status & ((0377ul << 24) | (0377ul << 16
)))
) {
519 LogGssError(major_status, minor_status, "gss_wrap() failed");
520 Reset();
521 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
522 return NS_ERROR_FAILURE;
523 }
524
525 *outTokenLen = output_token.length;
526
527 /* it is not possible for output_token.length to be zero */
528 *outToken = moz_xmemdup(output_token.value, output_token.length);
529 gss_release_buffer_ptr((gss_release_buffer_type) * gssFuncs[6].func)(&minor_status, &output_token);
530
531 return NS_OK;
532}