michael@0: //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 ProtocolParser_h__ michael@0: #define ProtocolParser_h__ michael@0: michael@0: #include "HashStore.h" michael@0: #include "nsICryptoHMAC.h" michael@0: michael@0: namespace mozilla { michael@0: namespace safebrowsing { michael@0: michael@0: /** michael@0: * Some helpers for parsing the safe michael@0: */ michael@0: class ProtocolParser { michael@0: public: michael@0: struct ForwardedUpdate { michael@0: nsCString table; michael@0: nsCString url; michael@0: }; michael@0: michael@0: ProtocolParser(); michael@0: ~ProtocolParser(); michael@0: michael@0: nsresult Status() const { return mUpdateStatus; } michael@0: michael@0: nsresult Init(nsICryptoHash* aHasher); michael@0: michael@0: void SetCurrentTable(const nsACString& aTable); michael@0: michael@0: nsresult Begin(); michael@0: nsresult AppendStream(const nsACString& aData); michael@0: michael@0: // Forget the table updates that were created by this pass. It michael@0: // becomes the caller's responsibility to free them. This is shitty. michael@0: TableUpdate *GetTableUpdate(const nsACString& aTable); michael@0: void ForgetTableUpdates() { mTableUpdates.Clear(); } michael@0: nsTArray &GetTableUpdates() { return mTableUpdates; } michael@0: michael@0: // Update information. michael@0: const nsTArray &Forwards() const { return mForwards; } michael@0: int32_t UpdateWait() { return mUpdateWait; } michael@0: bool ResetRequested() { return mResetRequested; } michael@0: michael@0: private: michael@0: nsresult ProcessControl(bool* aDone); michael@0: nsresult ProcessExpirations(const nsCString& aLine); michael@0: nsresult ProcessChunkControl(const nsCString& aLine); michael@0: nsresult ProcessForward(const nsCString& aLine); michael@0: nsresult AddForward(const nsACString& aUrl); michael@0: nsresult ProcessChunk(bool* done); michael@0: // Remove this, it's only used for testing michael@0: nsresult ProcessPlaintextChunk(const nsACString& aChunk); michael@0: nsresult ProcessShaChunk(const nsACString& aChunk); michael@0: nsresult ProcessHostAdd(const Prefix& aDomain, uint8_t aNumEntries, michael@0: const nsACString& aChunk, uint32_t* aStart); michael@0: nsresult ProcessHostSub(const Prefix& aDomain, uint8_t aNumEntries, michael@0: const nsACString& aChunk, uint32_t* aStart); michael@0: nsresult ProcessHostAddComplete(uint8_t aNumEntries, const nsACString& aChunk, michael@0: uint32_t *aStart); michael@0: nsresult ProcessHostSubComplete(uint8_t numEntries, const nsACString& aChunk, michael@0: uint32_t* start); michael@0: // Digest chunks are very similar to shavar chunks, except digest chunks michael@0: // always contain the full hash, so there is no need for chunk data to michael@0: // contain prefix sizes. michael@0: nsresult ProcessDigestChunk(const nsACString& aChunk); michael@0: nsresult ProcessDigestAdd(const nsACString& aChunk); michael@0: nsresult ProcessDigestSub(const nsACString& aChunk); michael@0: bool NextLine(nsACString& aLine); michael@0: michael@0: void CleanupUpdates(); michael@0: michael@0: enum ParserState { michael@0: PROTOCOL_STATE_CONTROL, michael@0: PROTOCOL_STATE_CHUNK michael@0: }; michael@0: ParserState mState; michael@0: michael@0: enum ChunkType { michael@0: // Types for shavar tables. michael@0: CHUNK_ADD, michael@0: CHUNK_SUB, michael@0: // Types for digest256 tables. digest256 tables differ in format from michael@0: // shavar tables since they only contain complete hashes. michael@0: CHUNK_ADD_DIGEST, michael@0: CHUNK_SUB_DIGEST michael@0: }; michael@0: michael@0: struct ChunkState { michael@0: ChunkType type; michael@0: uint32_t num; michael@0: uint32_t hashSize; michael@0: uint32_t length; michael@0: void Clear() { num = 0; hashSize = 0; length = 0; } michael@0: }; michael@0: ChunkState mChunkState; michael@0: michael@0: nsCOMPtr mCryptoHash; michael@0: michael@0: nsresult mUpdateStatus; michael@0: nsCString mPending; michael@0: michael@0: uint32_t mUpdateWait; michael@0: bool mResetRequested; michael@0: michael@0: nsTArray mForwards; michael@0: // Keep track of updates to apply before passing them to the DBServiceWorkers. michael@0: nsTArray mTableUpdates; michael@0: // Updates to apply to the current table being parsed. michael@0: TableUpdate *mTableUpdate; michael@0: }; michael@0: michael@0: } michael@0: } michael@0: michael@0: #endif