def gethttpdigestauth(self, si, wwwauthorize=None): # Check the nonce cache to see if we've used this user before user = [self.user, si.user][self.user == ""] pswd = [self.pswd, si.pswd][self.pswd == ""] details = None if user in self.manager.digestCache: details = self.manager.digestCache[user] else: http = SmartHTTPConnection(si.host, si.port, si.ssl) try: http.request("OPTIONS", self.getURI(si)) response = http.getresponse() finally: http.close() if response.status == 401: wwwauthorize = response.msg.getheaders("WWW-Authenticate") for item in wwwauthorize: if not item.startswith("digest "): continue wwwauthorize = item[7:] def unq(s): if s[0] == s[-1] == '"': return s[1:-1] return s parts = wwwauthorize.split(',') details = {} for (k, v) in [p.split('=', 1) for p in parts]: details[k.strip()] = unq(v.strip()) self.manager.digestCache[user] = details break if details: digest = calcResponse( calcHA1(details.get('algorithm'), user, details.get('realm'), pswd, details.get('nonce'), details.get('cnonce')), details.get('algorithm'), details.get('nonce'), details.get('nc'), details.get('cnonce'), details.get('qop'), self.method, self.getURI(si), None ) if details.get('qop'): response = ('Digest username="******", realm="%s", ' 'nonce="%s", uri="%s", ' 'response=%s, algorithm=%s, cnonce="%s", qop=%s, nc=%s' % (user, details.get('realm'), details.get('nonce'), self.getURI(si), digest, details.get('algorithm'), details.get('cnonce'), details.get('qop'), details.get('nc'),)) else: response = ('Digest username="******", realm="%s", ' 'nonce="%s", uri="%s", ' 'response=%s, algorithm=%s' % (user, details.get('realm'), details.get('nonce'), self.getURI(si), digest, details.get('algorithm'),)) return response else: return ""
def dorequest(self, req, details=False, doverify=True, forceverify=False, stats=None, etags=None, label="", count=1): req.count = count if isinstance(req, pause): # Useful for pausing at a particular point print "Paused" sys.stdin.readline() return True, "", None, None if len(req.missingFeatures()) != 0: return True, "", None, None if len(req.excludedFeatures()) != 0: return True, "", None, None # Special check for DELETEALL if req.method == "DELETEALL": for ruri in req.ruris: collection = (ruri, req.user, req.pswd) hrefs = self.dofindall(collection, label="%s | %s" % (label, "DELETEALL")) if not self.dodeleteall(hrefs, label="%s | %s" % (label, "DELETEALL")): return False, "DELETEALL failed for: {r}".format(r=ruri), None, None return True, "", None, None # Special for delay elif req.method == "DELAY": # self.ruri contains a numeric delay in seconds delay = int(req.ruri) starttime = time.time() while (time.time() < starttime + delay): pass return True, "", None, None # Special for GETNEW elif req.method == "GETNEW": collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindnew(collection, label=label) if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) req.method = "GET" req.ruri = "$" # Special for FINDNEW elif req.method == "FINDNEW": collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindnew(collection, label=label) if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) return True, "", None, None # Special for GETOTHER elif req.method == "GETOTHER": collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindnew(collection, label=label, other=True) if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) req.method = "GET" req.ruri = "$" # Special check for WAITCOUNT elif req.method.startswith("WAITCOUNT"): count = int(req.method[10:]) for ruri in req.ruris: collection = (ruri, req.user, req.pswd) waitresult, waitdetails = self.dowaitcount(collection, count, label=label) if not waitresult: return False, "Count did not change: {w}".format(w=waitdetails), None, None else: return True, "", None, None # Special check for WAITDELETEALL elif req.method.startswith("WAITDELETEALL"): count = int(req.method[len("WAITDELETEALL"):]) for ruri in req.ruris: collection = (ruri, req.user, req.pswd) waitresult, waitdetails = self.dowaitcount(collection, count, label=label) if waitresult: hrefs = self.dofindall(collection, label="%s | %s" % (label, "DELETEALL")) self.dodeleteall(hrefs, label="%s | %s" % (label, "DELETEALL")) else: return False, "Count did not change: {w}".format(w=waitdetails), None, None else: return True, "", None, None result = True resulttxt = "" response = None respdata = None method = req.method uri = req.getURI(self.manager.server_info) if (uri == "$"): uri = self.grabbedlocation headers = req.getHeaders(self.manager.server_info) data = req.getData() # Cache delayed delete if req.end_delete: self.end_deletes.append((uri, req.user, req.pswd)) if details: resulttxt += " %s: %s\n" % (method, uri) # Special for GETCHANGED if req.method == "GETCHANGED": if not self.dowaitchanged( uri, etags[uri], req.user, req.pswd, label=label ): return False, "Resource did not change", None, None method = "GET" # Start request timer if required if stats: stats.startTimer() # Do the http request http = SmartHTTPConnection(req.host, req.port, self.manager.server_info.ssl) if 'User-Agent' not in headers and label is not None: headers['User-Agent'] = label.encode("utf-8") try: puri = list(urlparse.urlparse(uri)) if req.ruri_quote: puri[2] = urllib.quote(puri[2]) quri = urlparse.urlunparse(puri) http.request(method, quri, data, headers) response = http.getresponse() respdata = None respdata = response.read() finally: http.close() # Stop request timer before verification if stats: stats.endTimer() if doverify and (respdata != None): result, txt = self.verifyrequest(req, uri, response, respdata) resulttxt += txt elif forceverify: result = (response.status / 100 == 2) if not result: resulttxt += "Status Code Error: %d" % response.status if req.print_request or (self.manager.print_request_response_on_error and not result): resulttxt += "\n-------BEGIN:REQUEST-------\n" resulttxt += http.requestData resulttxt += "\n--------END:REQUEST--------\n" if req.print_response or (self.manager.print_request_response_on_error and not result): resulttxt += "\n-------BEGIN:RESPONSE-------\n" resulttxt += "%s %s %s\n" % (getVersionStringFromResponse(response), response.status, response.reason,) resulttxt += str(response.msg) + "\n" + respdata resulttxt += "\n--------END:RESPONSE--------\n" if etags is not None and req.method == "GET": hdrs = response.msg.getheaders("Etag") if hdrs: etags[uri] = hdrs[0].encode("utf-8") if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) if req.grabcount: ctr = None if result and (response is not None) and (response.status == 207) and (respdata is not None): tree = ElementTree(file=StringIO(respdata)) ctr = len(tree.findall("{DAV:}response")) - 1 if ctr == None or ctr == -1: result = False resulttxt += "\nCould not count resources in response\n" else: self.manager.server_info.addextrasubs({req.grabcount: str(ctr)}) if req.grabheader: for hdrname, variable in req.grabheader: hdrs = response.msg.getheaders(hdrname) if hdrs: self.manager.server_info.addextrasubs({variable: hdrs[0].encode("utf-8")}) else: result = False resulttxt += "\nHeader %s was not extracted from response\n" % (hdrname,) if req.grabproperty: if response.status == 207: for propname, variable in req.grabproperty: # grab the property here propvalue = self.extractProperty(propname, respdata) if propvalue == None: result = False resulttxt += "\nProperty %s was not extracted from multistatus response\n" % (propname,) else: self.manager.server_info.addextrasubs({variable: propvalue.encode("utf-8")}) if req.grabelement: for item in req.grabelement: if len(item) == 2: elementpath, variables = item parent = None else: elementpath, parent, variables = item parent = self.manager.server_info.extrasubs(parent) # grab the property here elementvalues = self.extractElements(elementpath, parent, respdata) if elementvalues == None: result = False resulttxt += "\nElement %s was not extracted from response\n" % (elementpath,) elif len(variables) != len(elementvalues): result = False resulttxt += "\n%d found but expecting %d for element %s from response\n" % (len(elementvalues), len(variables), elementpath,) else: for variable, elementvalue in zip(variables, elementvalues): self.manager.server_info.addextrasubs({variable: elementvalue.encode("utf-8") if elementvalue else ""}) if req.grabjson: for pointer, variables in req.grabjson: # grab the JSON value here pointervalues = self.extractPointer(pointer, respdata) if pointervalues == None: result = False resulttxt += "\Pointer %s was not extracted from response\n" % (pointer,) elif len(variables) != len(pointervalues): result = False resulttxt += "\n%d found but expecting %d for pointer %s from response\n" % (len(pointervalues), len(variables), pointer,) else: for variable, pointervalue in zip(variables, pointervalues): self.manager.server_info.addextrasubs({variable: pointervalue.encode("utf-8") if pointervalue else ""}) if req.grabcalprop: for propname, variable in req.grabcalprop: # grab the property here propname = self.manager.server_info.subs(propname) propname = self.manager.server_info.extrasubs(propname) propvalue = self.extractCalProperty(propname, respdata) if propvalue == None: result = False resulttxt += "\nCalendar property %s was not extracted from response\n" % (propname,) else: self.manager.server_info.addextrasubs({variable: propvalue.encode("utf-8")}) if req.grabcalparam: for paramname, variable in req.grabcalparam: # grab the property here paramname = self.manager.server_info.subs(paramname) paramname = self.manager.server_info.extrasubs(paramname) paramvalue = self.extractCalParameter(paramname, respdata) if paramvalue == None: result = False resulttxt += "\nCalendar Parameter %s was not extracted from response\n" % (paramname,) else: self.manager.server_info.addextrasubs({variable: paramvalue.encode("utf-8")}) return result, resulttxt, response, respdata
def gethttpdigestauth(self, si, wwwauthorize=None): # Check the nonce cache to see if we've used this user before, or if the nonce is more than 5 minutes old user = [self.user, si.user][self.user == ""] pswd = [self.pswd, si.pswd][self.pswd == ""] details = None if user in self.manager.digestCache and self.manager.digestCache[user][ "max-nonce-time"] > time.time(): details = self.manager.digestCache[user] else: # Redo digest auth from scratch to get a new nonce etc http = SmartHTTPConnection(si.host, si.port, si.ssl, si.afunix) try: puri = list(urlparse.urlparse(self.getURI(si))) puri[2] = urllib.quote(puri[2]) quri = urlparse.urlunparse(puri) http.request("OPTIONS", quri) response = http.getresponse() finally: http.close() if response.status == 401: wwwauthorize = response.msg.getheaders("WWW-Authenticate") for item in wwwauthorize: if not item.lower().startswith("digest "): continue wwwauthorize = item[7:] def unq(s): if s[0] == s[-1] == '"': return s[1:-1] return s parts = wwwauthorize.split(',') details = {} for (k, v) in [p.split('=', 1) for p in parts]: details[k.strip()] = unq(v.strip()) details["max-nonce-time"] = time.time() + 600 self.manager.digestCache[user] = details break if details: if details.get('qop'): if self.nc.get(details.get('nonce')) is None: self.nc[details.get('nonce')] = 1 else: self.nc[details.get('nonce')] += 1 details['nc'] = "%08x" % self.nc[details.get('nonce')] if details.get('cnonce') is None: details['cnonce'] = "D4AAE4FF-ADA1-4149-BFE2-B506F9264318" digest = calcResponse( calcHA1(details.get('algorithm', 'md5'), user, details.get('realm'), pswd, details.get('nonce'), details.get('cnonce')), details.get('algorithm', 'md5'), details.get('nonce'), details.get('nc'), details.get('cnonce'), details.get('qop'), self.method, self.getURI(si), None) if details.get('qop'): response = ( 'Digest username="******", realm="%s", ' 'nonce="%s", uri="%s", ' 'response=%s, algorithm=%s, cnonce="%s", qop=%s, nc=%s' % ( user, details.get('realm'), details.get('nonce'), self.getURI(si), digest, details.get('algorithm', 'md5'), details.get('cnonce'), details.get('qop'), details.get('nc'), )) else: response = ('Digest username="******", realm="%s", ' 'nonce="%s", uri="%s", ' 'response=%s, algorithm=%s' % ( user, details.get('realm'), details.get('nonce'), self.getURI(si), digest, details.get('algorithm'), )) return response else: return ""
def dorequest(self, req, details=False, doverify=True, forceverify=False, stats=None, etags=None, label="", count=1): req.count = count if isinstance(req, pause): # Useful for pausing at a particular point print "Paused" sys.stdin.readline() return True, "", None, None if len(req.missingFeatures()) != 0: return True, "", None, None if len(req.excludedFeatures()) != 0: return True, "", None, None # Special check for DELETEALL if req.method == "DELETEALL": for ruri in req.ruris: collection = (ruri, req.user, req.pswd) hrefs = self.dofindall(req, collection, label="%s | %s" % (label, "DELETEALL")) if not self.dodeleteall(req, hrefs, label="%s | %s" % (label, "DELETEALL")): return False, "DELETEALL failed for: {r}".format(r=ruri), None, None return True, "", None, None # Special for delay elif req.method == "DELAY": # self.ruri contains a numeric delay in seconds delay = int(req.ruri) starttime = time.time() while (time.time() < starttime + delay): pass return True, "", None, None # Special for GETNEW elif req.method == "GETNEW": collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindnew(req, collection, label=label) if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) req.method = "GET" req.ruri = "$" # Special for FINDNEW elif req.method == "FINDNEW": collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindnew(req, collection, label=label) if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) return True, "", None, None # Special for GETOTHER elif req.method == "GETOTHER": collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindnew(req, collection, label=label, other=True) if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) req.method = "GET" req.ruri = "$" # Special for GETCONTAINS elif req.method.startswith("GETCONTAINS"): match = req.method[12:] collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindcontains(req, collection, match, label=label) if not self.grabbedlocation: return False, "No matching resource", None, None if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) req.method = "GET" req.ruri = "$" # Special check for WAITCOUNT elif req.method.startswith("WAITCOUNT"): count = int(req.method[10:]) for ruri in req.ruris: collection = (ruri, req.user, req.pswd) waitresult, waitdetails = self.dowaitcount(req, collection, count, label=label) if not waitresult: return False, "Count did not change: {w}".format(w=waitdetails), None, None else: return True, "", None, None # Special check for WAITDELETEALL elif req.method.startswith("WAITDELETEALL"): count = int(req.method[len("WAITDELETEALL"):]) for ruri in req.ruris: collection = (ruri, req.user, req.pswd) waitresult, waitdetails = self.dowaitcount(req, collection, count, label=label) if waitresult: hrefs = self.dofindall(req, collection, label="%s | %s" % (label, "DELETEALL")) self.dodeleteall(req, hrefs, label="%s | %s" % (label, "DELETEALL")) else: return False, "Count did not change: {w}".format(w=waitdetails), None, None else: return True, "", None, None result = True resulttxt = "" response = None respdata = None method = req.method uri = req.getURI(self.manager.server_info) if (uri == "$"): uri = self.grabbedlocation headers = req.getHeaders(self.manager.server_info) data = req.getData() # Cache delayed delete if req.end_delete: self.end_deletes.append((uri, req,)) if details: resulttxt += " %s: %s\n" % (method, uri) # Special for GETCHANGED if req.method == "GETCHANGED": if not self.dowaitchanged( req, uri, etags[uri], req.user, req.pswd, label=label ): return False, "Resource did not change", None, None method = "GET" # Start request timer if required if stats: stats.startTimer() # Do the http request http = SmartHTTPConnection( req.host, req.port, self.manager.server_info.ssl, afunix=req.afunix, cert=os.path.join(self.manager.server_info.certdir, req.cert) if req.cert else None ) if 'User-Agent' not in headers and label is not None: headers['User-Agent'] = label.encode("utf-8") try: puri = list(urlparse.urlparse(uri)) if req.ruri_quote: puri[2] = urllib.quote(puri[2]) quri = urlparse.urlunparse(puri) http.request(method, quri, data, headers) response = http.getresponse() respdata = None respdata = response.read() finally: http.close() # Stop request timer before verification if stats: stats.endTimer() if doverify and (respdata is not None): result, txt = self.verifyrequest(req, uri, response, respdata) resulttxt += txt elif forceverify: result = (response.status / 100 == 2) if not result: resulttxt += "Status Code Error: %d" % response.status if req.print_request or (self.manager.print_request_response_on_error and not result and not req.wait_for_success): requesttxt = "\n-------BEGIN:REQUEST-------\n" requesttxt += http.requestData requesttxt += "\n--------END:REQUEST--------\n" self.manager.message("protocol", requesttxt) if req.print_response or (self.manager.print_request_response_on_error and not result and not req.wait_for_success): responsetxt = "\n-------BEGIN:RESPONSE-------\n" responsetxt += "%s %s %s\n" % (getVersionStringFromResponse(response), response.status, response.reason,) responsetxt += str(response.msg) + "\n" + respdata responsetxt += "\n--------END:RESPONSE--------\n" self.manager.message("protocol", responsetxt) if etags is not None and req.method == "GET": hdrs = response.msg.getheaders("Etag") if hdrs: etags[uri] = hdrs[0].encode("utf-8") if req.graburi: self.manager.server_info.addextrasubs({req.graburi: self.grabbedlocation}) if req.grabcount: ctr = None if result and (response is not None) and (response.status == 207) and (respdata is not None): tree = ElementTree(file=StringIO(respdata)) ctr = len(tree.findall("{DAV:}response")) - 1 if ctr is None or ctr == -1: result = False resulttxt += "\nCould not count resources in response\n" else: self.manager.server_info.addextrasubs({req.grabcount: str(ctr)}) if req.grabheader: for hdrname, variable in req.grabheader: hdrs = response.msg.getheaders(hdrname) if hdrs: self.manager.server_info.addextrasubs({variable: hdrs[0].encode("utf-8")}) else: result = False resulttxt += "\nHeader %s was not extracted from response\n" % (hdrname,) if req.grabproperty: if response.status == 207: for propname, variable in req.grabproperty: # grab the property here propvalue = self.extractProperty(propname, respdata) if propvalue is None: result = False resulttxt += "\nProperty %s was not extracted from multistatus response\n" % (propname,) else: self.manager.server_info.addextrasubs({variable: propvalue.encode("utf-8")}) if req.grabelement: for item in req.grabelement: if len(item) == 2: elementpath, variables = item parent = None else: elementpath, parent, variables = item parent = self.manager.server_info.extrasubs(parent) # grab the property here elementvalues = self.extractElements(elementpath, parent, respdata) if elementvalues is None: result = False resulttxt += "\nElement %s was not extracted from response\n" % (elementpath,) elif len(variables) != len(elementvalues): result = False resulttxt += "\n%d found but expecting %d for element %s from response\n" % (len(elementvalues), len(variables), elementpath,) else: for variable, elementvalue in zip(variables, elementvalues): self.manager.server_info.addextrasubs({variable: elementvalue.encode("utf-8") if elementvalue else ""}) if req.grabjson: for pointer, variables in req.grabjson: # grab the JSON value here pointervalues = self.extractPointer(pointer, respdata) if pointervalues is None: result = False resulttxt += "\Pointer %s was not extracted from response\n" % (pointer,) elif len(variables) != len(pointervalues): result = False resulttxt += "\n%d found but expecting %d for pointer %s from response\n" % (len(pointervalues), len(variables), pointer,) else: for variable, pointervalue in zip(variables, pointervalues): self.manager.server_info.addextrasubs({variable: pointervalue.encode("utf-8") if pointervalue else ""}) if req.grabcalprop: for propname, variable in req.grabcalprop: # grab the property here propname = self.manager.server_info.subs(propname) propname = self.manager.server_info.extrasubs(propname) propvalue = self.extractCalProperty(propname, respdata) if propvalue is None: result = False resulttxt += "\nCalendar property %s was not extracted from response\n" % (propname,) else: self.manager.server_info.addextrasubs({variable: propvalue.encode("utf-8")}) if req.grabcalparam: for paramname, variable in req.grabcalparam: # grab the property here paramname = self.manager.server_info.subs(paramname) paramname = self.manager.server_info.extrasubs(paramname) paramvalue = self.extractCalParameter(paramname, respdata) if paramvalue is None: result = False resulttxt += "\nCalendar Parameter %s was not extracted from response\n" % (paramname,) else: self.manager.server_info.addextrasubs({variable: paramvalue.encode("utf-8")}) return result, resulttxt, response, respdata
def dorequest( self, req, details=False, doverify = True, forceverify = False, stats = None, etags = None, label = "", count = 1 ): req.count = count if isinstance(req, pause): # Useful for pausing at a particular point print "Paused" sys.stdin.readline() return True, "", None, None if len(req.missingFeatures()) != 0: #self.manager.log(manager.LOG_HIGH, "[IGNORED]") #self.manager.log(manager.LOG_HIGH, " Missing features: %s" % (", ".join(sorted(req.missingFeatures())),)) return True, "", None, None if len(req.excludedFeatures()) != 0: #self.manager.log(manager.LOG_HIGH, "[IGNORED]") #self.manager.log(manager.LOG_HIGH, " Excluded features: %s" % (", ".join(sorted(req.excludedFeatures())),)) return True, "", None, None # Special check for DELETEALL if req.method == "DELETEALL": for ruri in req.ruris: collection = (ruri, req.user, req.pswd) hrefs = self.dofindall(collection, label="%s | %s" % (label, "DELETEALL")) self.dodeleteall(hrefs, label="%s | %s" % (label, "DELETEALL")) return True, "", None, None # Special for delay elif req.method == "DELAY": # self.ruri contains a numeric delay in seconds delay = int(req.ruri) starttime = time.time() while (time.time() < starttime + delay): pass return True, "", None, None # Special for GETNEW elif req.method == "GETNEW": collection = (req.ruri, req.user, req.pswd) self.grabbedlocation = self.dofindnew(collection, label=label) req.method = "GET" req.ruri = "$" # Special check for WAITCOUNT elif req.method.startswith("WAITCOUNT"): count = int(req.method[10:]) collection = (req.ruri, req.user, req.pswd) if self.dowaitcount(collection, count, label=label): return True, "", None, None else: return False, "Count did not change", None, None elif req.method == "BREAK": # Useful for setting a break point return True, "", None, None elif req.method == "PAUSE": # Useful for pausing at a particular point print "Paused" sys.stdin.readline() return True, "", None, None result = True; resulttxt = "" response = None respdata = None method = req.method uri = req.getURI( self.manager.server_info ) if (uri == "$"): uri = self.grabbedlocation headers = req.getHeaders( self.manager.server_info ) data = req.getData() # Cache delayed delete if req.end_delete: self.end_deletes.append( (uri, req.user, req.pswd) ) if details: resulttxt += " %s: %s\n" % ( method, uri ) # Special for GETCHANGED if req.method == "GETCHANGED": if not self.dowaitchanged(uri, etags[uri], req.user, req.pswd, label=label): return False, "Resource did not change", None, None method = "GET" # Start request timer if required if stats: stats.startTimer() # Do the http request http = SmartHTTPConnection( self.manager.server_info.host, self.manager.server_info.port, self.manager.server_info.ssl ) if not headers.has_key('User-Agent') and label is not None: headers['User-Agent'] = label.encode("utf-8") try: #self.manager.log(manager.LOG_LOW, "Sending request") http.request( method, uri, data, headers ) #self.manager.log(manager.LOG_LOW, "Sent request") response = http.getresponse() respdata = None respdata = response.read() #self.manager.log(manager.LOG_LOW, "Read response") finally: http.close() # Stop request timer before verification if stats: stats.endTimer() if doverify and (respdata != None): result, txt = self.verifyrequest( req, uri, response, respdata ) resulttxt += txt elif forceverify: result = (response.status / 100 == 2) if not result: resulttxt += "Status Code Error: %d" % response.status if req.print_response: resulttxt += "\n-------BEGIN:RESPONSE-------\n" resulttxt += "Status = %d\n" % response.status resulttxt += str(response.msg) + "\n" + respdata resulttxt += "\n--------END:RESPONSE--------\n" if etags is not None and req.method == "GET": hdrs = response.msg.getheaders("Etag") if hdrs: etags[uri] = hdrs[0].encode("utf-8") if req.grabheader: for hdrname, variable in req.grabheader: hdrs = response.msg.getheaders(hdrname) if hdrs: self.manager.server_info.addextrasubs({variable: hdrs[0].encode("utf-8")}) else: result = False resulttxt += "\nHeader %s was not extracted from response\n" % (hdrname,) if req.grabproperty: if response.status == 207: for propname, variable in req.grabproperty: # grab the property here propvalue = self.extractProperty(propname, respdata) if propvalue == None: result = False resulttxt += "\nProperty %s was not extracted from multistatus response\n" % (propname,) else: self.manager.server_info.addextrasubs({variable: propvalue.encode("utf-8")}) if req.grabelement: for elementpath, variables in req.grabelement: # grab the property here elementvalues = self.extractElements(elementpath, respdata) if elementvalues == None: result = False resulttxt += "\nElement %s was not extracted from response\n" % (elementpath,) elif len(variables) != len(elementvalues): result = False resulttxt += "\n%d found but expecting %d for element %s from response\n" % (len(elementvalues), len(variables), elementpath,) else: for variable, elementvalue in zip(variables, elementvalues): self.manager.server_info.addextrasubs({variable: elementvalue.encode("utf-8") if elementvalue else ""}) return result, resulttxt, response, respdata
def gethttpdigestauth(self, si, wwwauthorize=None): # Check the nonce cache to see if we've used this user before, or if the nonce is more than 5 minutes old user = [self.user, si.user][self.user == ""] pswd = [self.pswd, si.pswd][self.pswd == ""] details = None if user in self.manager.digestCache and self.manager.digestCache[user]["max-nonce-time"] > time.time(): details = self.manager.digestCache[user] else: # Redo digest auth from scratch to get a new nonce etc http = SmartHTTPConnection(si.host, si.port, si.ssl, si.afunix) try: puri = list(urlparse.urlparse(self.getURI(si))) puri[2] = urllib.quote(puri[2]) quri = urlparse.urlunparse(puri) http.request("OPTIONS", quri) response = http.getresponse() finally: http.close() if response.status == 401: wwwauthorize = response.msg.getheaders("WWW-Authenticate") for item in wwwauthorize: if not item.lower().startswith("digest "): continue wwwauthorize = item[7:] def unq(s): if s[0] == s[-1] == '"': return s[1:-1] return s parts = wwwauthorize.split(',') details = {} for (k, v) in [p.split('=', 1) for p in parts]: details[k.strip()] = unq(v.strip()) details["max-nonce-time"] = time.time() + 600 self.manager.digestCache[user] = details break if details: if details.get('qop'): if self.nc.get(details.get('nonce')) is None: self.nc[details.get('nonce')] = 1 else: self.nc[details.get('nonce')] += 1 details['nc'] = "%08x" % self.nc[details.get('nonce')] if details.get('cnonce') is None: details['cnonce'] = "D4AAE4FF-ADA1-4149-BFE2-B506F9264318" digest = calcResponse( calcHA1(details.get('algorithm', 'md5'), user, details.get('realm'), pswd, details.get('nonce'), details.get('cnonce')), details.get('algorithm', 'md5'), details.get('nonce'), details.get('nc'), details.get('cnonce'), details.get('qop'), self.method, self.getURI(si), None ) if details.get('qop'): response = ( 'Digest username="******", realm="%s", ' 'nonce="%s", uri="%s", ' 'response=%s, algorithm=%s, cnonce="%s", qop=%s, nc=%s' % (user, details.get('realm'), details.get('nonce'), self.getURI(si), digest, details.get('algorithm', 'md5'), details.get('cnonce'), details.get('qop'), details.get('nc'),) ) else: response = ( 'Digest username="******", realm="%s", ' 'nonce="%s", uri="%s", ' 'response=%s, algorithm=%s' % (user, details.get('realm'), details.get('nonce'), self.getURI(si), digest, details.get('algorithm'),) ) return response else: return ""