/[svn]/vendor/pxys2-2.1.0/pxyscand/src/PXMSocks.cc
ViewVC logotype

Contents of /vendor/pxys2-2.1.0/pxyscand/src/PXMSocks.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3253 - (show annotations)
Wed Apr 2 20:46:18 2014 UTC (6 years, 11 months ago) by michael
File MIME type: text/x-c++src
File size: 6660 byte(s)
- Imported pxys2-2.1.0

1 // Copyright (C) 2003-2005 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: PXMSocks.cc,v 1.5 2006/09/10 22:17:24 spale Exp $"
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #define SOCKS4_SHORTNAME "Socks4"
26 #define SOCKS5_SHORTNAME "Socks5"
27
28 #define SOCKS4_DESCR "Insecure Socks 4 server"
29 #define SOCKS5_DESCR "Insecure Socks 5 server"
30
31 #define MAX_LINES_TRY 4
32
33 #include "PXMSocks.h"
34 #include "socks4.h"
35 #include "socks5.h"
36 #include "PXSecret.h"
37
38 #include <cassert>
39 #include <cerrno>
40 #include <cstring>
41
42 map<uint16_t, uint32_t*> PXMSocks::sConn4CountMap;
43 map<uint16_t, uint32_t*> PXMSocks::sProxy4CountMap;
44 map<uint16_t, uint32_t*> PXMSocks::sConn5CountMap;
45 map<uint16_t, uint32_t*> PXMSocks::sProxy5CountMap;
46
47 PXMSocks::PXMSocks(PXScan *inScan, int inPort)
48 : PXScanModule(inScan), mStatus(SCAN_NOSOCKS), mLinesTry(0), mPort(inPort)
49 {
50 if (sConn4CountMap.find(mPort) == sConn4CountMap.end())
51 {
52 sConn4CountMap[mPort] = new uint32_t;
53 *sConn4CountMap[mPort] = 0;
54 sProxy4CountMap[mPort] = new uint32_t;
55 *sProxy4CountMap[mPort] = 0;
56 sConn5CountMap[mPort] = new uint32_t;
57 *sConn5CountMap[mPort] = 0;
58 sProxy5CountMap[mPort] = new uint32_t;
59 *sProxy5CountMap[mPort] = 0;
60 }
61 }
62
63 PXMSocks::~PXMSocks()
64 {
65 }
66
67 void
68 PXMSocks::InitModule()
69 {
70 RegisterPXM(SOCKS4_SHORTNAME, mPort, sConn4CountMap[mPort], sProxy4CountMap[mPort]);
71 RegisterPXM(SOCKS5_SHORTNAME, mPort, sConn5CountMap[mPort], sProxy5CountMap[mPort]);
72 }
73
74 bool
75 PXMSocks::StartScan()
76 {
77 peak_task task = peak_task_self();
78
79 struct sockaddr_in sin;
80 memset(&sin, 0, sizeof(struct sockaddr_in));
81 sin.sin_family = AF_INET;
82 sin.sin_addr = this->GetAddress();
83 sin.sin_port = htons(mPort);
84
85 mStream = peak_stream_socket_create((struct sockaddr *)&sin, sizeof(sin),
86 PEAK_STREAM_OPT_DEFAULT,
87 EventCallback,
88 this);
89
90 if (!mStream)
91 return false;
92
93 if (this->IsLocalAddressSet())
94 {
95 sockaddr_in local_sin;
96 memset(&local_sin, 0, sizeof(local_sin));
97 local_sin.sin_family = AF_INET;
98 local_sin.sin_addr = this->GetLocalAddress();
99 local_sin.sin_port = htons(0);
100
101 peak_stream_set_address(mStream, (sockaddr*)&local_sin, sizeof(local_sin));
102 }
103
104 /* Enable built-in timeout option, this is so useful here. */
105 peak_stream_set_timeout(mStream, GetTimeout());
106
107 /* Connect (don't block) */
108 if (peak_stream_connect(mStream) == -1)
109 {
110 this->Cleanup();
111 this->ProxyNotFound();
112 }
113 else
114 peak_stream_schedule(mStream, task);
115 return true;
116 }
117
118 void
119 PXMSocks::Cleanup()
120 {
121 peak_release(mStream);
122 }
123
124 void
125 PXMSocks::ProxyNotFound()
126 {
127 if (mStatus == SCAN_SOCKS4)
128 {
129 mStatus = SCAN_SOCKS5;
130 this->StartScan();
131 return;
132 }
133
134 PXScanModule::ProxyNotFound();
135 }
136
137 void
138 PXMSocks::SendSocks4Request(peak_stream s)
139 {
140 struct socks4 socks4out = { S4_VN, S4_CMD_CONNECT, { 0, 0 },
141 { 0, 0, 0, 0 }, 0 };
142 in_addr targetAddr = GetTargetAddress();
143 uint16_t targetPort = htons(GetTargetPort());
144
145 /* Set target address */
146 memcpy(&socks4out.dstip, &targetAddr, sizeof(socks4out.dstip));
147 memcpy(&socks4out.dstport, &targetPort, sizeof(socks4out.dstport));
148
149 peak_stream_set_buffered(s, 1, sizeof(socks4out), sizeof(socks4out), NULL);
150 peak_stream_write_buffered(s, &socks4out, sizeof(socks4out));
151 }
152
153 void
154 PXMSocks::SendSocks5Request(peak_stream s)
155 {
156 struct socks5 socks5out = { S5_VN, S5_CMD_CONNECT };
157
158 peak_stream_set_buffered(s, 1, sizeof(socks5out), sizeof(socks5out), NULL);
159 peak_stream_write_buffered(s, &socks5out, sizeof(socks5out));
160 }
161
162 void
163 PXMSocks::ProcessEvent(peak_stream s, int type)
164 {
165 int err;
166
167 switch (type)
168 {
169 case PEAK_STREAM_EVT_OPEN:
170 if (mStatus == SCAN_NOSOCKS)
171 {
172 mStatus = SCAN_SOCKS4;
173 (*sConn4CountMap[mPort])++;
174 this->SendSocks4Request(s);
175 }
176 else
177 {
178 assert(mStatus == SCAN_SOCKS5);
179 (*sConn5CountMap[mPort])++;
180 this->SendSocks5Request(s);
181 }
182 break;
183 case PEAK_STREAM_EVT_READ:
184 if (mStatus == SCAN_SOCKS4)
185 {
186 int len;
187 char line[8192];
188 len = peak_stream_read(s, line, sizeof(line));
189
190 if (ScannerSha256StringCheck(line,len,GetTargetSecret()))
191 {
192 (*sProxy4CountMap[mPort])++;
193 this->Cleanup();
194 this->ProxyFound(OPAS_PROXY_TYPE_SOCKS4, mPort, SOCKS4_DESCR);
195 return; /* done! */
196 }
197 if (mLinesTry++ < MAX_LINES_TRY)
198 break;
199 }
200 else
201 {
202 // Socks v5
203 struct socks5_response socks5in;
204 if (peak_stream_read(s, &socks5in, sizeof(socks5in)) > 1)
205 {
206 if (socks5in.vn == S5_VN)
207 {
208 switch(socks5in.method)
209 {
210 case S5_R_METHOD_NOAUTH:
211 (*sProxy5CountMap[mPort])++;
212 this->Cleanup();
213 this->ProxyFound(OPAS_PROXY_TYPE_SOCKS5, mPort, SOCKS5_DESCR);
214 return; /* done! */
215 case S5_R_METHOD_GSSAPI:
216 case S5_R_METHOD_USERPW:
217 case S5_R_METHOD_NOTACC:
218 default:
219 break;
220 }
221 }
222 }
223 }
224 /* fall through */
225 case PEAK_STREAM_EVT_ERROR:
226 case PEAK_STREAM_EVT_TIMEDOUT:
227 this->Cleanup();
228 this->ProxyNotFound();
229 break;
230 case PEAK_STREAM_EVT_END:
231 err = peak_stream_get_error(s);
232 this->Cleanup();
233 if (err == ENETUNREACH)
234 this->ScanError(OPAS_ERROR_NETUNREACH); // Can't scan !
235 else if (err == ENETDOWN)
236 this->ScanError(OPAS_ERROR_NETDOWN); // Even worst !
237 else
238 this->ProxyNotFound();
239 break;
240 default:
241 break;
242 }
243 }
244
245 void
246 PXMSocks::EventCallback(peak_stream s, int type, void *context)
247 {
248 PXMSocks *pxm = reinterpret_cast<PXMSocks*>(context);
249 pxm->ProcessEvent(s, type);
250 }

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28