|
1 | 1 | #!/usr/bin/env python |
2 | 2 |
|
3 | 3 | """SocksiPy - Python SOCKS module. |
4 | | -Version 1.00 |
| 4 | +Version 1.01 |
5 | 5 |
|
6 | 6 | Copyright 2006 Dan-Haim. All rights reserved. |
7 | 7 |
|
|
44 | 44 |
|
45 | 45 | """ |
46 | 46 |
|
| 47 | +import functools |
47 | 48 | import socket |
48 | 49 | import struct |
49 | 50 |
|
@@ -107,8 +108,29 @@ def wrapmodule(module): |
107 | 108 | This will only work on modules that import socket directly into the namespace; |
108 | 109 | most of the Python Standard Library falls into this category. |
109 | 110 | """ |
110 | | - if _defaultproxy != None: |
111 | | - module.socket.socket = socksocket |
| 111 | + if _defaultproxy is not None: |
| 112 | + _orig_socket_ctor = _orgsocket |
| 113 | + |
| 114 | + @functools.wraps(_orig_socket_ctor) |
| 115 | + def guarded_socket(*args, **kwargs): |
| 116 | + # socket.socket([family[, type[, proto]]]) |
| 117 | + family = args[0] if len(args) > 0 else kwargs.get("family", socket.AF_INET) |
| 118 | + stype = args[1] if len(args) > 1 else kwargs.get("type", socket.SOCK_STREAM) |
| 119 | + |
| 120 | + # Normalize socket type by stripping flags (Py3.3+ may OR these in) |
| 121 | + flags = 0 |
| 122 | + flags |= getattr(socket, "SOCK_CLOEXEC", 0) |
| 123 | + flags |= getattr(socket, "SOCK_NONBLOCK", 0) |
| 124 | + base_type = stype & ~flags |
| 125 | + |
| 126 | + if family in (socket.AF_INET, getattr(socket, "AF_INET6", socket.AF_INET)) and base_type == socket.SOCK_STREAM: |
| 127 | + return socksocket(*args, **kwargs) |
| 128 | + |
| 129 | + # Fallback: don't proxy AF_UNIX / raw / etc. |
| 130 | + return _orig_socket_ctor(*args, **kwargs) |
| 131 | + |
| 132 | + module.socket.socket = guarded_socket |
| 133 | + |
112 | 134 | if _defaultproxy[0] == PROXY_TYPE_SOCKS4: |
113 | 135 | # Note: unable to prevent DNS leakage in SOCKS4 (Reference: https://security.stackexchange.com/a/171280) |
114 | 136 | pass |
|
0 commit comments