1 |
michael |
3252 |
// Copyright (C) 2003, 2004 Stephane Thiell |
2 |
|
|
// |
3 |
|
|
// This file is part of pxyscand (from pxys) |
4 |
|
|
// |
5 |
|
|
// This program is free software; you can redistribute it and/or |
6 |
|
|
// modify it under the terms of the GNU General Public License |
7 |
|
|
// as published by the Free Software Foundation; either version 2 |
8 |
|
|
// of the License, or (at your option) any later version. |
9 |
|
|
// |
10 |
|
|
// This program is distributed in the hope that it will be useful, |
11 |
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
|
|
// GNU General Public License for more details. |
14 |
|
|
// |
15 |
|
|
// You should have received a copy of the GNU General Public License |
16 |
|
|
// along with this program; if not, write to the Free Software |
17 |
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 |
|
|
// |
19 |
|
|
#define RCSID "$Id: PXMWingate.cc,v 1.3 2004/01/10 14:32:29 mbuna Exp $" |
20 |
|
|
|
21 |
|
|
// This class scans for Open Wingate or Cisco (with "cisco" password). |
22 |
|
|
|
23 |
|
|
#define WINGATE_SHORTNAME "WinGate" |
24 |
|
|
#define CISCO_SHORTNAME "Cisco" |
25 |
|
|
|
26 |
|
|
#define WINGATE_DESCR "Insecure WinGate server" |
27 |
|
|
#define CISCO_DESCR "Insecure Cisco router" |
28 |
|
|
|
29 |
|
|
#define WINGATE_PORT 23 |
30 |
|
|
#define CISCO_PORT WINGATE_PORT |
31 |
|
|
|
32 |
|
|
#define MAX_LINES_TRY 30 |
33 |
|
|
#define CRLF "\r\n" |
34 |
|
|
|
35 |
|
|
#include "PXMWingate.h" |
36 |
|
|
#include <iostream> |
37 |
|
|
#include <cassert> |
38 |
|
|
#include <cerrno> |
39 |
|
|
#include <cstring> |
40 |
|
|
#include <arpa/inet.h> |
41 |
|
|
#include <opas/opas.h> |
42 |
|
|
|
43 |
|
|
using std::clog; |
44 |
|
|
using std::endl; |
45 |
|
|
|
46 |
|
|
uint32_t PXMWingate::sConnCount = 0; |
47 |
|
|
uint32_t PXMWingate::sProxyCount1 = 0; |
48 |
|
|
uint32_t PXMWingate::sProxyCount2 = 0; |
49 |
|
|
|
50 |
|
|
PXMWingate::PXMWingate(PXScan *inScan) |
51 |
|
|
: PXScanModule(inScan), mStream(NULL), mCiscoRequest(false), mLinesTry(0) |
52 |
|
|
{ |
53 |
|
|
} |
54 |
|
|
|
55 |
|
|
PXMWingate::~PXMWingate() |
56 |
|
|
{ |
57 |
|
|
} |
58 |
|
|
|
59 |
|
|
void |
60 |
|
|
PXMWingate::InitModule() |
61 |
|
|
{ |
62 |
|
|
RegisterPXM(WINGATE_SHORTNAME, WINGATE_PORT, &sConnCount, &sProxyCount1); |
63 |
|
|
RegisterPXM(CISCO_SHORTNAME, CISCO_PORT, &sConnCount, &sProxyCount2); |
64 |
|
|
} |
65 |
|
|
|
66 |
|
|
bool |
67 |
|
|
PXMWingate::StartScan() |
68 |
|
|
{ |
69 |
|
|
peak_task task = peak_task_self(); |
70 |
|
|
|
71 |
|
|
sockaddr_in sin; |
72 |
|
|
memset(&sin, 0, sizeof(sockaddr_in)); |
73 |
|
|
sin.sin_family = AF_INET; |
74 |
|
|
sin.sin_addr = this->GetAddress(); |
75 |
|
|
sin.sin_port = htons(WINGATE_PORT); |
76 |
|
|
|
77 |
|
|
mStream = peak_stream_socket_create((sockaddr *)&sin, sizeof(sin), |
78 |
|
|
PEAK_STREAM_OPT_DEFAULT, |
79 |
|
|
EventCallback, |
80 |
|
|
this); |
81 |
|
|
|
82 |
|
|
if (!mStream) |
83 |
|
|
return false; |
84 |
|
|
|
85 |
|
|
if (this->IsLocalAddressSet()) |
86 |
|
|
{ |
87 |
|
|
sockaddr_in local_sin; |
88 |
|
|
memset(&local_sin, 0, sizeof(local_sin)); |
89 |
|
|
local_sin.sin_family = AF_INET; |
90 |
|
|
local_sin.sin_addr = this->GetLocalAddress(); |
91 |
|
|
local_sin.sin_port = htons(0); |
92 |
|
|
|
93 |
|
|
peak_stream_set_address(mStream, (sockaddr*)&local_sin, sizeof(local_sin)); |
94 |
|
|
} |
95 |
|
|
|
96 |
|
|
/* Set write buffered mode. */ |
97 |
|
|
peak_stream_set_buffered(mStream, 1, 2, 512, NULL); |
98 |
|
|
|
99 |
|
|
/* Enable built-in timeout option, this is so useful here. */ |
100 |
|
|
peak_stream_set_timeout(mStream, GetTimeout() / 2 + 1); |
101 |
|
|
|
102 |
|
|
/* Connect (don't block) */ |
103 |
|
|
if (peak_stream_connect(mStream) == -1) |
104 |
|
|
{ |
105 |
|
|
peak_release(mStream); |
106 |
|
|
this->ProxyNotFound(); |
107 |
|
|
} |
108 |
|
|
else |
109 |
|
|
peak_stream_schedule(mStream, task); |
110 |
|
|
return true; |
111 |
|
|
} |
112 |
|
|
|
113 |
|
|
void |
114 |
|
|
PXMWingate::SendCiscoRequest(peak_stream s) |
115 |
|
|
{ |
116 |
|
|
in_addr targetAddr = GetTargetAddress(); |
117 |
|
|
char uriHostname[16]; |
118 |
|
|
int uriPort = GetTargetPort(); |
119 |
|
|
|
120 |
|
|
inet_ntop(AF_INET, &targetAddr, uriHostname, sizeof(uriHostname)); |
121 |
|
|
|
122 |
|
|
peak_stream_set_buffered(s, 1, 64, 64*2, NULL); |
123 |
|
|
peak_stream_msgbuf_make(s, "cisco" CRLF); |
124 |
|
|
peak_stream_msgbuf_make(s, "telnet %s %d" CRLF, uriHostname, uriPort); |
125 |
|
|
} |
126 |
|
|
|
127 |
|
|
void |
128 |
|
|
PXMWingate::ProcessEvent(peak_stream s, int type) |
129 |
|
|
{ |
130 |
|
|
char *line; |
131 |
|
|
char winReadBuf[64]; |
132 |
|
|
int err; |
133 |
|
|
|
134 |
|
|
switch (type) |
135 |
|
|
{ |
136 |
|
|
case PEAK_STREAM_EVT_OPEN: |
137 |
|
|
sConnCount++; |
138 |
|
|
break; |
139 |
|
|
case PEAK_STREAM_EVT_READ: |
140 |
|
|
if (!mCiscoRequest) |
141 |
|
|
{ |
142 |
|
|
memset(winReadBuf, 0, sizeof(winReadBuf)); |
143 |
|
|
if (peak_stream_read(s, winReadBuf, sizeof(winReadBuf)) > 0) |
144 |
|
|
{ |
145 |
|
|
if (!strncmp(winReadBuf, "WinGate>", 8) |
146 |
|
|
|| !strncmp(winReadBuf, "Too m", 5)) |
147 |
|
|
{ |
148 |
|
|
sProxyCount1++; |
149 |
|
|
#if 0 |
150 |
|
|
clog << "PXMWingate::ProcessEvent: proxy found: " |
151 |
|
|
<< winReadBuf << endl; |
152 |
|
|
#endif |
153 |
|
|
peak_release(s); |
154 |
|
|
this->ProxyFound(OPAS_PROXY_TYPE_WINGATE, WINGATE_PORT, |
155 |
|
|
WINGATE_DESCR); |
156 |
|
|
return; /* we are done */ |
157 |
|
|
} |
158 |
|
|
} |
159 |
|
|
if (mLinesTry++ < MAX_LINES_TRY) |
160 |
|
|
break; |
161 |
|
|
} |
162 |
|
|
else |
163 |
|
|
{ |
164 |
|
|
line = peak_stream_get_line(s); |
165 |
|
|
|
166 |
|
|
if (this->ScannerStringCheck(line)) |
167 |
|
|
{ |
168 |
|
|
sProxyCount2++; |
169 |
|
|
peak_release(s); |
170 |
|
|
this->ProxyFound(OPAS_PROXY_TYPE_CISCOROUTER, CISCO_PORT, |
171 |
|
|
CISCO_DESCR); |
172 |
|
|
return; /* done! */ |
173 |
|
|
} |
174 |
|
|
else if (mLinesTry++ < MAX_LINES_TRY) |
175 |
|
|
break; |
176 |
|
|
} |
177 |
|
|
/* fall through */ |
178 |
|
|
case PEAK_STREAM_EVT_END: |
179 |
|
|
this->ProxyNotFound(); |
180 |
|
|
peak_release(s); |
181 |
|
|
break; |
182 |
|
|
|
183 |
|
|
case PEAK_STREAM_EVT_ERROR: |
184 |
|
|
err = peak_stream_get_error(s); |
185 |
|
|
if (err == ENETUNREACH || err == EHOSTUNREACH) |
186 |
|
|
this->ScanError(OPAS_ERROR_NETUNREACH); // Can't scan ! |
187 |
|
|
else if (err == ENETDOWN || err == EHOSTDOWN) |
188 |
|
|
this->ScanError(OPAS_ERROR_NETDOWN); // Even worst ! |
189 |
|
|
else |
190 |
|
|
this->ProxyNotFound(); |
191 |
|
|
peak_release(s); |
192 |
|
|
break; |
193 |
|
|
|
194 |
|
|
case PEAK_STREAM_EVT_TIMEDOUT: |
195 |
|
|
if (!mCiscoRequest && peak_stream_is_open(s)) |
196 |
|
|
{ |
197 |
|
|
mCiscoRequest = true; |
198 |
|
|
peak_stream_set_linemode(s); |
199 |
|
|
peak_stream_set_timeout(s, GetTimeout()); |
200 |
|
|
this->SendCiscoRequest(s); |
201 |
|
|
} |
202 |
|
|
else |
203 |
|
|
{ |
204 |
|
|
this->ProxyNotFound(); |
205 |
|
|
peak_release(s); |
206 |
|
|
} |
207 |
|
|
break; |
208 |
|
|
default: |
209 |
|
|
break; |
210 |
|
|
} |
211 |
|
|
} |
212 |
|
|
|
213 |
|
|
void |
214 |
|
|
PXMWingate::EventCallback(peak_stream s, int type, void *context) |
215 |
|
|
{ |
216 |
|
|
PXMWingate *pxm = reinterpret_cast<PXMWingate*>(context); |
217 |
|
|
pxm->ProcessEvent(s, type); |
218 |
|
|
} |