Branch data Line data Source code
1 : : // $Id: SSH.cc 6782 2009-06-28 02:19:03Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #include "config.h"
6 : :
7 : : #include <ctype.h>
8 : :
9 : : #include "NetVar.h"
10 : : #include "SSH.h"
11 : : #include "Event.h"
12 : : #include "ContentLine.h"
13 : :
14 : 0 : SSH_Analyzer::SSH_Analyzer(Connection* c)
15 : 0 : : TCP_ApplicationAnalyzer(AnalyzerTag::SSH, c)
16 : : {
17 : 0 : orig = new ContentLine_Analyzer(c, true);
18 : 0 : orig->SetSkipPartial(true);
19 : 0 : orig->SetCRLFAsEOL(LF_as_EOL);
20 : 0 : AddSupportAnalyzer(orig);
21 : :
22 : 0 : resp = new ContentLine_Analyzer(c, false);
23 : 0 : resp->SetSkipPartial(true);
24 : 0 : resp->SetCRLFAsEOL(LF_as_EOL);
25 : 0 : AddSupportAnalyzer(resp);
26 : 0 : }
27 : :
28 : 0 : void SSH_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig)
29 : : {
30 : 0 : TCP_ApplicationAnalyzer::DeliverStream(length, data, is_orig);
31 : :
32 : : // We're all done processing this endpoint - flag it as such,
33 : : // before we even determine whether we have any event generation
34 : : // work to do, to make sure we don't do any further work on it.
35 [ # # ]: 0 : if ( is_orig )
36 : 0 : orig->SetSkipDeliveries(true);
37 : : else
38 : 0 : resp->SetSkipDeliveries(true);
39 : :
40 [ # # ]: 0 : if ( TCP() )
41 : : {
42 : : // Don't try to parse version if there has already been a gap.
43 [ # # ]: 0 : TCP_Endpoint* endp = is_orig ? TCP()->Orig() : TCP()->Resp();
44 [ # # ]: 0 : if ( endp->HadGap() )
45 : 0 : return;
46 : : }
47 : :
48 : 0 : const char* line = (const char*) data;
49 : :
50 : : // The SSH identification looks like this:
51 : : //
52 : : // SSH-<protocolmajor>.<protocolminor>-<version>\n
53 : : //
54 : : // We're interested in the "version" part here.
55 : :
56 [ # # ][ # # ]: 0 : if ( length < 4 || memcmp(line, "SSH-", 4) != 0 )
57 : : {
58 : 0 : Weird("malformed_ssh_identification");
59 : 0 : ProtocolViolation("malformed ssh identification", line, length);
60 : 0 : return;
61 : : }
62 : :
63 : : int i;
64 [ # # ][ # # ]: 0 : for ( i = 4; i < length && line[i] != '-'; ++i )
65 : : ;
66 : :
67 [ # # ]: 0 : if ( TCP() )
68 : : {
69 [ # # ]: 0 : if ( length >= i )
70 : : {
71 : : const uint32* dst;
72 [ # # ]: 0 : if ( is_orig )
73 : 0 : dst = TCP()->Orig()->dst_addr;
74 : : else
75 : 0 : dst = TCP()->Resp()->dst_addr;
76 : :
77 [ # # ]: 0 : if ( Conn()->VersionFoundEvent(dst, line + i,
78 : : length - i) )
79 : 0 : ProtocolConfirmation();
80 : : else
81 : : ProtocolViolation("malformed ssh version",
82 : 0 : line, length);
83 : : }
84 : : else
85 : : {
86 : 0 : Weird("malformed_ssh_version");
87 : 0 : ProtocolViolation("malformed ssh version", line, length);
88 : : }
89 : : }
90 : :
91 : : // Generate SSH events.
92 : : EventHandlerPtr event = is_orig ?
93 [ # # ]: 0 : ssh_client_version : ssh_server_version;
94 [ # # ]: 0 : if ( ! event )
95 : 0 : return;
96 : :
97 : 0 : val_list* vl = new val_list;
98 : 0 : vl->append(BuildConnVal());
99 : 0 : vl->append(new StringVal(length, line));
100 : :
101 : 0 : ConnectionEvent(event, vl);
102 [ + - ][ + - ]: 6 : }
|