mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
Initial import of svn+ssh:://svn.icir.org/bro/trunk/bro as of r7088
This commit is contained in:
commit
61757ac78b
1383 changed files with 380824 additions and 0 deletions
250
src/Ident.cc
Normal file
250
src/Ident.cc
Normal file
|
@ -0,0 +1,250 @@
|
|||
// $Id: Ident.cc 6219 2008-10-01 05:39:07Z vern $
|
||||
//
|
||||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "NetVar.h"
|
||||
#include "Ident.h"
|
||||
#include "Event.h"
|
||||
#include "TCP_Rewriter.h"
|
||||
|
||||
Ident_Analyzer::Ident_Analyzer(Connection* conn)
|
||||
: TCP_ApplicationAnalyzer(AnalyzerTag::Ident, conn)
|
||||
{
|
||||
did_bad_reply = did_deliver = 0;
|
||||
|
||||
orig_ident = new ContentLine_Analyzer(conn, true);
|
||||
resp_ident = new ContentLine_Analyzer(conn, false);
|
||||
|
||||
orig_ident->SetIsNULSensitive(true);
|
||||
resp_ident->SetIsNULSensitive(true);
|
||||
|
||||
AddSupportAnalyzer(orig_ident);
|
||||
AddSupportAnalyzer(resp_ident);
|
||||
}
|
||||
|
||||
void Ident_Analyzer::Done()
|
||||
{
|
||||
TCP_ApplicationAnalyzer::Done();
|
||||
|
||||
if ( TCP() )
|
||||
if ( (! did_deliver || orig_ident->HasPartialLine()) &&
|
||||
(TCP()->OrigState() == TCP_ENDPOINT_CLOSED ||
|
||||
TCP()->OrigPrevState() == TCP_ENDPOINT_CLOSED) &&
|
||||
TCP()->OrigPrevState() != TCP_ENDPOINT_PARTIAL &&
|
||||
TCP()->RespPrevState() != TCP_ENDPOINT_PARTIAL &&
|
||||
TCP()->OrigPrevState() != TCP_ENDPOINT_INACTIVE &&
|
||||
TCP()->RespPrevState() != TCP_ENDPOINT_INACTIVE )
|
||||
Weird("partial_ident_request");
|
||||
}
|
||||
|
||||
void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig)
|
||||
{
|
||||
TCP_ApplicationAnalyzer::DeliverStream(length, data, is_orig);
|
||||
|
||||
int remote_port, local_port;
|
||||
const char* line = (const char*) data;
|
||||
const char* orig_line = line;
|
||||
const char* end_of_line = line + length;
|
||||
|
||||
TCP_Endpoint* s = 0;
|
||||
|
||||
if ( TCP() )
|
||||
s = is_orig ? TCP()->Orig() : TCP()->Resp();
|
||||
|
||||
if ( is_orig )
|
||||
{
|
||||
if ( ! ident_request )
|
||||
return;
|
||||
|
||||
line = ParsePair(line, end_of_line, remote_port, local_port);
|
||||
if ( ! line )
|
||||
{
|
||||
if ( s && s->state == TCP_ENDPOINT_CLOSED &&
|
||||
(s->prev_state == TCP_ENDPOINT_INACTIVE ||
|
||||
s->prev_state == TCP_ENDPOINT_PARTIAL) )
|
||||
// not surprising the request is mangled.
|
||||
return;
|
||||
|
||||
BadRequest(length, orig_line);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( line != end_of_line )
|
||||
Weird("ident_request_addendum", length, orig_line);
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new PortVal(local_port, TRANSPORT_TCP));
|
||||
vl->append(new PortVal(remote_port, TRANSPORT_TCP));
|
||||
|
||||
ConnectionEvent(ident_request, vl);
|
||||
|
||||
did_deliver = 1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( ! ident_reply )
|
||||
return;
|
||||
|
||||
line = ParsePair(line, end_of_line, remote_port, local_port);
|
||||
|
||||
if ( ! line || line == end_of_line || line[0] != ':' )
|
||||
{
|
||||
if ( s && s->state == TCP_ENDPOINT_CLOSED &&
|
||||
(s->prev_state == TCP_ENDPOINT_INACTIVE ||
|
||||
s->prev_state == TCP_ENDPOINT_PARTIAL) )
|
||||
// not surprising the request is mangled.
|
||||
return;
|
||||
|
||||
BadReply(length, orig_line);
|
||||
return;
|
||||
}
|
||||
|
||||
line = skip_whitespace(line + 1, end_of_line);
|
||||
int restlen = end_of_line - line;
|
||||
|
||||
int is_error;
|
||||
if ( restlen >= 5 && ! strncmp(line, "ERROR", 5) )
|
||||
{
|
||||
is_error = 1;
|
||||
line += 5;
|
||||
}
|
||||
else if ( restlen >= 6 && ! strncmp(line, "USERID", 6) )
|
||||
{
|
||||
is_error = 0;
|
||||
line += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
BadReply(length, orig_line);
|
||||
return;
|
||||
}
|
||||
|
||||
line = skip_whitespace(line, end_of_line);
|
||||
|
||||
if ( line >= end_of_line || line[0] != ':' )
|
||||
{
|
||||
BadReply(length, orig_line);
|
||||
return;
|
||||
}
|
||||
|
||||
line = skip_whitespace(line + 1, end_of_line);
|
||||
|
||||
if ( is_error )
|
||||
{
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new PortVal(local_port, TRANSPORT_TCP));
|
||||
vl->append(new PortVal(remote_port, TRANSPORT_TCP));
|
||||
vl->append(new StringVal(end_of_line - line, line));
|
||||
|
||||
ConnectionEvent(ident_error, vl);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
const char* sys_type = line;
|
||||
const char* colon = strchr_n(line, end_of_line, ':');
|
||||
const char* comma = strchr_n(line, end_of_line, ',');
|
||||
if ( ! colon )
|
||||
{
|
||||
BadReply(length, orig_line);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* sys_end = (comma && comma < colon) ?
|
||||
comma : colon;
|
||||
|
||||
while ( --sys_end > sys_type && isspace(*sys_end) )
|
||||
;
|
||||
|
||||
BroString* sys_type_s =
|
||||
new BroString((const u_char*) sys_type,
|
||||
sys_end - sys_type + 1, 1);
|
||||
|
||||
line = skip_whitespace(colon + 1, end_of_line);
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new PortVal(local_port, TRANSPORT_TCP));
|
||||
vl->append(new PortVal(remote_port, TRANSPORT_TCP));
|
||||
vl->append(new StringVal(end_of_line - line, line));
|
||||
vl->append(new StringVal(sys_type_s));
|
||||
|
||||
ConnectionEvent(ident_reply, vl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* Ident_Analyzer::ParsePair(const char* line, const char* end_of_line, int & p1, int& p2)
|
||||
{
|
||||
line = ParsePort(line, end_of_line, p1);
|
||||
if ( ! line )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( line >= end_of_line || line[0] != ',' )
|
||||
return 0;
|
||||
|
||||
++line;
|
||||
|
||||
line = ParsePort(line, end_of_line, p2);
|
||||
if ( ! line )
|
||||
return 0;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
const char* Ident_Analyzer::ParsePort(const char* line, const char* end_of_line,
|
||||
int& pn)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
line = skip_whitespace(line, end_of_line);
|
||||
if ( ! isdigit(*line) )
|
||||
return 0;
|
||||
|
||||
const char* l = line;
|
||||
|
||||
do
|
||||
{
|
||||
n = n * 10 + (*line - '0');
|
||||
++line;
|
||||
}
|
||||
while ( isdigit(*line) );
|
||||
|
||||
line = skip_whitespace(line, end_of_line);
|
||||
|
||||
if ( n < 0 || n > 65535 )
|
||||
{
|
||||
Weird("bad_ident_port", l);
|
||||
n = 0;
|
||||
}
|
||||
|
||||
pn = n;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
void Ident_Analyzer::BadRequest(int length, const char* line)
|
||||
{
|
||||
Weird("bad_ident_request", length, line);
|
||||
}
|
||||
|
||||
void Ident_Analyzer::BadReply(int length, const char* line)
|
||||
{
|
||||
if ( ! did_bad_reply )
|
||||
{
|
||||
Weird("bad_ident_reply", length, line);
|
||||
did_bad_reply = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#include "ident-rw.bif.func_def"
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue