Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
146
venv/Lib/site-packages/win32/Demos/security/sspi/fetch_url.py
Normal file
146
venv/Lib/site-packages/win32/Demos/security/sspi/fetch_url.py
Normal file
|
@ -0,0 +1,146 @@
|
|||
"""
|
||||
Fetches a URL from a web-server supporting NTLM authentication
|
||||
eg, IIS.
|
||||
|
||||
If no arguments are specified, a default of http://localhost/localstart.asp
|
||||
is used. This script does follow simple 302 redirections, so pointing at the
|
||||
root of an IIS server is should work.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
import http.client
|
||||
import urllib.parse
|
||||
from base64 import encodestring, decodestring
|
||||
|
||||
from sspi import ClientAuth
|
||||
|
||||
import optparse # sorry, this demo needs 2.3+
|
||||
|
||||
options = None # set to optparse options object
|
||||
|
||||
def open_url(host, url):
|
||||
h = http.client.HTTPConnection(host)
|
||||
# h.set_debuglevel(9)
|
||||
h.putrequest('GET', url)
|
||||
h.endheaders()
|
||||
resp = h.getresponse()
|
||||
print("Initial response is", resp.status, resp.reason)
|
||||
body = resp.read()
|
||||
if resp.status == 302: # object moved
|
||||
url = "/" + resp.msg["location"]
|
||||
resp.close()
|
||||
h.putrequest('GET', url)
|
||||
h.endheaders()
|
||||
resp = h.getresponse()
|
||||
print("After redirect response is", resp.status, resp.reason)
|
||||
if options.show_headers:
|
||||
print("Initial response headers:")
|
||||
for name, val in list(resp.msg.items()):
|
||||
print(" %s: %s" % (name, val))
|
||||
if options.show_body:
|
||||
print(body)
|
||||
if resp.status == 401:
|
||||
# 401: Unauthorized - here is where the real work starts
|
||||
auth_info = None
|
||||
if options.user or options.domain or options.password:
|
||||
auth_info = options.user, options.domain, options.password
|
||||
ca = ClientAuth("NTLM", auth_info=auth_info)
|
||||
auth_scheme = ca.pkg_info['Name']
|
||||
data = None
|
||||
while 1:
|
||||
err, out_buf = ca.authorize(data)
|
||||
data = out_buf[0].Buffer
|
||||
# Encode it as base64 as required by HTTP
|
||||
auth = encodestring(data).replace("\012", "")
|
||||
h.putrequest('GET', url)
|
||||
h.putheader('Authorization', auth_scheme + ' ' + auth)
|
||||
h.putheader('Content-Length', '0')
|
||||
h.endheaders()
|
||||
resp = h.getresponse()
|
||||
if options.show_headers:
|
||||
print("Token dance headers:")
|
||||
for name, val in list(resp.msg.items()):
|
||||
print(" %s: %s" % (name, val))
|
||||
|
||||
if err==0:
|
||||
break
|
||||
else:
|
||||
if resp.status != 401:
|
||||
print("Eeek - got response", resp.status)
|
||||
cl = resp.msg.get("content-length")
|
||||
if cl:
|
||||
print(repr(resp.read(int(cl))))
|
||||
else:
|
||||
print("no content!")
|
||||
|
||||
assert resp.status == 401, resp.status
|
||||
|
||||
assert not resp.will_close, "NTLM is per-connection - must not close"
|
||||
schemes = [s.strip() for s in resp.msg.get("WWW-Authenticate", "").split(",")]
|
||||
for scheme in schemes:
|
||||
if scheme.startswith(auth_scheme):
|
||||
data = decodestring(scheme[len(auth_scheme)+1:])
|
||||
break
|
||||
else:
|
||||
print("Could not find scheme '%s' in schemes %r" % (auth_scheme, schemes))
|
||||
break
|
||||
|
||||
resp.read()
|
||||
print("Final response status is", resp.status, resp.reason)
|
||||
if resp.status == 200:
|
||||
# Worked!
|
||||
# Check we can read it again without re-authenticating.
|
||||
if resp.will_close:
|
||||
print("EEEK - response will close, but NTLM is per connection - it must stay open")
|
||||
body = resp.read()
|
||||
if options.show_body:
|
||||
print("Final response body:")
|
||||
print(body)
|
||||
h.putrequest('GET', url)
|
||||
h.endheaders()
|
||||
resp = h.getresponse()
|
||||
print("Second fetch response is", resp.status, resp.reason)
|
||||
if options.show_headers:
|
||||
print("Second response headers:")
|
||||
for name, val in list(resp.msg.items()):
|
||||
print(" %s: %s" % (name, val))
|
||||
|
||||
resp.read(int(resp.msg.get("content-length", 0)))
|
||||
elif resp.status == 500:
|
||||
print("Error text")
|
||||
print(resp.read())
|
||||
else:
|
||||
if options.show_body:
|
||||
cl = resp.msg.get("content-length")
|
||||
print(resp.read(int(cl)))
|
||||
|
||||
if __name__=='__main__':
|
||||
parser = optparse.OptionParser(description=__doc__)
|
||||
|
||||
parser.add_option("", "--show-body", action="store_true",
|
||||
help="print the body of each response as it is received")
|
||||
|
||||
parser.add_option("", "--show-headers", action="store_true",
|
||||
help="print the headers of each response as it is received")
|
||||
|
||||
parser.add_option("", "--user", action="store",
|
||||
help="The username to login with")
|
||||
|
||||
parser.add_option("", "--password", action="store",
|
||||
help="The password to login with")
|
||||
|
||||
parser.add_option("", "--domain", action="store",
|
||||
help="The domain to login to")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
if not args:
|
||||
print("Run with --help for usage details")
|
||||
args = ["http://localhost/localstart.asp"]
|
||||
for url in args:
|
||||
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url)
|
||||
if (scheme != "http") or params or query or fragment:
|
||||
parser.error("Scheme must be http, URL must be simple")
|
||||
|
||||
print("Opening '%s' from '%s'" % (path, netloc))
|
||||
r = open_url(netloc, path)
|
Loading…
Add table
Add a link
Reference in a new issue