|
|
|
|
|
|
|
|
// FilterChain.hpp |
|
|
// FilterChain.hpp |
|
|
// |
|
|
// |
|
|
// (C) 2002-2009 MicroNeil Research Corporation |
|
|
|
|
|
|
|
|
// (C) 2002-2020 MicroNeil Research Corporation |
|
|
// |
|
|
// |
|
|
// This is the base class header for FilterChain objects. |
|
|
// This is the base class header for FilterChain objects. |
|
|
// FilterChain objects can be chained together to filter |
|
|
// FilterChain objects can be chained together to filter |
|
|
|
|
|
|
|
|
// it's source's data, or a stream of '0's if none has been |
|
|
// it's source's data, or a stream of '0's if none has been |
|
|
// defined. |
|
|
// defined. |
|
|
|
|
|
|
|
|
#ifndef _MN_FilterChain |
|
|
|
|
|
#define _MN_FilterChain |
|
|
|
|
|
|
|
|
#pragma once |
|
|
|
|
|
|
|
|
#include <stdexcept> |
|
|
#include <stdexcept> |
|
|
#include <iostream> |
|
|
#include <iostream> |
|
|
|
|
|
|
|
|
#include <cctype> |
|
|
#include <cctype> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Define parameters for this module. |
|
|
// Define parameters for this module. |
|
|
|
|
|
|
|
|
const static int ScanBufferSize = 128; // Define the buffer size. |
|
|
const static int ScanBufferSize = 128; // Define the buffer size. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
public: |
|
|
|
|
|
|
|
|
class BadSource : public invalid_argument { // Bad Source Exception. |
|
|
|
|
|
public: BadSource(const string& w):invalid_argument(w){} |
|
|
|
|
|
|
|
|
class BadSource : public std::invalid_argument { // Bad Source Exception. |
|
|
|
|
|
public: BadSource(const std::string& w):invalid_argument(w){} |
|
|
}; |
|
|
}; |
|
|
class Empty : public underflow_error { // Empty Exception. |
|
|
|
|
|
public: Empty(const string& w):underflow_error(w){} |
|
|
|
|
|
|
|
|
class Empty : public std::underflow_error { // Empty Exception. |
|
|
|
|
|
public: Empty(const std::string& w):underflow_error(w){} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
virtual unsigned char GetByte() { // Return either 0 |
|
|
virtual unsigned char GetByte() { // Return either 0 |
|
|
|
|
|
|
|
|
FilterChain(FilterChain* S) { |
|
|
FilterChain(FilterChain* S) { |
|
|
if(NULL==S) throw BadSource("FilterChain: NULL source not valid"); |
|
|
if(NULL==S) throw BadSource("FilterChain: NULL source not valid"); |
|
|
else Source = S; |
|
|
else Source = S; |
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
virtual ~FilterChain() {} // Stop Warns about no virt dtor |
|
|
virtual ~FilterChain() {} // Stop Warns about no virt dtor |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
|
|
|
|
|
|
istream* SourceIstream; |
|
|
|
|
|
|
|
|
std::istream* SourceIstream; |
|
|
|
|
|
|
|
|
public: |
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Here we overload the constructor to accept a stream. |
|
|
// Here we overload the constructor to accept a stream. |
|
|
|
|
|
|
|
|
FilterChainInput(istream* S){ // Build me with a stream. |
|
|
|
|
|
|
|
|
FilterChainInput(std::istream* S){ // Build me with a stream. |
|
|
if(NULL==S) throw BadSource("FilterChainInput: Null source not valid" ); // If it's NULL that's bad. |
|
|
if(NULL==S) throw BadSource("FilterChainInput: Null source not valid" ); // If it's NULL that's bad. |
|
|
if(!S->good()) throw BadSource("FilterChainInput: Bad istream"); // Not good is bad. |
|
|
if(!S->good()) throw BadSource("FilterChainInput: Bad istream"); // Not good is bad. |
|
|
else SourceIstream = S; // If it's good we keep it. |
|
|
else SourceIstream = S; // If it's good we keep it. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned char* InputBuffer; |
|
|
unsigned char* InputBuffer; |
|
|
unsigned int BufferLength; |
|
|
unsigned int BufferLength; |
|
|
unsigned int BufferIndex;
|
|
|
|
|
|
|
|
|
unsigned int BufferIndex; |
|
|
|
|
|
|
|
|
stringstream& PrependedHeaders; |
|
|
|
|
|
|
|
|
std::stringstream& PrependedHeaders; |
|
|
|
|
|
|
|
|
bool PrependNotBuffer; |
|
|
bool PrependNotBuffer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Here we overload the constructor to accept a stream. |
|
|
// Here we overload the constructor to accept a stream. |
|
|
|
|
|
|
|
|
FilterChainCBFR(unsigned char* S, int l, stringstream& P) : // Give me a bfr and a stringstream. |
|
|
|
|
|
|
|
|
FilterChainCBFR(unsigned char* S, int l, std::stringstream& P) : // Give me a bfr and a stringstream. |
|
|
InputBuffer(S), // Grab the buffer, |
|
|
InputBuffer(S), // Grab the buffer, |
|
|
BufferLength(l), // Grab the buffer length, |
|
|
BufferLength(l), // Grab the buffer length, |
|
|
BufferIndex(0), // Initialize the index to 0, |
|
|
BufferIndex(0), // Initialize the index to 0, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int ScanIx; // Scanning Index. |
|
|
unsigned int ScanIx; // Scanning Index. |
|
|
unsigned int DequeIx; // Dequeing Index. |
|
|
unsigned int DequeIx; // Dequeing Index. |
|
|
unsigned char Buffer; // Define a buffer.
|
|
|
|
|
|
|
|
|
unsigned char Buffer; // Define a buffer. |
|
|
bool ValidBuffer; // Set if Buffer has data. |
|
|
bool ValidBuffer; // Set if Buffer has data. |
|
|
|
|
|
|
|
|
bool ValidByte(unsigned char y); // True if y can be decoded. |
|
|
bool ValidByte(unsigned char y); // True if y can be decoded. |
|
|
|
|
|
|
|
|
class FilterChainDefunker : public FilterChain { // Class definition. |
|
|
class FilterChainDefunker : public FilterChain { // Class definition. |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
|
|
|
|
|
|
// Occasionally when parsing a chunk of data we must return nothing and
|
|
|
|
|
|
// instead try again for the next character. Instead of resursing we can
|
|
|
|
|
|
// set this flag and the root state will simply try again in a loop.
|
|
|
|
|
|
|
|
|
|
|
|
bool ReturnNothing; // Set true to skip this round;
|
|
|
|
|
|
|
|
|
|
|
|
// Storeage
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Occasionally when parsing a chunk of data we must return nothing and |
|
|
|
|
|
// instead try again for the next character. Instead of resursing we can |
|
|
|
|
|
// set this flag and the root state will simply try again in a loop. |
|
|
|
|
|
|
|
|
|
|
|
bool ReturnNothing; // Set true to skip this round; |
|
|
|
|
|
|
|
|
|
|
|
// Storeage |
|
|
|
|
|
|
|
|
unsigned char StoreBuffer[DefunkerSize]; |
|
|
unsigned char StoreBuffer[DefunkerSize]; |
|
|
int InputPosition; |
|
|
int InputPosition; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FilterChainDefunker(FilterChain* S) // Sourced constructor... |
|
|
FilterChainDefunker(FilterChain* S) // Sourced constructor... |
|
|
:FilterChain(S), // Call the base constructor. |
|
|
:FilterChain(S), // Call the base constructor. |
|
|
InputPosition(0), // Reset both position pointers.
|
|
|
|
|
|
OutputPosition(0),
|
|
|
|
|
|
LastRawByte(0),
|
|
|
|
|
|
LastReadOut(0),
|
|
|
|
|
|
LastGetStore(0),
|
|
|
|
|
|
|
|
|
InputPosition(0), // Reset both position pointers. |
|
|
|
|
|
OutputPosition(0), |
|
|
|
|
|
LastRawByte(0), |
|
|
|
|
|
LastReadOut(0), |
|
|
|
|
|
LastGetStore(0), |
|
|
Master(&FilterChainDefunker::SkipHeaders), // Set the initial external and |
|
|
Master(&FilterChainDefunker::SkipHeaders), // Set the initial external and |
|
|
Internal(&FilterChainDefunker::Preamble) { // internal states. |
|
|
Internal(&FilterChainDefunker::Preamble) { // internal states. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FilterChainIPTester { |
|
|
class FilterChainIPTester { |
|
|
public: |
|
|
public: |
|
|
virtual string& test(string& input, string& output) = 0; |
|
|
|
|
|
|
|
|
virtual std::string& test(std::string& input, std::string& output) = 0; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// The supplied test() function accepts the input string and returns the |
|
|
// The supplied test() function accepts the input string and returns the |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned char (FilterChainHeaderAnalysis::*Mode)(); // Internal State Fn Pointer (What Mode) |
|
|
unsigned char (FilterChainHeaderAnalysis::*Mode)(); // Internal State Fn Pointer (What Mode) |
|
|
FilterChainIPTester& IPTester; // This is the IP tester we use. |
|
|
FilterChainIPTester& IPTester; // This is the IP tester we use. |
|
|
string IPToTest; // String to capture IPs for testing. |
|
|
|
|
|
string IPTestResult; // String to receive IPtest results. |
|
|
|
|
|
|
|
|
std::string IPToTest; // String to capture IPs for testing. |
|
|
|
|
|
std::string IPTestResult; // String to receive IPtest results. |
|
|
|
|
|
|
|
|
// Header analysis output state... |
|
|
// Header analysis output state... |
|
|
|
|
|
|
|
|
string EndOfHeaderResults; // String to capture EndOfHeaderResults. |
|
|
|
|
|
|
|
|
std::string EndOfHeaderResults; // String to capture EndOfHeaderResults. |
|
|
|
|
|
|
|
|
// OutputIndex and OutputLength are used to inject string data. |
|
|
// OutputIndex and OutputLength are used to inject string data. |
|
|
// These are used to inject IPTestResult data and Header Analysis data. |
|
|
// These are used to inject IPTestResult data and Header Analysis data. |
|
|
|
|
|
|
|
|
char* OutputBuffer; // Pointer to output injection string. |
|
|
char* OutputBuffer; // Pointer to output injection string. |
|
|
int OutputIndex; // End of header output results index. |
|
|
int OutputIndex; // End of header output results index. |
|
|
void SetOutputBuffer(string& s); // Setup the OutputBuffer. |
|
|
|
|
|
|
|
|
void SetOutputBuffer(std::string& s); // Setup the OutputBuffer. |
|
|
unsigned char doInjectIPTestResult(); // Inject OutputBuffer and go to doSeekNL. |
|
|
unsigned char doInjectIPTestResult(); // Inject OutputBuffer and go to doSeekNL. |
|
|
unsigned char doInjectAnalysis(); // Inject OutputBuffer and go to doOff. |
|
|
unsigned char doInjectAnalysis(); // Inject OutputBuffer and go to doOff. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FilterChainHeaderAnalysis(FilterChain* S, FilterChainIPTester& T) : // Construct with the chain and a tester. |
|
|
FilterChainHeaderAnalysis(FilterChain* S, FilterChainIPTester& T) : // Construct with the chain and a tester. |
|
|
FilterChain(S), // Capture the chain. |
|
|
FilterChain(S), // Capture the chain. |
|
|
Mode(&FilterChainHeaderAnalysis::doSeekDispatch), // Start in SeekDispatch() mode
|
|
|
|
|
|
|
|
|
Mode(&FilterChainHeaderAnalysis::doSeekDispatch), // Start in SeekDispatch() mode |
|
|
IPTester(T), // Capture the tester. |
|
|
IPTester(T), // Capture the tester. |
|
|
IPToTest(""), // IPToTest and |
|
|
IPToTest(""), // IPToTest and |
|
|
IPTestResult(""), // IPTestResult are both empty to start. |
|
|
IPTestResult(""), // IPTestResult are both empty to start. |
|
|
|
|
|
|
|
|
bool HighBitCharacters() { return (FoundHighBitCharacters); } // True if High bit characters were found. |
|
|
bool HighBitCharacters() { return (FoundHighBitCharacters); } // True if High bit characters were found. |
|
|
|
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
#endif |
|
|
|