def _getAuthOpener_LXP150(self, http_user, http_pass): ''' Create an authenticated opener for the LXPx50 series. The LXPx50 HTTP authentication is again weird. First, a request must be sent to the phone with a Cookie with a SessionId set to a random number between 0 and 99999. Sending 0 works just as well. The first request must be a GET that asks the phone to calculate a hash for a specified username and password. The hash is embedded inside a HTML fragment in the response. Next the hash must be sent as a new Cookie in a POST request that also includes the original SessionId number and the UserName as cookies. A successful login returns a response with the phone status, including the phone model. Additionally, the response after a successful login includes a brand new SessionId that must be replaced in the opener cookie. ''' cookiejar = cookielib.CookieJar(cookielib.DefaultCookiePolicy(rfc2965=True)) sesscookie = cookielib.Cookie(None, 'SessionId', '0', None, False, self._ip, False, False, '/', False, False, str((int)(time.time() + 3600)), False, 'SessionId', None, None) cookiejar.set_cookie(sesscookie) opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar)) response = opener.open('http://' + self._ip + '/fcgi/do?' + urllib.urlencode({ 'action': 'Encrypt', 'UserName' : http_user, 'Password' : http_pass})) body = response.read() m = re.search(r"id=hcSingleResult type=hidden value='(.+?)'", body) if m is None: return (None, None) encrypted_password = m.group(1) sesscookie = cookielib.Cookie(None, 'UserName', http_user, None, False, self._ip, False, False, '/', False, False, str((int)(time.time() + 3600)), False, 'UserName', None, None) cookiejar.set_cookie(sesscookie) sesscookie = cookielib.Cookie(None, 'Password', encrypted_password, None, False, self._ip, False, False, '/', False, False, str((int)(time.time() + 3600)), False, 'Password', None, None) cookiejar.set_cookie(sesscookie) response = opener.open('http://' + self._ip + '/fcgi/do?id=1', 'SubmitData=begin%26Operation%3DCreateSession%26DestURL%3Did%6021%26SubmitData%3Dend') # Find new SessionId value. What, no Set-Cookie header? body = response.read() m = re.search(r"id=hcSessionIdNow type=hidden value='(.+?)'", body) if m != None: sesscookie = cookielib.Cookie(None, 'SessionId', m.group(1), None, False, self._ip, False, False, '/', False, False, str((int)(time.time() + 3600)), False, 'SessionId', None, None) cookiejar.set_cookie(sesscookie) else: logging.error('Endpoint %s@%s LXPx50 failed to authenticate - new session ID not found in response' % (self._vendorname, self._ip)) return (None, None) # Subsequent requests must NOT have the UserName/Password cookies cookiejar.clear(self._ip, '/', 'UserName') cookiejar.clear(self._ip, '/', 'Password') return (opener, body)
def _enableStaticProvisioning_GXP1450(self, vars): try: # Login into interface opener = urllib2.build_opener(urllib2.HTTPCookieProcessor()) response = opener.open( 'http://' + self._ip + '/cgi-bin/dologin', urllib.urlencode({ 'Login': '******', 'P2': self._http_password, 'gnkey': '0b82' })) body = response.read() if 'dologin' in body: logging.error('Endpoint %s@%s GXP1450 - dologin failed login' % (self._vendorname, self._ip)) return False response = opener.open('http://' + self._ip + '/cgi-bin/update', urllib.urlencode(vars) + '&gnkey=0b82') body = response.read() if 'dologin' in body: logging.error( 'Endpoint %s@%s GXP1450 - dologin failed to keep session' % (self._vendorname, self._ip)) return False return True except socket.error, e: logging.error('Endpoint %s@%s GXP1450 failed to connect - %s' % (self._vendorname, self._ip, str(e))) return False
def _enableStaticProvisioning_GXP140x(self, vars): try: # Login into interface and get SID. Check proper Content-Type cookiejar = cookielib.CookieJar( cookielib.DefaultCookiePolicy(rfc2965=True)) opener = urllib2.build_opener( urllib2.HTTPCookieProcessor(cookiejar)) # response = urllib2.urlopen('http://' + self._ip + '/cgi-bin/dologin', response = opener.open( 'http://' + self._ip + '/cgi-bin/dologin', urllib.urlencode({'password': self._http_password})) body = response.read() content_type = response.info()['Content-Type'].rsplit(';', 1)[0] if content_type <> 'application/json': logging.error( 'Endpoint %s@%s GXP140x - dologin answered not application/json but %s' % (self._vendorname, self._ip, response.info()['Content-Type'])) return False # Check successful login and get sid jsonvars = cjson.decode(body) if not ('body' in jsonvars and 'sid' in jsonvars['body']): logging.error('Endpoint %s@%s GXP140x - dologin failed login' % (self._vendorname, self._ip)) return False sid = jsonvars['body']['sid'] # Post vars with sid vars.update({'sid': sid}) # response = urllib2.urlopen('http://' + self._ip + '/cgi-bin/api.values.post', response = opener.open( 'http://' + self._ip + '/cgi-bin/api.values.post', urllib.urlencode(vars)) jsonvars = self._parseBotchedJSONResponse(response) if jsonvars == None: logging.error( 'jsonvars vacio %s@%s GXP140x - vars rejected by interface - %s - %s - %s' % (self._vendorname, self._ip, urllib.urlencode(vars), jsonvars['body'], sid)) return False if not ('response' in jsonvars and jsonvars['response'] == 'success' \ and 'body' in jsonvars and 'status' in jsonvars['body'] and jsonvars['body']['status'] == 'right' ): logging.error( 'Endpoint %s@%s GXP140x - vars rejected by interface - %s - %s - %s' % (self._vendorname, self._ip, urllib.urlencode(vars), jsonvars['body'], sid)) return False return True except cjson.DecodeError, e: logging.error('Endpoint %s@%s GXP140x received invalid JSON - %s' % (self._vendorname, self._ip, str(e))) return False
def _rebootbyhttp(self): opener = urllib2.build_opener(urllib2.HTTPCookieProcessor()) response = opener.open('http://' + self._ip + '/cgi-bin//api-sys_operation?passcode=' + self._http_password + '&request=REBOOT') jsonvars = self._parseBotchedJSONResponse(response) if jsonvars == None: return False if not ('response' in jsonvars and jsonvars['response'] == 'success'): logging.error('Endpoint %s@%s unimplemented reboot by HTTP' % (self._vendorname, self._ip)) return False return True
def test_cookies(self): cj = MockCookieJar() h = urllib2.HTTPCookieProcessor(cj) o = h.parent = MockOpener() req = Request("http://example.com/") r = MockResponse(200, "OK", {}, "") newreq = h.http_request(req) self.assert_(cj.ach_req is req is newreq) self.assertEquals(req.get_origin_req_host(), "example.com") self.assert_(not req.is_unverifiable()) newr = h.http_response(req, r) self.assert_(cj.ec_req is req) self.assert_(cj.ec_r is r is newr)
def dont_test_cookie_redirect(self): # cookies shouldn't leak into redirected requests from cookielib import CookieJar from test.test_cookielib import interact_netscape cj = CookieJar() interact_netscape(cj, "http://www.example.com/", "spam=eggs") hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n") hdeh = urllib2.HTTPDefaultErrorHandler() hrh = urllib2.HTTPRedirectHandler() cp = urllib2.HTTPCookieProcessor(cj) o = build_test_opener(hh, hdeh, hrh, cp) o.open("http://www.example.com/") self.assert_(not hh.req.has_header("Cookie"))
def _enableStaticProvisioning_BT200(self, vars): try: # Login into interface cookiejar = cookielib.CookieJar( cookielib.DefaultCookiePolicy(rfc2965=True)) opener = urllib2.build_opener( urllib2.HTTPCookieProcessor(cookiejar)) response = opener.open( 'http://' + self._ip + '/dologin.htm', urllib.urlencode({ 'Login': '******', 'P2': self._http_password, 'gnkey': '0b82' })) body = response.read() if 'dologin.htm' in body: logging.error('Endpoint %s@%s BT200 - dologin failed login' % (self._vendorname, self._ip)) return False # Force cookie version to 0 for cookie in cookiejar: cookie.version = 0 response = opener.open('http://' + self._ip + '/update.htm', urllib.urlencode(vars) + '&gnkey=0b82') body = response.read() if 'dologin.htm' in body: logging.error( 'Endpoint %s@%s BT200 - dologin failed to keep session' % (self._vendorname, self._ip)) return False return True except urllib2.HTTPError, e: logging.error( 'Endpoint %s@%s BT200 failed to send vars to interface - %s' % (self._vendorname, self._ip, str(e))) return False
filename = ''.join(c for c in name if c in valid_chrs) return filename def fetch_pair(self, (lSpecies, rSpecies)): while True: try: self.attempt_fetch_pair((lSpecies, rSpecies)) break except urllib2.URLError as e: print "Error fetching (%s,%s): %s" % (lSpecies, rSpecies, e) return (lSpecies, rSpecies) def attempt_fetch_pair(self, (lSpecies, rSpecies)): # First grab the CSRF, cookies with a GET request cjar = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cjar)) request = urllib2.Request('http://roundup.hms.harvard.edu/retrieve/') response = opener.open(request).read() rtree = lxml.html.document_fromstring(response) key = rtree.xpath('//input[@name="csrfmiddlewaretoken"]/@value')[0] # Now use the session ID to submit the form params = [] params.append(('csrfmiddlewaretoken', key)) params.append(('genomes_filter', 'E')) params.append(('genomes_filter', 'B')) params.append(('genomes_filter', 'A')) params.append(('genomes_filter', 'V')) params.append(('genome_choices', 'Escherichia coli 536')) params.append(('genomes', '%s\r\n%s\r\n' % (lSpecies, rSpecies))) params.append(('divergence', '0.8')) params.append(('evalue', '1e-5'))
def _enableStaticProvisioning_GXV(self, vars): try: # Login into interface opener = urllib2.build_opener(urllib2.HTTPCookieProcessor()) response = opener.open('http://' + self._ip + '/manager?' + urllib.urlencode({ 'action': 'login', 'Username': self._http_username, 'Secret': self._http_password, 'time': (int)(time.time()) })) body = response.read() if 'Error' in body: logging.error('Endpoint %s@%s GXV - dologin failed login' % (self._vendorname, self._ip)) return False # For this interface, the variables are translated as follows: The # source key of the form Pxxxx produces a variable var-dddd where # dddd is a counter. The corresponding value produces a variable # val-dddd with the same counter varcount = 0 submitvars = {'action': 'put', 'time': (int)(time.time())} for pk in vars: varkey = 'var-' + ('%04d' % (varcount, )) varval = 'val-' + ('%04d' % (varcount, )) submitvars[varkey] = pk[1:] submitvars[varval] = vars[pk] varcount += 1 response = opener.open('http://' + self._ip + '/manager?' + urllib.urlencode(submitvars)) body = response.read() if not ('Success' in body): logging.error( 'Endpoint %s@%s GXV - dologin failed to keep session' % (self._vendorname, self._ip)) return False # Phonebook programming is a special case. submitvars = { 'action': 'putdownphbk', 'time': (int)(time.time()), 'url': vars['P331'], 'mode': 2, # HTTP 'clear-old': 1, 'flag': 1, # 1 forces download right now 'interval': vars['P332'], 'rm-redup': 1 } response = opener.open('http://' + self._ip + '/manager?' + urllib.urlencode(submitvars)) body = response.read() if not ('Success' in body): logging.error( 'Endpoint %s@%s GXV - could not reprogram phonebook' % (self._vendorname, self._ip)) return True except urllib2.HTTPError, e: logging.error( 'Endpoint %s@%s GXV failed to send vars to interface - %s' % (self._vendorname, self._ip, str(e))) return False
def _sendPhoneConfiguration(self, xmlcontent): try: # Login into interface opener = urllib2.build_opener(urllib2.HTTPCookieProcessor()) response = opener.open( 'http://' + self._ip + '/console/j_security_check', urllib.urlencode({ 'submit': 'Login', 'j_username': self._http_username, 'j_password': self._http_password })) body = response.read() if not '/console/start' in body: logging.error( 'Endpoint %s@%s - j_security_check failed login' % (self._vendorname, self._ip)) return False # Build a custom request with form data boundary = '------------------ENDPOINTCONFIG' postdata = '--' + boundary + '\r\n' +\ 'Content-Disposition: form-data; name="COMMAND"\r\n' +\ '\r\n' +\ 'RX' + '\r\n' +\ '--' + boundary + '\r\n' +\ 'Content-Disposition: form-data; name="RX"; filename="config.xml"\r\n' +\ 'Content-Type: text/xml\r\n' +\ '\r\n' +\ xmlcontent + '\r\n' +\ '--' + boundary + '--\r\n' filerequest = urllib2.Request( 'http://' + self._ip + '/console/configuration', postdata, {'Content-Type': 'multipart/form-data; boundary=' + boundary}) # The phone configuration restore is known to hang for 25-30 seconds oldtimeout = socket.getdefaulttimeout() socket.setdefaulttimeout(40) try: response = opener.open(filerequest) finally: socket.setdefaulttimeout(oldtimeout) body = response.read() if not 'Configuration restore complete' in body: logging.error('Endpoint %s@%s - configuration post failed' % (self._vendorname, self._ip)) return False # Attempt to set just the provisioning server response = opener.open( 'http://' + self._ip + '/console/general', urllib.urlencode({ 'COMMAND': 'AP', '@p.provisioningServer': self._serverip, '@dhcp_option_protocol': 'TFTP' })) body = response.read() # Since the web interface will NOT immediately apply the network # changes, we need to go raw and ssh into the phone. Additionally, # if we are changing the network setting from DHCP to static or # viceversa, we expect the SSH connection to be disconnected in the # middle of the update. A timeout of 5 seconds should do it. if self._dhcp: command = '/root/dhcp-configure.sh' else: dns2 = 'none' if self._static_dns2 != None: dns2 = self._static_dns2 command = '/root/staticip-configure.sh %s %s %s %s %s' %\ (self._static_ip, self._static_mask, self._static_gw, self._static_dns1, dns2) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.WarningPolicy()) ssh.connect(self._ip, username=self._ssh_username, password=self._ssh_password, timeout=5) stdin, stdout, stderr = ssh.exec_command(command) logging.info( 'Endpoint %s@%s - about to set timeout of %d on stdout' % ( self._vendorname, self._ip, oldtimeout, )) stdout.channel.settimeout(5) try: s = stdout.read() logging.info('Endpoint %s@%s - answer follows:\n%s' % ( self._vendorname, self._ip, s, )) except socket.error, e: pass ssh.close() return True
def _enableStaticProvisioning_GXV(self, vars): try: # Login into interface opener = urllib2.build_opener(urllib2.HTTPCookieProcessor()) headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36', } opener.addheaders = headers.items() response = opener.open('http://' + self._ip + '/manager?' + urllib.urlencode({ 'action': 'login', 'Username': self._http_username, 'Secret': self._http_password, 'time': (int)(time.time()) })) body = response.read() if 'Error' in body: logging.error('Endpoint %s@%s GXV - dologin failed login' % (self._vendorname, self._ip)) return False # For this interface, the variables are translated as follows: The # source key of the form Pxxxx produces a variable var-dddd where # dddd is a counter. The corresponding value produces a variable # val-dddd with the same counter varcount = 0 submitvars = {'action': 'put', 'time': (int)(time.time())} for pk in vars: varkey = 'var-' + ('%04d' % (varcount, )) varval = 'val-' + ('%04d' % (varcount, )) submitvars[varkey] = pk[1:] submitvars[varval] = vars[pk] varcount += 1 response = opener.open('http://' + self._ip + '/manager?' + urllib.urlencode(submitvars)) body = response.read() if not ('Success' in body): logging.error( 'Endpoint %s@%s GXV - dologin failed to keep session' % (self._vendorname, self._ip)) return False # Phonebook programming is a special case. submitvars = { 'action': 'putdownphbk', 'time': (int)(time.time()), 'url': vars['P331'], 'mode': 2, # HTTP 'clear-old': 1, 'flag': 1, # 1 forces download right now 'interval': vars['P332'], 'rm-redup': 1 } # This generates problems with GXV3240 # logging.info('Endpoint %s@%s GXV failed to send vars to interface - %s' % # (self._vendorname, self._ip, 'http://' + self._ip + '/manager?' + urllib.urlencode(submitvars))) # response = opener.open('http://' + self._ip + '/manager?' + urllib.urlencode(submitvars)) # body = response.read() # if not ('Success' in body): # logging.error('Endpoint %s@%s GXV - could not reprogram phonebook' % # (self._vendorname, self._ip)) return True except httplib.HTTPException as e: logging.info( 'Endpoint %s@%s GXV failed to send vars to interface - %s' % (self._vendorname, self._ip, str(e))) return True except urllib2.HTTPError, e: logging.error( 'Endpoint %s@%s GXV failed to send vars to interface - %s' % (self._vendorname, self._ip, str(e))) return False