aboutsummaryrefslogtreecommitdiffstats
path: root/netlib
diff options
context:
space:
mode:
Diffstat (limited to 'netlib')
-rw-r--r--netlib/certutils.py2
-rw-r--r--netlib/http.py17
-rw-r--r--netlib/http_auth.py44
-rw-r--r--netlib/tcp.py12
-rw-r--r--netlib/test.py2
-rw-r--r--netlib/version.py2
6 files changed, 62 insertions, 17 deletions
diff --git a/netlib/certutils.py b/netlib/certutils.py
index a21f0188..22b5c35c 100644
--- a/netlib/certutils.py
+++ b/netlib/certutils.py
@@ -1,4 +1,4 @@
-import os, ssl, time, datetime, tempfile, shutil
+import os, ssl, time, datetime
from pyasn1.type import univ, constraint, char, namedtype, tag
from pyasn1.codec.der.decoder import decode
from pyasn1.error import PyAsn1Error
diff --git a/netlib/http.py b/netlib/http.py
index f1a2bfb5..7060b688 100644
--- a/netlib/http.py
+++ b/netlib/http.py
@@ -283,32 +283,23 @@ def parse_init_http(line):
return method, url, httpversion
-def request_connection_close(httpversion, headers):
+def connection_close(httpversion, headers):
"""
- Checks the request to see if the client connection should be closed.
+ Checks the message to see if the client connection should be closed according to RFC 2616 Section 8.1
"""
+ # At first, check if we have an explicit Connection header.
if "connection" in headers:
toks = get_header_tokens(headers, "connection")
if "close" in toks:
return True
elif "keep-alive" in toks:
return False
- # HTTP 1.1 connections are assumed to be persistent
+ # If we don't have a Connection header, HTTP 1.1 connections are assumed to be persistent
if httpversion == (1, 1):
return False
return True
-def response_connection_close(httpversion, headers):
- """
- Checks the response to see if the client connection should be closed.
- """
- if request_connection_close(httpversion, headers):
- return True
- elif (not has_chunked_encoding(headers)) and "content-length" in headers:
- return False
- return True
-
def read_http_body_request(rfile, wfile, headers, httpversion, limit):
"""
diff --git a/netlib/http_auth.py b/netlib/http_auth.py
index 4adae179..6c91c7c5 100644
--- a/netlib/http_auth.py
+++ b/netlib/http_auth.py
@@ -1,6 +1,7 @@
import binascii
import contrib.md5crypt as md5crypt
import http
+from argparse import Action, ArgumentTypeError
class NullProxyAuth():
@@ -111,3 +112,46 @@ class PassManSingleUser:
def test(self, username, password_token):
return self.username==username and self.password==password_token
+
+
+class AuthAction(Action):
+ """
+ Helper class to allow seamless integration int argparse. Example usage:
+ parser.add_argument(
+ "--nonanonymous",
+ action=NonanonymousAuthAction, nargs=0,
+ help="Allow access to any user long as a credentials are specified."
+ )
+ """
+ def __call__(self, parser, namespace, values, option_string=None):
+ passman = self.getPasswordManager(values)
+ if passman:
+ authenticator = BasicProxyAuth(passman, "mitmproxy")
+ else:
+ authenticator = NullProxyAuth(None)
+ setattr(namespace, "authenticator", authenticator)
+
+ def getPasswordManager(self, s):
+ """
+ returns the password manager
+ """
+ raise NotImplementedError()
+
+
+class SingleuserAuthAction(AuthAction):
+ def getPasswordManager(self, s):
+ if len(s.split(':')) != 2:
+ raise ArgumentTypeError("Invalid single-user specification. Please use the format username:password")
+ username, password = s.split(':')
+ return PassManSingleUser(username, password)
+
+
+class NonanonymousAuthAction(AuthAction):
+ def getPasswordManager(self, s):
+ return PassManNonAnon()
+
+
+class HtpasswdAuthAction(AuthAction):
+ def getPasswordManager(self, s):
+ with open(s, "r") as f:
+ return PassManHtpasswd(f) \ No newline at end of file
diff --git a/netlib/tcp.py b/netlib/tcp.py
index 31e9a398..c632ec67 100644
--- a/netlib/tcp.py
+++ b/netlib/tcp.py
@@ -235,6 +235,7 @@ class TCPClient:
try:
if self.ssl_established:
self.connection.shutdown()
+ self.connection.sock_shutdown(socket.SHUT_WR)
else:
self.connection.shutdown(socket.SHUT_WR)
#Section 4.2.2.13 of RFC 1122 tells us that a close() with any pending readable data could lead to an immediate RST being sent.
@@ -302,6 +303,8 @@ class BaseHandler:
if request_client_cert:
def ver(*args):
self.clientcert = certutils.SSLCert(args[1])
+ # Return true to prevent cert verification error
+ return True
ctx.set_verify(SSL.VERIFY_PEER, ver)
self.connection = SSL.Connection(ctx, self.connection)
self.ssl_established = True
@@ -338,6 +341,7 @@ class BaseHandler:
try:
if self.ssl_established:
self.connection.shutdown()
+ self.connection.sock_shutdown(socket.SHUT_WR)
else:
self.connection.shutdown(socket.SHUT_WR)
#Section 4.2.2.13 of RFC 1122 tells us that a close() with any pending readable data could lead to an immediate RST being sent.
@@ -376,7 +380,13 @@ class TCPServer:
self.__is_shut_down.clear()
try:
while not self.__shutdown_request:
- r, w, e = select.select([self.socket], [], [], poll_interval)
+ try:
+ r, w, e = select.select([self.socket], [], [], poll_interval)
+ except select.error, ex:
+ if ex[0] == 4:
+ continue
+ else:
+ raise
if self.socket in r:
request, client_address = self.socket.accept()
t = threading.Thread(
diff --git a/netlib/test.py b/netlib/test.py
index 661395c5..87802bd5 100644
--- a/netlib/test.py
+++ b/netlib/test.py
@@ -52,7 +52,7 @@ class TServer(tcp.TCPServer):
self.last_handler = h
if self.ssl:
cert = certutils.SSLCert.from_pem(
- file(self.ssl["cert"], "r").read()
+ file(self.ssl["cert"], "rb").read()
)
if self.ssl["v3_only"]:
method = tcp.SSLv3_METHOD
diff --git a/netlib/version.py b/netlib/version.py
index 63a9d862..32013c35 100644
--- a/netlib/version.py
+++ b/netlib/version.py
@@ -1,4 +1,4 @@
-IVERSION = (0, 9, 1)
+IVERSION = (0, 9, 2)
VERSION = ".".join(str(i) for i in IVERSION)
NAME = "netlib"
NAMEVERSION = NAME + " " + VERSION