diff --git a/snxconnect b/snxconnect index 94cab74..70df7d8 100755 --- a/snxconnect +++ b/snxconnect @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python2 from snxconnect import main diff --git a/snxconnect.py b/snxconnect.py index 66e99b3..036a199 100644 --- a/snxconnect.py +++ b/snxconnect.py @@ -6,6 +6,9 @@ import sys import socket try : + import httplib + import urllib2 + import ssl from urllib2 import build_opener, HTTPCookieProcessor, Request from urllib import urlencode from httplib import IncompleteRead @@ -68,6 +71,29 @@ def iterbytes (x) : yield (x [i:i+1]) # end def iterbytes +class VerifiedHTTPSConnection(httplib.HTTPSConnection): + def connect(self): + # overrides the version in httplib so that we can fiddle with cert options + sock = socket.create_connection((self.host, self.port), self.timeout) + if self._tunnel_host: + self.sock = sock + self._tunnel() + + self.sock = ssl.wrap_socket(sock, + self.key_file, + self.cert_file, + cert_reqs=ssl.CERT_NONE ) + #cert_reqs=ssl.CERT_REQUIRED, + #ca_certs="PATH_TO_VALID_CA_CRT") + +# wraps https connections with ssl certificate verification +class VerifiedHTTPSHandler(urllib2.HTTPSHandler): + def __init__(self, connection_class = VerifiedHTTPSConnection): + self.specialized_conn_class = connection_class + urllib2.HTTPSHandler.__init__(self) + def https_open(self, req): + return self.do_open(self.specialized_conn_class, req) + class HTML_Requester (object) : def __init__ (self, args) : @@ -82,7 +108,8 @@ def __init__ (self, args) : j.load (self.args.cookiefile, ignore_discard = True) except IOError : self.has_cookies = False - self.opener = build_opener (HTTPCookieProcessor (j)) + https_handler = VerifiedHTTPSHandler() + self.opener = build_opener (https_handler, HTTPCookieProcessor (j)) self.nextfile = args.file # end def __init__ @@ -159,7 +186,7 @@ def login (self) : self.open () self.debug (self.purl) if self.purl.endswith ('Portal/Main') : - self.open ('sslvpn/SNX/extender') + self.open (self.args.extender) self.parse_extender () self.generate_snx_info () return True @@ -203,26 +230,35 @@ def login (self) : self.open (data = urlencode (d)) self.debug (self.purl) self.debug (self.info) - while 'MultiChallenge' in self.purl : - d = self.parse_pw_response () - otp = getpass ('One-time Password: ') - d ['password'] = enc.encrypt (otp) - self.debug ("nextfile: %s" % self.nextfile) + + if self.args.multi_challenge : + while 'MultiChallenge' in self.purl : + d = self.parse_pw_response () + otp = getpass ('One-time Password: ') + d ['password'] = enc.encrypt (otp) + self.debug ("nextfile: %s" % self.nextfile) + self.debug ("purl: %s" % self.purl) + self.open (data = urlencode (d)) + self.debug ("info: %s" % self.info) + + if self.purl.endswith ('Login/ActivateLogin') : + if self.args.save_cookies : + self.jar.save (self.args.cookiefile, ignore_discard = True) self.debug ("purl: %s" % self.purl) - self.open (data = urlencode (d)) - self.debug ("info: %s" % self.info) + self.open('sslvpn/Login/ActivateLogin?ActivateLogin=activate&LangSelect=en_US&submit=Continue&HeightData=') + if self.purl.endswith ('Portal/Main') : if self.args.save_cookies : self.jar.save (self.args.cookiefile, ignore_discard = True) self.debug ("purl: %s" % self.purl) - self.open ('sslvpn/SNX/extender') + self.open (self.args.extender) self.debug (self.purl) self.debug (self.info) self.parse_extender () self.generate_snx_info () return True else : - print ("Unexpected response, looking for MultiChallenge or Portal") + print ("Unexpected response, try again.") self.debug ("purl: %s" % self.purl) return # end def login @@ -405,7 +441,7 @@ def main () : except (OSError, IOError) : pass cfg = {} - boolopts = ['debug', 'save_cookies'] + boolopts = ['debug', 'save_cookies', 'multi_challenge'] if cfgf : for line in cfgf : line = line.strip ().decode ('utf-8') @@ -439,6 +475,11 @@ def main () : , help = 'File part of URL default="%(default)s"' , default = cfg.get ('file', 'sslvpn/Login/Login') ) + cmd.add_argument \ + ( '-E', '--extender' + , help = 'File part of URL default="%(default)s"' + , default = cfg.get ('extender', 'sslvpn/SNX/extender') + ) cmd.add_argument \ ( '-H', '--host' , help = 'Host part of URL default="%(default)s"' @@ -455,6 +496,11 @@ def main () : , help = 'Login type, default="%(default)s"' , default = cfg.get ('login_type', 'Standard') ) + cmd.add_argument \ + ( '-MC', '--multi-challenge' + , help = 'MultiChallenge, default="%(default)s"' + , default = cfg.get ('multi_challenge', False) + ) cmd.add_argument \ ( '-P', '--password' , help = 'Login password, not a good idea to specify on commandline'