mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Add decode_base64_custom BiF to allow alternate base64 alphabets.
Addresses #670
This commit is contained in:
parent
151664bc26
commit
5865bf3850
5 changed files with 97 additions and 14 deletions
|
@ -1,14 +1,27 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "Base64.h"
|
#include "Base64.h"
|
||||||
|
|
||||||
static int base64_table[256];
|
int Base64Decoder::default_base64_table[256];
|
||||||
|
const string Base64Decoder::default_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
static void init_base64_table()
|
int* Base64Decoder::InitBase64Table(const string& alphabet)
|
||||||
{
|
{
|
||||||
static int table_initialized = 0;
|
static bool default_table_initialized = false;
|
||||||
|
|
||||||
if ( ++table_initialized > 1 )
|
if ( alphabet == default_alphabet && default_table_initialized )
|
||||||
return;
|
return default_base64_table;
|
||||||
|
|
||||||
|
int* base64_table = 0;
|
||||||
|
|
||||||
|
if ( alphabet == default_alphabet )
|
||||||
|
{
|
||||||
|
base64_table = default_base64_table;
|
||||||
|
default_table_initialized = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base64_table = new int[256];
|
||||||
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for ( i = 0; i < 256; ++i )
|
for ( i = 0; i < 256; ++i )
|
||||||
|
@ -16,28 +29,44 @@ static void init_base64_table()
|
||||||
|
|
||||||
for ( i = 0; i < 26; ++i )
|
for ( i = 0; i < 26; ++i )
|
||||||
{
|
{
|
||||||
base64_table['A' + i] = i;
|
base64_table[int(alphabet[0 + i])] = i;
|
||||||
base64_table['a' + i] = i + 26;
|
base64_table[int(alphabet[26 + i])] = i + 26;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( i = 0; i < 10; ++i )
|
for ( i = 0; i < 10; ++i )
|
||||||
base64_table['0' + i] = i + 52;
|
base64_table[int(alphabet[52 + i])] = i + 52;
|
||||||
|
|
||||||
// Casts to avoid compiler warnings.
|
// Casts to avoid compiler warnings.
|
||||||
base64_table[int('+')] = 62;
|
base64_table[int(alphabet[62])] = 62;
|
||||||
base64_table[int('/')] = 63;
|
base64_table[int(alphabet[63])] = 63;
|
||||||
base64_table[int('=')] = 0;
|
base64_table[int('=')] = 0;
|
||||||
|
|
||||||
|
return base64_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
Base64Decoder::Base64Decoder(Analyzer* arg_analyzer)
|
Base64Decoder::Base64Decoder(Analyzer* arg_analyzer)
|
||||||
{
|
{
|
||||||
init_base64_table();
|
base64_table = InitBase64Table(default_alphabet);
|
||||||
base64_group_next = 0;
|
base64_group_next = 0;
|
||||||
base64_padding = base64_after_padding = 0;
|
base64_padding = base64_after_padding = 0;
|
||||||
errored = 0;
|
errored = 0;
|
||||||
analyzer = arg_analyzer;
|
analyzer = arg_analyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Base64Decoder::Base64Decoder(Analyzer* arg_analyzer, const string& alphabet)
|
||||||
|
{
|
||||||
|
base64_table = InitBase64Table(alphabet);
|
||||||
|
base64_group_next = 0;
|
||||||
|
base64_padding = base64_after_padding = 0;
|
||||||
|
errored = 0;
|
||||||
|
analyzer = arg_analyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Base64Decoder::~Base64Decoder()
|
||||||
|
{
|
||||||
|
if ( base64_table != default_base64_table ) delete base64_table;
|
||||||
|
}
|
||||||
|
|
||||||
int Base64Decoder::Decode(int len, const char* data, int* pblen, char** pbuf)
|
int Base64Decoder::Decode(int len, const char* data, int* pblen, char** pbuf)
|
||||||
{
|
{
|
||||||
int blen;
|
int blen;
|
||||||
|
@ -142,13 +171,21 @@ int Base64Decoder::Done(int* pblen, char** pbuf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BroString* decode_base64(const BroString* s)
|
|
||||||
|
BroString* decode_base64(const BroString* s, const BroString* a)
|
||||||
{
|
{
|
||||||
|
if (a->Len() != 64)
|
||||||
|
{
|
||||||
|
reporter->Error("base64 decoding alphabet is not 64 characters: %s",
|
||||||
|
a->CheckString());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int buf_len = int((s->Len() + 3) / 4) * 3 + 1;
|
int buf_len = int((s->Len() + 3) / 4) * 3 + 1;
|
||||||
int rlen2, rlen = buf_len;
|
int rlen2, rlen = buf_len;
|
||||||
char* rbuf2, *rbuf = new char[rlen];
|
char* rbuf2, *rbuf = new char[rlen];
|
||||||
|
|
||||||
Base64Decoder dec(0);
|
Base64Decoder dec(0, a->CheckString());
|
||||||
if ( dec.Decode(s->Len(), (const char*) s->Bytes(), &rlen, &rbuf) == -1 )
|
if ( dec.Decode(s->Len(), (const char*) s->Bytes(), &rlen, &rbuf) == -1 )
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -166,3 +203,9 @@ err:
|
||||||
delete [] rbuf;
|
delete [] rbuf;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BroString* decode_base64(const BroString* s)
|
||||||
|
{
|
||||||
|
BroString a(Base64Decoder::default_alphabet);
|
||||||
|
return decode_base64(s, &a);
|
||||||
|
}
|
||||||
|
|
10
src/Base64.h
10
src/Base64.h
|
@ -17,7 +17,8 @@ public:
|
||||||
// when the decoder is called by the built-in function
|
// when the decoder is called by the built-in function
|
||||||
// decode_base64().
|
// decode_base64().
|
||||||
Base64Decoder(Analyzer* analyzer);
|
Base64Decoder(Analyzer* analyzer);
|
||||||
~Base64Decoder() { }
|
Base64Decoder(Analyzer* analyzer, const string& alphabet);
|
||||||
|
~Base64Decoder();
|
||||||
|
|
||||||
// A note on Decode():
|
// A note on Decode():
|
||||||
//
|
//
|
||||||
|
@ -47,6 +48,11 @@ public:
|
||||||
reporter->Error("%s", msg);
|
reporter->Error("%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int* InitBase64Table(const string& alphabet);
|
||||||
|
|
||||||
|
static const string default_alphabet;
|
||||||
|
static int default_base64_table[256];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char error_msg[256];
|
char error_msg[256];
|
||||||
|
|
||||||
|
@ -57,8 +63,10 @@ protected:
|
||||||
int base64_after_padding;
|
int base64_after_padding;
|
||||||
int errored; // if true, we encountered an error - skip further processing
|
int errored; // if true, we encountered an error - skip further processing
|
||||||
Analyzer* analyzer;
|
Analyzer* analyzer;
|
||||||
|
int* base64_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BroString* decode_base64(const BroString* s, const BroString* a);
|
||||||
BroString* decode_base64(const BroString* s);
|
BroString* decode_base64(const BroString* s);
|
||||||
|
|
||||||
#endif /* base64_h */
|
#endif /* base64_h */
|
||||||
|
|
12
src/bro.bif
12
src/bro.bif
|
@ -1860,6 +1860,18 @@ function decode_base64%(s: string%): string
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
function decode_base64_custom%(s: string, a: string%): string
|
||||||
|
%{
|
||||||
|
BroString* t = decode_base64(s->AsString(), a->AsString());
|
||||||
|
if ( t )
|
||||||
|
return new StringVal(t);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reporter->Error("error in decoding string %s", s->CheckString());
|
||||||
|
return new StringVal("");
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
%%{
|
%%{
|
||||||
#include "DCE_RPC.h"
|
#include "DCE_RPC.h"
|
||||||
|
|
||||||
|
|
6
testing/btest/Baseline/bifs.decode_base64/out
Normal file
6
testing/btest/Baseline/bifs.decode_base64/out
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
bro
|
||||||
|
bro
|
||||||
|
bro
|
||||||
|
bro
|
||||||
|
bro
|
||||||
|
bro
|
14
testing/btest/bifs/decode_base64.bro
Normal file
14
testing/btest/bifs/decode_base64.bro
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# @TEST-EXEC: bro -b %INPUT >out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
global default_alphabet: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
global my_alphabet: string = "!#$%&/(),-.:;<>@[]^ `_{|}~abcdefghijklmnopqrstuvwxyz0123456789+?";
|
||||||
|
|
||||||
|
print decode_base64("YnJv");
|
||||||
|
print decode_base64_custom("YnJv", default_alphabet);
|
||||||
|
print decode_base64_custom("}n-v", my_alphabet);
|
||||||
|
|
||||||
|
print decode_base64("YnJv");
|
||||||
|
print decode_base64_custom("YnJv", default_alphabet);
|
||||||
|
print decode_base64_custom("}n-v", my_alphabet);
|
Loading…
Add table
Add a link
Reference in a new issue