summaryrefslogtreecommitdiffstats
path: root/toolkit/components/url-classifier/ProtocolParser.h
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/url-classifier/ProtocolParser.h')
-rw-r--r--toolkit/components/url-classifier/ProtocolParser.h204
1 files changed, 204 insertions, 0 deletions
diff --git a/toolkit/components/url-classifier/ProtocolParser.h b/toolkit/components/url-classifier/ProtocolParser.h
new file mode 100644
index 000000000..ec1a695f4
--- /dev/null
+++ b/toolkit/components/url-classifier/ProtocolParser.h
@@ -0,0 +1,204 @@
+//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef ProtocolParser_h__
+#define ProtocolParser_h__
+
+#include "HashStore.h"
+#include "nsICryptoHMAC.h"
+#include "safebrowsing.pb.h"
+
+namespace mozilla {
+namespace safebrowsing {
+
+/**
+ * Abstract base class for parsing update data in multiple formats.
+ */
+class ProtocolParser {
+public:
+ struct ForwardedUpdate {
+ nsCString table;
+ nsCString url;
+ };
+
+ ProtocolParser();
+ virtual ~ProtocolParser();
+
+ nsresult Status() const { return mUpdateStatus; }
+
+ nsresult Init(nsICryptoHash* aHasher);
+
+#ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
+ nsCString GetRawTableUpdates() const { return mPending; }
+#endif
+
+ virtual void SetCurrentTable(const nsACString& aTable) = 0;
+
+ void SetRequestedTables(const nsTArray<nsCString>& aRequestTables)
+ {
+ mRequestedTables = aRequestTables;
+ }
+
+ nsresult Begin();
+ virtual nsresult AppendStream(const nsACString& aData) = 0;
+
+ uint32_t UpdateWaitSec() { return mUpdateWaitSec; }
+
+ // Notify that the inbound data is ready for parsing if progressive
+ // parsing is not supported, for example in V4.
+ virtual void End() = 0;
+
+ // Forget the table updates that were created by this pass. It
+ // becomes the caller's responsibility to free them. This is shitty.
+ TableUpdate *GetTableUpdate(const nsACString& aTable);
+ void ForgetTableUpdates() { mTableUpdates.Clear(); }
+ nsTArray<TableUpdate*> &GetTableUpdates() { return mTableUpdates; }
+
+ // These are only meaningful to V2. Since they were originally public,
+ // moving them to ProtocolParserV2 requires a dymamic cast in the call
+ // sites. As a result, we will leave them until we remove support
+ // for V2 entirely..
+ virtual const nsTArray<ForwardedUpdate> &Forwards() const { return mForwards; }
+ virtual bool ResetRequested() { return false; }
+
+protected:
+ virtual TableUpdate* CreateTableUpdate(const nsACString& aTableName) const = 0;
+
+ nsCString mPending;
+ nsresult mUpdateStatus;
+
+ // Keep track of updates to apply before passing them to the DBServiceWorkers.
+ nsTArray<TableUpdate*> mTableUpdates;
+
+ nsTArray<ForwardedUpdate> mForwards;
+ nsCOMPtr<nsICryptoHash> mCryptoHash;
+
+ // The table names that were requested from the client.
+ nsTArray<nsCString> mRequestedTables;
+
+ // How long we should wait until the next update.
+ uint32_t mUpdateWaitSec;
+
+private:
+ void CleanupUpdates();
+};
+
+/**
+ * Helpers to parse the "shavar", "digest256" and "simple" list formats.
+ */
+class ProtocolParserV2 final : public ProtocolParser {
+public:
+ ProtocolParserV2();
+ virtual ~ProtocolParserV2();
+
+ virtual void SetCurrentTable(const nsACString& aTable) override;
+ virtual nsresult AppendStream(const nsACString& aData) override;
+ virtual void End() override;
+
+ // Update information.
+ virtual const nsTArray<ForwardedUpdate> &Forwards() const override { return mForwards; }
+ virtual bool ResetRequested() override { return mResetRequested; }
+
+private:
+ virtual TableUpdate* CreateTableUpdate(const nsACString& aTableName) const override;
+
+ nsresult ProcessControl(bool* aDone);
+ nsresult ProcessExpirations(const nsCString& aLine);
+ nsresult ProcessChunkControl(const nsCString& aLine);
+ nsresult ProcessForward(const nsCString& aLine);
+ nsresult AddForward(const nsACString& aUrl);
+ nsresult ProcessChunk(bool* done);
+ // Remove this, it's only used for testing
+ nsresult ProcessPlaintextChunk(const nsACString& aChunk);
+ nsresult ProcessShaChunk(const nsACString& aChunk);
+ nsresult ProcessHostAdd(const Prefix& aDomain, uint8_t aNumEntries,
+ const nsACString& aChunk, uint32_t* aStart);
+ nsresult ProcessHostSub(const Prefix& aDomain, uint8_t aNumEntries,
+ const nsACString& aChunk, uint32_t* aStart);
+ nsresult ProcessHostAddComplete(uint8_t aNumEntries, const nsACString& aChunk,
+ uint32_t *aStart);
+ nsresult ProcessHostSubComplete(uint8_t numEntries, const nsACString& aChunk,
+ uint32_t* start);
+ // Digest chunks are very similar to shavar chunks, except digest chunks
+ // always contain the full hash, so there is no need for chunk data to
+ // contain prefix sizes.
+ nsresult ProcessDigestChunk(const nsACString& aChunk);
+ nsresult ProcessDigestAdd(const nsACString& aChunk);
+ nsresult ProcessDigestSub(const nsACString& aChunk);
+ bool NextLine(nsACString& aLine);
+
+ enum ParserState {
+ PROTOCOL_STATE_CONTROL,
+ PROTOCOL_STATE_CHUNK
+ };
+ ParserState mState;
+
+ enum ChunkType {
+ // Types for shavar tables.
+ CHUNK_ADD,
+ CHUNK_SUB,
+ // Types for digest256 tables. digest256 tables differ in format from
+ // shavar tables since they only contain complete hashes.
+ CHUNK_ADD_DIGEST,
+ CHUNK_SUB_DIGEST
+ };
+
+ struct ChunkState {
+ ChunkType type;
+ uint32_t num;
+ uint32_t hashSize;
+ uint32_t length;
+ void Clear() { num = 0; hashSize = 0; length = 0; }
+ };
+ ChunkState mChunkState;
+
+ bool mResetRequested;
+
+ // Updates to apply to the current table being parsed.
+ TableUpdateV2 *mTableUpdate;
+};
+
+// Helpers to parse the "proto" list format.
+class ProtocolParserProtobuf final : public ProtocolParser {
+public:
+ typedef FetchThreatListUpdatesResponse_ListUpdateResponse ListUpdateResponse;
+ typedef google::protobuf::RepeatedPtrField<ThreatEntrySet> ThreatEntrySetList;
+
+public:
+ ProtocolParserProtobuf();
+
+ virtual void SetCurrentTable(const nsACString& aTable) override;
+ virtual nsresult AppendStream(const nsACString& aData) override;
+ virtual void End() override;
+
+private:
+ virtual ~ProtocolParserProtobuf();
+
+ virtual TableUpdate* CreateTableUpdate(const nsACString& aTableName) const override;
+
+ // For parsing update info.
+ nsresult ProcessOneResponse(const ListUpdateResponse& aResponse);
+
+ nsresult ProcessAdditionOrRemoval(TableUpdateV4& aTableUpdate,
+ const ThreatEntrySetList& aUpdate,
+ bool aIsAddition);
+
+ nsresult ProcessRawAddition(TableUpdateV4& aTableUpdate,
+ const ThreatEntrySet& aAddition);
+
+ nsresult ProcessRawRemoval(TableUpdateV4& aTableUpdate,
+ const ThreatEntrySet& aRemoval);
+
+ nsresult ProcessEncodedAddition(TableUpdateV4& aTableUpdate,
+ const ThreatEntrySet& aAddition);
+
+ nsresult ProcessEncodedRemoval(TableUpdateV4& aTableUpdate,
+ const ThreatEntrySet& aRemoval);
+};
+
+} // namespace safebrowsing
+} // namespace mozilla
+
+#endif