mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-01 14:07:48 +00:00
first commit
This commit is contained in:
161
.venv/Lib/site-packages/win32/Demos/security/sspi/fetch_url.py
Normal file
161
.venv/Lib/site-packages/win32/Demos/security/sspi/fetch_url.py
Normal file
@ -0,0 +1,161 @@
|
||||
"""
|
||||
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)
|
@ -0,0 +1,70 @@
|
||||
# A demo of basic SSPI authentication.
|
||||
# There is a 'client' context and a 'server' context - typically these will
|
||||
# be on different machines (here they are in the same process, but the same
|
||||
# concepts apply)
|
||||
import sspi
|
||||
import win32security, sspicon, win32api
|
||||
|
||||
|
||||
def lookup_ret_code(err):
|
||||
for k, v in list(sspicon.__dict__.items()):
|
||||
if k[0:6] in ("SEC_I_", "SEC_E_") and v == err:
|
||||
return k
|
||||
|
||||
|
||||
"""
|
||||
pkg_name='Kerberos'
|
||||
sspiclient=SSPIClient(pkg_name, win32api.GetUserName(), ## target spn is ourself
|
||||
None, None, ## use none for client name and authentication information for current context
|
||||
## u'username', (u'username',u'domain.com',u'passwd'),
|
||||
sspicon.ISC_REQ_INTEGRITY|sspicon.ISC_REQ_SEQUENCE_DETECT|sspicon.ISC_REQ_REPLAY_DETECT| \
|
||||
sspicon.ISC_REQ_DELEGATE|sspicon.ISC_REQ_CONFIDENTIALITY|sspicon.ISC_REQ_USE_SESSION_KEY)
|
||||
sspiserver=SSPIServer(pkg_name, None,
|
||||
sspicon.ASC_REQ_INTEGRITY|sspicon.ASC_REQ_SEQUENCE_DETECT|sspicon.ASC_REQ_REPLAY_DETECT| \
|
||||
sspicon.ASC_REQ_DELEGATE|sspicon.ASC_REQ_CONFIDENTIALITY|sspicon.ASC_REQ_STREAM|sspicon.ASC_REQ_USE_SESSION_KEY)
|
||||
"""
|
||||
|
||||
pkg_name = "NTLM"
|
||||
|
||||
# Setup the 2 contexts.
|
||||
sspiclient = sspi.ClientAuth(pkg_name)
|
||||
sspiserver = sspi.ServerAuth(pkg_name)
|
||||
|
||||
# Perform the authentication dance, each loop exchanging more information
|
||||
# on the way to completing authentication.
|
||||
sec_buffer = None
|
||||
while 1:
|
||||
err, sec_buffer = sspiclient.authorize(sec_buffer)
|
||||
err, sec_buffer = sspiserver.authorize(sec_buffer)
|
||||
if err == 0:
|
||||
break
|
||||
|
||||
# The server can now impersonate the client. In this demo the 2 users will
|
||||
# always be the same.
|
||||
sspiserver.ctxt.ImpersonateSecurityContext()
|
||||
print("Impersonated user: ", win32api.GetUserNameEx(win32api.NameSamCompatible))
|
||||
sspiserver.ctxt.RevertSecurityContext()
|
||||
print("Reverted to self: ", win32api.GetUserName())
|
||||
|
||||
pkg_size_info = sspiclient.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES)
|
||||
# Now sign some data
|
||||
msg = "some data to be encrypted ......"
|
||||
|
||||
sigsize = pkg_size_info["MaxSignature"]
|
||||
sigbuf = win32security.PySecBufferDescType()
|
||||
sigbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
|
||||
sigbuf.append(win32security.PySecBufferType(sigsize, sspicon.SECBUFFER_TOKEN))
|
||||
sigbuf[0].Buffer = msg
|
||||
sspiclient.ctxt.MakeSignature(0, sigbuf, 1)
|
||||
sspiserver.ctxt.VerifySignature(sigbuf, 1)
|
||||
|
||||
# And finally encrypt some.
|
||||
trailersize = pkg_size_info["SecurityTrailer"]
|
||||
encbuf = win32security.PySecBufferDescType()
|
||||
encbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
|
||||
encbuf.append(win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN))
|
||||
encbuf[0].Buffer = msg
|
||||
sspiclient.ctxt.EncryptMessage(0, encbuf, 1)
|
||||
print("Encrypted data:", repr(encbuf[0].Buffer))
|
||||
sspiserver.ctxt.DecryptMessage(encbuf, 1)
|
||||
print("Unencrypted data:", encbuf[0].Buffer)
|
@ -0,0 +1,203 @@
|
||||
"""A sample socket server and client using SSPI authentication and encryption.
|
||||
|
||||
You must run with either 'client' or 'server' as arguments. A server must be
|
||||
running before a client can connect.
|
||||
|
||||
To use with Kerberos you should include in the client options
|
||||
--target-spn=username, where 'username' is the user under which the server is
|
||||
being run.
|
||||
|
||||
Running either the client or server as a different user can be informative.
|
||||
A command-line such as the following may be useful:
|
||||
`runas /user:{user} {fqp}\python.exe {fqp}\socket_server.py --wait client|server`
|
||||
|
||||
{fqp} should specify the relevant fully-qualified path names.
|
||||
|
||||
To use 'runas' with Kerberos, the client program will need to
|
||||
specify --target-spn with the username under which the *server* is running.
|
||||
|
||||
See the SSPI documentation for more details.
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
import struct
|
||||
import socketserver
|
||||
import win32api
|
||||
import http.client
|
||||
import traceback
|
||||
|
||||
import win32security
|
||||
import sspi, sspicon
|
||||
|
||||
import optparse # sorry, this demo needs 2.3+
|
||||
|
||||
options = None # set to optparse object.
|
||||
|
||||
|
||||
def GetUserName():
|
||||
try:
|
||||
return win32api.GetUserName()
|
||||
except win32api.error as details:
|
||||
# Seeing 'access denied' errors here for non-local users (presumably
|
||||
# without permission to login locally). Get the fully-qualified
|
||||
# username, although a side-effect of these permission-denied errors
|
||||
# is a lack of Python codecs - so printing the Unicode value fails.
|
||||
# So just return the repr(), and avoid codecs completely.
|
||||
return repr(win32api.GetUserNameEx(win32api.NameSamCompatible))
|
||||
|
||||
|
||||
# Send a simple "message" over a socket - send the number of bytes first,
|
||||
# then the string. Ditto for receive.
|
||||
def _send_msg(s, m):
|
||||
s.send(struct.pack("i", len(m)))
|
||||
s.send(m)
|
||||
|
||||
|
||||
def _get_msg(s):
|
||||
size_data = s.recv(struct.calcsize("i"))
|
||||
if not size_data:
|
||||
return None
|
||||
cb = struct.unpack("i", size_data)[0]
|
||||
return s.recv(cb)
|
||||
|
||||
|
||||
class SSPISocketServer(socketserver.TCPServer):
|
||||
def __init__(self, *args, **kw):
|
||||
socketserver.TCPServer.__init__(self, *args, **kw)
|
||||
self.sa = sspi.ServerAuth(options.package)
|
||||
|
||||
def verify_request(self, sock, ca):
|
||||
# Do the sspi auth dance
|
||||
self.sa.reset()
|
||||
while 1:
|
||||
data = _get_msg(sock)
|
||||
if data is None:
|
||||
return False
|
||||
try:
|
||||
err, sec_buffer = self.sa.authorize(data)
|
||||
except sspi.error as details:
|
||||
print("FAILED to authorize client:", details)
|
||||
return False
|
||||
|
||||
if err == 0:
|
||||
break
|
||||
_send_msg(sock, sec_buffer[0].Buffer)
|
||||
return True
|
||||
|
||||
def process_request(self, request, client_address):
|
||||
# An example using the connection once it is established.
|
||||
print("The server is running as user", GetUserName())
|
||||
self.sa.ctxt.ImpersonateSecurityContext()
|
||||
try:
|
||||
print("Having conversation with client as user", GetUserName())
|
||||
while 1:
|
||||
# we need to grab 2 bits of data - the encrypted data, and the
|
||||
# 'key'
|
||||
data = _get_msg(request)
|
||||
key = _get_msg(request)
|
||||
if data is None or key is None:
|
||||
break
|
||||
data = self.sa.decrypt(data, key)
|
||||
print("Client sent:", repr(data))
|
||||
finally:
|
||||
self.sa.ctxt.RevertSecurityContext()
|
||||
self.close_request(request)
|
||||
print("The server is back to user", GetUserName())
|
||||
|
||||
|
||||
def serve():
|
||||
s = SSPISocketServer(("localhost", options.port), None)
|
||||
print("Running test server...")
|
||||
s.serve_forever()
|
||||
|
||||
|
||||
def sspi_client():
|
||||
c = http.client.HTTPConnection("localhost", options.port)
|
||||
c.connect()
|
||||
# Do the auth dance.
|
||||
ca = sspi.ClientAuth(options.package, targetspn=options.target_spn)
|
||||
data = None
|
||||
while 1:
|
||||
err, out_buf = ca.authorize(data)
|
||||
_send_msg(c.sock, out_buf[0].Buffer)
|
||||
if err == 0:
|
||||
break
|
||||
data = _get_msg(c.sock)
|
||||
print("Auth dance complete - sending a few encryted messages")
|
||||
# Assume out data is sensitive - encrypt the message.
|
||||
for data in "Hello from the client".split():
|
||||
blob, key = ca.encrypt(data)
|
||||
_send_msg(c.sock, blob)
|
||||
_send_msg(c.sock, key)
|
||||
c.sock.close()
|
||||
print("Client completed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = optparse.OptionParser("%prog [options] client|server", description=__doc__)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--package",
|
||||
action="store",
|
||||
default="NTLM",
|
||||
help="The SSPI package to use (eg, Kerberos) - default is NTLM",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--target-spn",
|
||||
action="store",
|
||||
help="""The target security provider name to use. The
|
||||
string contents are security-package specific. For
|
||||
example, 'Kerberos' or 'Negotiate' require the server
|
||||
principal name (SPN) (ie, the username) of the remote
|
||||
process. For NTLM this must be blank.""",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--port",
|
||||
action="store",
|
||||
default="8181",
|
||||
help="The port number to use (default=8181)",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"",
|
||||
"--wait",
|
||||
action="store_true",
|
||||
help="""Cause the program to wait for input just before
|
||||
terminating. Useful when using via runas to see
|
||||
any error messages before termination.
|
||||
""",
|
||||
)
|
||||
|
||||
options, args = parser.parse_args()
|
||||
try:
|
||||
options.port = int(options.port)
|
||||
except (ValueError, TypeError):
|
||||
parser.error("--port must be an integer")
|
||||
|
||||
try:
|
||||
try:
|
||||
if not args:
|
||||
args = [""]
|
||||
if args[0] == "client":
|
||||
sspi_client()
|
||||
elif args[0] == "server":
|
||||
serve()
|
||||
else:
|
||||
parser.error(
|
||||
"You must supply 'client' or 'server' - " "use --help for details"
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
except SystemExit:
|
||||
pass
|
||||
except:
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
if options.wait:
|
||||
input("Press enter to continue")
|
@ -0,0 +1,40 @@
|
||||
# Demonstrates how to validate a password.
|
||||
# See also MSKB article Q180548
|
||||
#
|
||||
# To use with Kerberos you need to jump through the 'targetspn' hoops.
|
||||
|
||||
import win32security
|
||||
import sys
|
||||
from sspi import ClientAuth, ServerAuth
|
||||
|
||||
|
||||
def validate(username, password, domain=""):
|
||||
auth_info = username, domain, password
|
||||
ca = ClientAuth("NTLM", auth_info=auth_info)
|
||||
sa = ServerAuth("NTLM")
|
||||
|
||||
data = err = None
|
||||
while err != 0:
|
||||
err, data = ca.authorize(data)
|
||||
err, data = sa.authorize(data)
|
||||
# If we get here without exception, we worked!
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) not in [2, 3, 4]:
|
||||
print("Usage: %s username [password [domain]]" % (__file__,))
|
||||
sys.exit(1)
|
||||
|
||||
# password and domain are optional!
|
||||
password = None
|
||||
if len(sys.argv) >= 3:
|
||||
password = sys.argv[2]
|
||||
domain = ""
|
||||
if len(sys.argv) >= 4:
|
||||
domain = sys.argv[3]
|
||||
try:
|
||||
validate(sys.argv[1], password, domain)
|
||||
print("Validated OK")
|
||||
except win32security.error as details:
|
||||
hr, func, msg = details
|
||||
print("Validation failed: %s (%d)" % (msg, hr))
|
Reference in New Issue
Block a user