Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r=alwu
[gecko.git] / extensions / auth / nsAuthSASL.cpp
blob9fcb2859a716aaf6b3b520a94465d504faaced6c
1 /* vim:set ts=4 sw=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/. */
6 #include "nsNativeCharsetUtils.h"
7 #include "nsIPrefService.h"
8 #include "nsServiceManagerUtils.h"
10 #include "nsAuthSASL.h"
12 static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
14 nsAuthSASL::nsAuthSASL() { mSASLReady = false; }
16 void nsAuthSASL::Reset() { mSASLReady = false; }
18 /* Limitations apply to this class's thread safety. See the header file */
19 NS_IMPL_ISUPPORTS(nsAuthSASL, nsIAuthModule)
21 NS_IMETHODIMP
22 nsAuthSASL::Init(const nsACString& serviceName, uint32_t serviceFlags,
23 const nsAString& domain, const nsAString& username,
24 const nsAString& password) {
25 nsresult rv;
27 NS_ASSERTION(!username.IsEmpty(), "SASL requires a username");
28 NS_ASSERTION(domain.IsEmpty() && password.IsEmpty(),
29 "unexpected credentials");
31 mUsername = username;
33 // If we're doing SASL, we should do mutual auth
34 serviceFlags |= REQ_MUTUAL_AUTH;
36 // Find out whether we should be trying SSPI or not
37 const char* authType = "kerb-gss";
39 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
40 if (prefs) {
41 bool val;
42 rv = prefs->GetBoolPref(kNegotiateAuthSSPI, &val);
43 if (NS_SUCCEEDED(rv) && val) authType = "kerb-sspi";
46 MOZ_ALWAYS_TRUE(mInnerModule = nsIAuthModule::CreateInstance(authType));
48 mInnerModule->Init(serviceName, serviceFlags, u""_ns, u""_ns, u""_ns);
50 return NS_OK;
53 NS_IMETHODIMP
54 nsAuthSASL::GetNextToken(const void* inToken, uint32_t inTokenLen,
55 void** outToken, uint32_t* outTokenLen) {
56 nsresult rv;
57 void* unwrappedToken;
58 char* message;
59 uint32_t unwrappedTokenLen, messageLen;
60 nsAutoCString userbuf;
62 if (!mInnerModule) return NS_ERROR_NOT_INITIALIZED;
64 if (mSASLReady) {
65 // If the server COMPLETEs with an empty token, Cyrus sends us that token.
66 // I don't think this is correct, but we need to handle that behaviour.
67 // Cyrus ignores the contents of our reply token.
68 if (inTokenLen == 0) {
69 *outToken = nullptr;
70 *outTokenLen = 0;
71 return NS_OK;
73 // We've completed the GSSAPI portion of the handshake, and are
74 // now ready to do the SASL security layer and authzid negotiation
76 // Input packet from the server needs to be unwrapped.
77 rv = mInnerModule->Unwrap(inToken, inTokenLen, &unwrappedToken,
78 &unwrappedTokenLen);
79 if (NS_FAILED(rv)) {
80 Reset();
81 return rv;
84 // If we were doing security layers then we'd care what the
85 // server had sent us. We're not, so all we had to do was make
86 // sure that the signature was correct with the above unwrap()
87 free(unwrappedToken);
89 NS_CopyUnicodeToNative(mUsername, userbuf);
90 messageLen = userbuf.Length() + 4 + 1;
91 message = (char*)moz_xmalloc(messageLen);
92 message[0] = 0x01; // No security layer
93 message[1] = 0x00;
94 message[2] = 0x00;
95 message[3] = 0x00; // Maxbuf must be zero if we've got no sec layer
96 strcpy(message + 4, userbuf.get());
97 // Userbuf should not be nullptr terminated, so trim the trailing nullptr
98 // when wrapping the message
99 rv = mInnerModule->Wrap((void*)message, messageLen - 1, false, outToken,
100 outTokenLen);
101 free(message);
102 Reset(); // All done
103 return NS_SUCCEEDED(rv) ? NS_SUCCESS_AUTH_FINISHED : rv;
105 rv = mInnerModule->GetNextToken(inToken, inTokenLen, outToken, outTokenLen);
106 if (rv == NS_SUCCESS_AUTH_FINISHED) {
107 mSASLReady = true;
108 rv = NS_OK;
110 return rv;
113 NS_IMETHODIMP
114 nsAuthSASL::Unwrap(const void* inToken, uint32_t inTokenLen, void** outToken,
115 uint32_t* outTokenLen) {
116 return NS_ERROR_NOT_IMPLEMENTED;
119 NS_IMETHODIMP
120 nsAuthSASL::Wrap(const void* inToken, uint32_t inTokenLen, bool confidential,
121 void** outToken, uint32_t* outTokenLen) {
122 return NS_ERROR_NOT_IMPLEMENTED;