A python client for .Net NegotiateStream
Project description
jetblack-negotiate-stream
A Python client for .Net NegotiateStream. It supports single sign on (SSO) and encryption.
This was tested using Python 3.8 on Windows 11.
Installation
Install from pypi.
pip install jetblack-negotiate-stream
Example
The following programs provide a simple echo server in C# and client in Python.
Client
This is an example of a Python client using the synchronous
NegotiateStream class. Note the call to authenticate_as_client before
reading and writing.
import socket
from jetblack_negotiate_stream import NegotiateStream
def main():
hostname = socket.gethostname()
port = 8181
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((hostname, port))
stream = NegotiateStream(hostname, sock)
# Do the client side negotiate handshake.
stream.authenticate_as_client()
for data in (b'first line', b'second line', b'third line'):
# All reads and writes are encrypted.
stream.write(data)
response = stream.read()
print("Received: ", response)
if __name__ == '__main__':
main()
Async Client
This program uses NegotiateStreamAsync which is simply an asynchronous
version of the NegotiateStream class demonstrated above.
import asyncio
import socket
from jetblack_negotiate_stream import NegotiateStreamAsync
async def main():
hostname = socket.gethostname()
port = 8181
reader, writer = await asyncio.open_connection(hostname, port)
stream = NegotiateStreamAsync(hostname, reader, writer)
await stream.authenticate_as_client()
for data in (b'first line', b'second line', b'third line'):
stream.write(data)
await stream.drain()
response = await stream.read()
print("Received: ", response)
stream.close()
await stream.wait_closed()
if __name__ == '__main__':
asyncio.run(main())
Alternative Async Client
The following client follows the patterns demonstrated in the asyncio library
using open_negotiate_stream. This follows the conventions of the asyncio
open_connection function. The negotiation happens before the function
returns, resulting in cleaner code.
import asyncio
import socket
from jetblack_negotiate_stream import open_negotiate_stream
async def main():
hostname = socket.gethostname()
port = 8181
# Following the same pattern as asyncio.open_connection.
reader, writer = await open_negotiate_stream(hostname, port)
for data in (b'first line', b'second line', b'third line'):
writer.write(data)
await writer.drain()
response = await reader.read()
print("Received: ", response)
writer.close()
await writer.wait_closed()
if __name__ == '__main__':
asyncio.run(main())
Server
Here is a trivial C# echo server for the clients.
using System;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
namespace NegotiateStreamServer
{
internal class Program
{
static void Main(string[] args)
{
var listener = new TcpListener(IPAddress.Any, 8181);
listener.Start();
while (true)
{
Console.WriteLine("Listening ...");
var client = listener.AcceptTcpClient();
try
{
Console.WriteLine("... Client connected.");
Console.WriteLine("Authenticating...");
var stream = new NegotiateStream(client.GetStream(), false);
stream.AuthenticateAsServer();
Console.WriteLine(
"... {0} authenticated using {1}",
stream.RemoteIdentity.Name,
stream.RemoteIdentity.AuthenticationType);
var buf = new byte[4096];
for (var i = 0; i < 3; ++i)
{
var bytesRead = stream.Read(buf, 0, buf.Length);
var message = Encoding.UTF8.GetString(buf, 0, bytesRead);
Console.WriteLine(message);
stream.Write(buf, 0, bytesRead);
}
stream.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
}
Acknowledgements
The library uses the pyspnego library, and takes many ideas from net.tcp-proxy.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jetblack-negotiate-stream-0.2.2.tar.gz.
File metadata
- Download URL: jetblack-negotiate-stream-0.2.2.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.12 CPython/3.10.10 Darwin/21.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
802bc76162ebc48f7237b725af160dca68cf11469b574af7a7a2fd0d24bb9389
|
|
| MD5 |
0313b8c189b535b6a3657c0590b9a7f2
|
|
| BLAKE2b-256 |
81f654c1e7894be785c2f8dab0a0620285c31c5bfbf6c4939de3011fa76390e4
|
File details
Details for the file jetblack_negotiate_stream-0.2.2-py3-none-any.whl.
File metadata
- Download URL: jetblack_negotiate_stream-0.2.2-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.12 CPython/3.10.10 Darwin/21.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b14b563929944ca503218be09be7aa1df3304a15faf0967e8e8d37dae03bd05f
|
|
| MD5 |
2f9a84beb8127355eea51ec42bf92a07
|
|
| BLAKE2b-256 |
08e2ebaba1c4d187160ff863d058004f35a7acfbb46fc5f158363677bb3bbd15
|