Bug Summary

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