/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
nsresult nsCertOverrideService::Init() { if (!NS_IsMainThread()) {
MOZ_ASSERT_UNREACHABLE("nsCertOverrideService initialized off main thread"); return NS_ERROR_NOT_SAME_THREAD;
}
// If we cannot add ourselves as a profile change observer, then we will not // attempt to read/write any settings file. Otherwise, we would end up // reading/writing the wrong settings file after a profile change. if (observerService) {
observerService->AddObserver(this, "last-pb-context-exited", false);
observerService->AddObserver(this, "profile-do-change", true); // simulate a profile change so we read the current profile's settings file
Observe(nullptr, "profile-do-change", nullptr);
}
return NS_OK;
}
NS_IMETHODIMP
nsCertOverrideService::Observe(nsISupports*, constchar* aTopic, const char16_t* aData) { if (!nsCRT::strcmp(aTopic, "profile-do-change")) { // The profile has already changed. // Now read from the new profile location. // we also need to update the cached file location
void nsCertOverrideService::RemoveAllTemporaryOverrides() {
MutexAutoLock lock(mMutex); bool removedAny = false; for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) {
nsCertOverrideEntry* entry = iter.Get(); if (entry->mSettings->mIsTemporary) {
iter.Remove();
removedAny = true;
}
} if (removedAny) {
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) {
os->NotifyObservers(nullptr, "net:cancel-all-connections", nullptr);
}
} // no need to write, as temporaries are never written to disk
}
staticconstchar sSHA256OIDString[] = "OID.2.16.840.1.101.3.4.2.1";
nsresult nsCertOverrideService::Read(const MutexAutoLock& aProofOfLock) {
mMutex.AssertCurrentThreadOwns(); // If we don't have a profile, then we won't try to read any settings file. if (!mSettingsFile) return NS_OK;
// Each line is of the form: // host:port:originAttributes \t sSHA256OIDString \t fingerprint \t // There may be some "bits" identifiers and "dbKey" after the `fingerprint` // field in 'fingerprint \t \t dbKey' format, but these are now ignored. // Lines that don't match this form are silently dropped.
while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) { if (buffer.IsEmpty() || buffer.First() == '#') { continue;
}
Tokenizer parser(buffer);
nsDependentCSubstring host; if (parser.CheckChar('[')) { // this is a IPv6 address if (!parser.ReadUntil(Tokenizer::Token::Char(']'), host) ||
host.Length() == 0 || !parser.CheckChar(':')) { continue;
}
} elseif (!parser.ReadUntil(Tokenizer::Token::Char(':'), host) ||
host.Length() == 0) { continue;
}
int32_t port = -1; if (!parser.ReadInteger(&port)) { continue;
}
OriginAttributes attributes; if (parser.CheckChar(':')) {
nsDependentCSubstring attributesString; if (!parser.ReadUntil(Tokenizer::Token::Whitespace(), attributesString) ||
!attributes.PopulateFromSuffix(attributesString)) { continue;
}
} elseif (!parser.CheckWhite()) { continue;
}
nsDependentCSubstring algorithm; if (!parser.ReadUntil(Tokenizer::Token::Whitespace(), algorithm) ||
algorithm != sSHA256OIDString) { continue;
}
nsDependentCSubstring fingerprint; if (!parser.ReadUntil(Tokenizer::Token::Whitespace(), fingerprint) ||
fingerprint.Length() == 0) { continue;
}
AddEntryToList(host, port, attributes, false, // not temporary
fingerprint, aProofOfLock);
}
// If we don't have any profile, then we won't try to write any file if (!mSettingsFile) { return NS_OK;
}
nsCString output;
staticconstchar kHeader[] = "# PSM Certificate Override Settings file" NS_LINEBREAK "# This is a generated file! Do not edit." NS_LINEBREAK;
/* see ::Read for file format */
output.Append(kHeader);
staticconstchar kTab[] = "\t"; for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) {
nsCertOverrideEntry* entry = iter.Get();
RefPtr<nsCertOverride> settings = entry->mSettings; if (settings->mIsTemporary) { continue;
}
output.Append(entry->mKeyString);
output.Append(kTab);
output.Append(sSHA256OIDString);
output.Append(kTab);
output.Append(settings->mFingerprint);
output.Append(kTab); // the "bits" string used to go here, but it no longer exists // the "\t dbKey" string used to go here, but it no longer exists
output.Append(NS_LINEBREAK);
}
// Make a clone of the file to pass to the WriterRunnable.
nsCOMPtr<nsIFile> file;
nsresult rv;
rv = mSettingsFile->Clone(getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRunnable> runnable = new WriterRunnable(this, output, file);
rv = mWriterTaskQueue->Dispatch(runnable.forget()); if (NS_FAILED(rv)) { return rv;
}
mPendingWriteCount++;
RefPtr<nsCertOverride> settings(
GetOverrideFor(aHostName, aPort, aOriginAttributes)); // If there is no corresponding override and the given OriginAttributes isn't // the default, try to look up an override using the default OriginAttributes. if (!settings && aOriginAttributes != OriginAttributes()) {
settings = GetOverrideFor(aHostName, aPort, OriginAttributes());
} if (!settings) { return NS_OK;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.