1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 #ifndef nsHttpAuthCache_h__ 7 #define nsHttpAuthCache_h__ 8 9 #include "nsError.h" 10 #include "nsTArray.h" 11 #include "nsAutoPtr.h" 12 #include "nsClassHashtable.h" 13 #include "nsCOMPtr.h" 14 #include "nsHashKeys.h" 15 #include "nsStringFwd.h" 16 #include "nsIObserver.h" 17 18 namespace mozilla { 19 20 class OriginAttributesPattern; 21 22 namespace net { 23 24 struct nsHttpAuthPath { 25 struct nsHttpAuthPath *mNext; 26 char mPath[1]; 27 }; 28 29 //----------------------------------------------------------------------------- 30 // nsHttpAuthIdentity 31 //----------------------------------------------------------------------------- 32 33 class nsHttpAuthIdentity { 34 public: nsHttpAuthIdentity()35 nsHttpAuthIdentity() : mUser(nullptr), mPass(nullptr), mDomain(nullptr) {} nsHttpAuthIdentity(const char16_t * domain,const char16_t * user,const char16_t * password)36 nsHttpAuthIdentity(const char16_t *domain, const char16_t *user, 37 const char16_t *password) 38 : mUser(nullptr) { 39 DebugOnly<nsresult> rv = Set(domain, user, password); 40 MOZ_ASSERT(NS_SUCCEEDED(rv)); 41 } ~nsHttpAuthIdentity()42 ~nsHttpAuthIdentity() { Clear(); } 43 Domain()44 const char16_t *Domain() const { return mDomain; } User()45 const char16_t *User() const { return mUser; } Password()46 const char16_t *Password() const { return mPass; } 47 48 MOZ_MUST_USE nsresult Set(const char16_t *domain, const char16_t *user, 49 const char16_t *password); Set(const nsHttpAuthIdentity & other)50 MOZ_MUST_USE nsresult Set(const nsHttpAuthIdentity &other) { 51 return Set(other.mDomain, other.mUser, other.mPass); 52 } 53 void Clear(); 54 55 bool Equals(const nsHttpAuthIdentity &other) const; IsEmpty()56 bool IsEmpty() const { return !mUser; } 57 58 private: 59 // allocated as one contiguous blob, starting at mUser. 60 char16_t *mUser; 61 char16_t *mPass; 62 char16_t *mDomain; 63 }; 64 65 //----------------------------------------------------------------------------- 66 // nsHttpAuthEntry 67 //----------------------------------------------------------------------------- 68 69 class nsHttpAuthEntry { 70 public: Realm()71 const char *Realm() const { return mRealm; } Creds()72 const char *Creds() const { return mCreds; } Challenge()73 const char *Challenge() const { return mChallenge; } Domain()74 const char16_t *Domain() const { return mIdent.Domain(); } User()75 const char16_t *User() const { return mIdent.User(); } Pass()76 const char16_t *Pass() const { return mIdent.Password(); } RootPath()77 nsHttpAuthPath *RootPath() { return mRoot; } 78 Identity()79 const nsHttpAuthIdentity &Identity() const { return mIdent; } 80 81 MOZ_MUST_USE nsresult AddPath(const char *aPath); 82 83 nsCOMPtr<nsISupports> mMetaData; 84 85 private: nsHttpAuthEntry(const char * path,const char * realm,const char * creds,const char * challenge,const nsHttpAuthIdentity * ident,nsISupports * metadata)86 nsHttpAuthEntry(const char *path, const char *realm, const char *creds, 87 const char *challenge, const nsHttpAuthIdentity *ident, 88 nsISupports *metadata) 89 : mRoot(nullptr), mTail(nullptr), mRealm(nullptr) { 90 DebugOnly<nsresult> rv = 91 Set(path, realm, creds, challenge, ident, metadata); 92 MOZ_ASSERT(NS_SUCCEEDED(rv)); 93 } 94 ~nsHttpAuthEntry(); 95 96 MOZ_MUST_USE nsresult Set(const char *path, const char *realm, 97 const char *creds, const char *challenge, 98 const nsHttpAuthIdentity *ident, 99 nsISupports *metadata); 100 101 nsHttpAuthIdentity mIdent; 102 103 nsHttpAuthPath *mRoot; // root pointer 104 nsHttpAuthPath *mTail; // tail pointer 105 106 // allocated together in one blob, starting with mRealm. 107 char *mRealm; 108 char *mCreds; 109 char *mChallenge; 110 111 friend class nsHttpAuthNode; 112 friend class nsHttpAuthCache; 113 friend class nsAutoPtr<nsHttpAuthEntry>; // needs to call the destructor 114 }; 115 116 //----------------------------------------------------------------------------- 117 // nsHttpAuthNode 118 //----------------------------------------------------------------------------- 119 120 class nsHttpAuthNode { 121 private: 122 nsHttpAuthNode(); 123 ~nsHttpAuthNode(); 124 125 // path can be null, in which case we'll search for an entry 126 // with a null path. 127 nsHttpAuthEntry *LookupEntryByPath(const char *path); 128 129 // realm must not be null 130 nsHttpAuthEntry *LookupEntryByRealm(const char *realm); 131 132 // if a matching entry is found, then credentials will be changed. 133 MOZ_MUST_USE nsresult SetAuthEntry(const char *path, const char *realm, 134 const char *credentials, 135 const char *challenge, 136 const nsHttpAuthIdentity *ident, 137 nsISupports *metadata); 138 139 void ClearAuthEntry(const char *realm); 140 EntryCount()141 uint32_t EntryCount() { return mList.Length(); } 142 143 private: 144 nsTArray<nsAutoPtr<nsHttpAuthEntry> > mList; 145 146 friend class nsHttpAuthCache; 147 friend class nsAutoPtr<nsHttpAuthNode>; // needs to call the destructor 148 }; 149 150 //----------------------------------------------------------------------------- 151 // nsHttpAuthCache 152 // (holds a hash table from host:port to nsHttpAuthNode) 153 //----------------------------------------------------------------------------- 154 155 class nsHttpAuthCache { 156 public: 157 nsHttpAuthCache(); 158 ~nsHttpAuthCache(); 159 160 // |scheme|, |host|, and |port| are required 161 // |path| can be null 162 // |entry| is either null or a weak reference 163 MOZ_MUST_USE nsresult GetAuthEntryForPath(const char *scheme, 164 const char *host, int32_t port, 165 const char *path, 166 nsACString const &originSuffix, 167 nsHttpAuthEntry **entry); 168 169 // |scheme|, |host|, and |port| are required 170 // |realm| must not be null 171 // |entry| is either null or a weak reference 172 MOZ_MUST_USE nsresult GetAuthEntryForDomain(const char *scheme, 173 const char *host, int32_t port, 174 const char *realm, 175 nsACString const &originSuffix, 176 nsHttpAuthEntry **entry); 177 178 // |scheme|, |host|, and |port| are required 179 // |path| can be null 180 // |realm| must not be null 181 // if |credentials|, |user|, |pass|, and |challenge| are each 182 // null, then the entry is deleted. 183 MOZ_MUST_USE nsresult SetAuthEntry(const char *scheme, const char *host, 184 int32_t port, const char *directory, 185 const char *realm, const char *credentials, 186 const char *challenge, 187 nsACString const &originSuffix, 188 const nsHttpAuthIdentity *ident, 189 nsISupports *metadata); 190 191 void ClearAuthEntry(const char *scheme, const char *host, int32_t port, 192 const char *realm, nsACString const &originSuffix); 193 194 // expire all existing auth list entries including proxy auths. 195 MOZ_MUST_USE nsresult ClearAll(); 196 197 private: 198 nsHttpAuthNode *LookupAuthNode(const char *scheme, const char *host, 199 int32_t port, nsACString const &originSuffix, 200 nsCString &key); 201 202 class OriginClearObserver : public nsIObserver { ~OriginClearObserver()203 virtual ~OriginClearObserver() {} 204 205 public: 206 NS_DECL_ISUPPORTS 207 NS_DECL_NSIOBSERVER OriginClearObserver(nsHttpAuthCache * aOwner)208 explicit OriginClearObserver(nsHttpAuthCache *aOwner) : mOwner(aOwner) {} 209 nsHttpAuthCache *mOwner; 210 }; 211 212 void ClearOriginData(OriginAttributesPattern const &pattern); 213 214 private: 215 using AuthNodeTable = nsClassHashtable<nsCStringHashKey, nsHttpAuthNode>; 216 AuthNodeTable mDB; // "host:port" --> nsHttpAuthNode 217 RefPtr<OriginClearObserver> mObserver; 218 }; 219 220 } // namespace net 221 } // namespace mozilla 222 223 #endif // nsHttpAuthCache_h__ 224