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
)
22 nsAuthSASL::Init(const nsACString
& serviceName
, uint32_t serviceFlags
,
23 const nsAString
& domain
, const nsAString
& username
,
24 const nsAString
& password
) {
27 NS_ASSERTION(!username
.IsEmpty(), "SASL requires a username");
28 NS_ASSERTION(domain
.IsEmpty() && password
.IsEmpty(),
29 "unexpected credentials");
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
);
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
);
54 nsAuthSASL::GetNextToken(const void* inToken
, uint32_t inTokenLen
,
55 void** outToken
, uint32_t* outTokenLen
) {
59 uint32_t unwrappedTokenLen
, messageLen
;
60 nsAutoCString userbuf
;
62 if (!mInnerModule
) return NS_ERROR_NOT_INITIALIZED
;
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) {
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
,
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()
89 NS_CopyUnicodeToNative(mUsername
, userbuf
);
90 messageLen
= userbuf
.Length() + 4 + 1;
91 message
= (char*)moz_xmalloc(messageLen
);
92 message
[0] = 0x01; // No security layer
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
,
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
) {
114 nsAuthSASL::Unwrap(const void* inToken
, uint32_t inTokenLen
, void** outToken
,
115 uint32_t* outTokenLen
) {
116 return NS_ERROR_NOT_IMPLEMENTED
;
120 nsAuthSASL::Wrap(const void* inToken
, uint32_t inTokenLen
, bool confidential
,
121 void** outToken
, uint32_t* outTokenLen
) {
122 return NS_ERROR_NOT_IMPLEMENTED
;