michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef __NSCERTOVERRIDESERVICE_H__ michael@0: #define __NSCERTOVERRIDESERVICE_H__ michael@0: michael@0: #include "mozilla/ReentrantMonitor.h" michael@0: #include "nsICertOverrideService.h" michael@0: #include "nsTHashtable.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsString.h" michael@0: #include "nsIFile.h" michael@0: #include "secoidt.h" michael@0: #include "nsWeakReference.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: class nsCertOverride michael@0: { michael@0: public: michael@0: michael@0: enum OverrideBits { ob_None=0, ob_Untrusted=1, ob_Mismatch=2, michael@0: ob_Time_error=4 }; michael@0: michael@0: nsCertOverride() michael@0: :mPort(-1) michael@0: ,mOverrideBits(ob_None) michael@0: { michael@0: } michael@0: michael@0: nsCertOverride(const nsCertOverride &other) michael@0: { michael@0: this->operator=(other); michael@0: } michael@0: michael@0: nsCertOverride &operator=(const nsCertOverride &other) michael@0: { michael@0: mAsciiHost = other.mAsciiHost; michael@0: mPort = other.mPort; michael@0: mIsTemporary = other.mIsTemporary; michael@0: mFingerprintAlgOID = other.mFingerprintAlgOID; michael@0: mFingerprint = other.mFingerprint; michael@0: mOverrideBits = other.mOverrideBits; michael@0: mDBKey = other.mDBKey; michael@0: mCert = other.mCert; michael@0: return *this; michael@0: } michael@0: michael@0: nsCString mAsciiHost; michael@0: int32_t mPort; michael@0: bool mIsTemporary; // true: session only, false: stored on disk michael@0: nsCString mFingerprint; michael@0: nsCString mFingerprintAlgOID; michael@0: OverrideBits mOverrideBits; michael@0: nsCString mDBKey; michael@0: nsCOMPtr mCert; michael@0: michael@0: static void convertBitsToString(OverrideBits ob, nsACString &str); michael@0: static void convertStringToBits(const nsACString &str, OverrideBits &ob); michael@0: }; michael@0: michael@0: michael@0: // hash entry class michael@0: class nsCertOverrideEntry MOZ_FINAL : public PLDHashEntryHdr michael@0: { michael@0: public: michael@0: // Hash methods michael@0: typedef const char* KeyType; michael@0: typedef const char* KeyTypePointer; michael@0: michael@0: // do nothing with aHost - we require mHead to be set before we're live! michael@0: nsCertOverrideEntry(KeyTypePointer aHostWithPortUTF8) michael@0: { michael@0: } michael@0: michael@0: nsCertOverrideEntry(const nsCertOverrideEntry& toCopy) michael@0: { michael@0: mSettings = toCopy.mSettings; michael@0: mHostWithPort = toCopy.mHostWithPort; michael@0: } michael@0: michael@0: ~nsCertOverrideEntry() michael@0: { michael@0: } michael@0: michael@0: KeyType GetKey() const michael@0: { michael@0: return HostWithPortPtr(); michael@0: } michael@0: michael@0: KeyTypePointer GetKeyPointer() const michael@0: { michael@0: return HostWithPortPtr(); michael@0: } michael@0: michael@0: bool KeyEquals(KeyTypePointer aKey) const michael@0: { michael@0: return !strcmp(HostWithPortPtr(), aKey); michael@0: } michael@0: michael@0: static KeyTypePointer KeyToPointer(KeyType aKey) michael@0: { michael@0: return aKey; michael@0: } michael@0: michael@0: static PLDHashNumber HashKey(KeyTypePointer aKey) michael@0: { michael@0: // PL_DHashStringKey doesn't use the table parameter, so we can safely michael@0: // pass nullptr michael@0: return PL_DHashStringKey(nullptr, aKey); michael@0: } michael@0: michael@0: enum { ALLOW_MEMMOVE = false }; michael@0: michael@0: // get methods michael@0: inline const nsCString &HostWithPort() const { return mHostWithPort; } michael@0: michael@0: inline KeyTypePointer HostWithPortPtr() const michael@0: { michael@0: return mHostWithPort.get(); michael@0: } michael@0: michael@0: nsCertOverride mSettings; michael@0: nsCString mHostWithPort; michael@0: }; michael@0: michael@0: class nsCertOverrideService MOZ_FINAL : public nsICertOverrideService michael@0: , public nsIObserver michael@0: , public nsSupportsWeakReference michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSICERTOVERRIDESERVICE michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: nsCertOverrideService(); michael@0: ~nsCertOverrideService(); michael@0: michael@0: nsresult Init(); michael@0: void RemoveAllTemporaryOverrides(); michael@0: michael@0: typedef void michael@0: (*CertOverrideEnumerator)(const nsCertOverride &aSettings, michael@0: void *aUserData); michael@0: michael@0: // aCert == null: return all overrides michael@0: // aCert != null: return overrides that match the given cert michael@0: nsresult EnumerateCertOverrides(nsIX509Cert *aCert, michael@0: CertOverrideEnumerator enumerator, michael@0: void *aUserData); michael@0: michael@0: // Concates host name and the port number. If the port number is -1 then michael@0: // port 443 is automatically used. This method ensures there is always a port michael@0: // number separated with colon. michael@0: static void GetHostWithPort(const nsACString & aHostName, int32_t aPort, nsACString& _retval); michael@0: michael@0: protected: michael@0: mozilla::ReentrantMonitor monitor; michael@0: nsCOMPtr mSettingsFile; michael@0: nsTHashtable mSettingsTable; michael@0: michael@0: SECOidTag mOidTagForStoringNewHashes; michael@0: nsCString mDottedOidForStoringNewHashes; michael@0: michael@0: void RemoveAllFromMemory(); michael@0: nsresult Read(); michael@0: nsresult Write(); michael@0: nsresult AddEntryToList(const nsACString &host, int32_t port, michael@0: nsIX509Cert *aCert, michael@0: const bool aIsTemporary, michael@0: const nsACString &algo_oid, michael@0: const nsACString &fingerprint, michael@0: nsCertOverride::OverrideBits ob, michael@0: const nsACString &dbKey); michael@0: }; michael@0: michael@0: #define NS_CERTOVERRIDE_CID { /* 67ba681d-5485-4fff-952c-2ee337ffdcd6 */ \ michael@0: 0x67ba681d, \ michael@0: 0x5485, \ michael@0: 0x4fff, \ michael@0: {0x95, 0x2c, 0x2e, 0xe3, 0x37, 0xff, 0xdc, 0xd6} \ michael@0: } michael@0: michael@0: #endif