Package: jetblack-negotiate-stream
jetblack-negotiate-streamA Python client for .NetNegotiateStream.
It supports single sign on (SSO) and encryption.This was tested using Python 3.8 on Windows 11.InstallationInstall from pypi.pipinstalljetblack-negotiate-streamExampleThe following programs provide a simple echo server in C# and client in Python.ClientThis is an example of a Python client using the synchronousNegotiateStreamclass. Note the call toauthenticate_as_clientbefore
reading and writing.importsocketfromjetblack_negotiate_streamimportNegotiateStreamdefmain():hostname=socket.gethostname()port=8181withsocket.socket(socket.AF_INET,socket.SOCK_STREAM)assock:sock.connect((hostname,port))stream=NegotiateStream(hostname,sock)# Do the client side negotiate handshake.stream.authenticate_as_client()fordatain(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 ClientThis program usesNegotiateStreamAsyncwhich is simply an asynchronous
version of theNegotiateStreamclass demonstrated above.importasyncioimportsocketfromjetblack_negotiate_streamimportNegotiateStreamAsyncasyncdefmain():hostname=socket.gethostname()port=8181reader,writer=awaitasyncio.open_connection(hostname,port)stream=NegotiateStreamAsync(hostname,reader,writer)awaitstream.authenticate_as_client()fordatain(b'first line',b'second line',b'third line'):stream.write(data)awaitstream.drain()response=awaitstream.read()print("Received: ",response)stream.close()awaitstream.wait_closed()if__name__=='__main__':asyncio.run(main())Alternative Async ClientThe following client follows the patterns demonstrated in the asyncio library
usingopen_negotiate_stream. This follows the conventions of the asyncioopen_connectionfunction. The negotiation happens before the function
returns, resulting in cleaner code.importasyncioimportsocketfromjetblack_negotiate_streamimportopen_negotiate_streamasyncdefmain():hostname=socket.gethostname()port=8181# Following the same pattern as asyncio.open_connection.reader,writer=awaitopen_negotiate_stream(hostname,port)fordatain(b'first line',b'second line',b'third line'):writer.write(data)awaitwriter.drain()response=awaitreader.read()print("Received: ",response)writer.close()awaitwriter.wait_closed()if__name__=='__main__':asyncio.run(main())ServerHere is a trivial C# echo server for the clients.usingSystem;usingSystem.Net;usingSystem.Net.Security;usingSystem.Net.Sockets;usingSystem.Text;namespaceNegotiateStreamServer{internalclassProgram{staticvoidMain(string[]args){varlistener=newTcpListener(IPAddress.Any,8181);listener.Start();while(true){Console.WriteLine("Listening ...");varclient=listener.AcceptTcpClient();try{Console.WriteLine("... Client connected.");Console.WriteLine("Authenticating...");varstream=newNegotiateStream(client.GetStream(),false);stream.AuthenticateAsServer();Console.WriteLine("... {0} authenticated using {1}",stream.RemoteIdentity.Name,stream.RemoteIdentity.AuthenticationType);varbuf=newbyte[4096];for(vari=0;i<3;++i){varbytesRead=stream.Read(buf,0,buf.Length);varmessage=Encoding.UTF8.GetString(buf,0,bytesRead);Console.WriteLine(message);stream.Write(buf,0,bytesRead);}stream.Close();}catch(Exceptionex){Console.WriteLine(ex.ToString());}}}}}AcknowledgementsThe library uses thepyspnegolibrary,
and takes many ideas fromnet.tcp-proxy.