Python socket server do client authentication by using token - python

There're basically two issues I'd like to resolve:
Client side send query string when initializing the connection to server
Server side validate user token in handshake (not after the connection is established and then validate streaming message that contains the token) and set user session accordingly.
I read a article (https://auth0.com/blog/2014/01/15/auth-with-socket-io/) that talks about this process implemented in nodejs, just wonder if the same function can be achieved by using python. (Currently I'm doing some research on twisted but haven't found anything similar)
PS: guess it's helpful to demo the use case as well. A user may login to your server over normal http then server will issue him/her an valid accessToken. Then this user may need to establish a socket connection with the server (or some other server), then the server needs to figure out who the user is and validate before establishing the socket connection.

Query strings are part of HTTP URLs.
If you're building a TCP socket server instead of an HTTP server, you don't get URLs—or headers, or anything else out-of-band.* All you get is a stream of data. You need to come up with a protocol for your data that you can fit the token into.
This means the server can't "figure out who the user is and validate before establishing the socket connection". It has to establish the socket connection, read the first message, parse it, validate the token, and then drop or continue the connection. (You can, of course, put up a front-end server that accepts connections, validates them, and then migrates or proxies them to the real back-end server. But someone has to accept, read, and parse.)
Note that this is exactly what HTTP does—it can't see the query string until it accepts the connection and reads the first line of data.
Meanwhile, the example you're looking at appears to be using WebSockets. A WebSockets client can't talk to a socket server (well, unless you build a WebSockets server on top of your socket server, or a proxy in front of it) in the first place.
* This isn't quite true. You can cram 40 bytes of options into TCP header extensions. But then you have to go below the level people are usually talking about when they say "socket server"—and there's a good chance it won't make it through the internet. Also, TCP does have a concept of "out-of-band" data, but that isn't relevant here; you still have to accept the connection and read from it to get an OOB data.

Related

HTTP server with socket communication

I am trying to create a simple http server, that will take http requests from a client and interact with an application that listens on a port (on the same host).
My initial take on that was to create a BaseHTTPServer with custom definitions of GET,POST.
So when a request arrived on the server, the custom POST method would first create a socket for the communication with the underlying application. It then extract the data that needs to be passed to that application and write them through the socket. Then when the application to respond and pass that response to the response of the initial post request.
Even though that flow works at a degree, i feel that there is a much more appropriate solution to the problem.
in a nutshell, we have:
Server:
appA running on port 8000
http server on port 80
Client:
connect to http server and interact with appA through http requests.
e.g. post for sending data, get to receive response
Any thoughts on how to solve the problem more appropriately?
Maybe a library to handle sockets at a higher level (currently I am connecting to the socket and use select to read,write data). I think asyncio may have such capability?
In general how would somebody optimally approach that problem. (without getting in trouble of implementing stuff that are already there, like http server)

Only allow connections from custom clients

I'm writing a Socket Server in Python, and also a Socket Client to connect to the Server.
The Client interacts with the Server in a way that the Client sends information when an action is invoked, and the Server processes the information.
The problem I'm having, is that I am able to connect to my Server with Telnet, and probably other things that I haven't tried yet. I want to disable connection from these other Clients, and only allow connections from Python Clients. (Preferably my custom-made client, as it sends information to communicate)
Is there a way I could set up authentication on connection to differentiate Python Clients from others?
Currently there is no code, as this is a problem I want to be able to solve before getting my hands dirty.
When a new connection is made to your server, your protocol will have to specify some way for the client to authenticate. Ultimately there is nothing that the network infrastructure can do to determine what sort of process initiated the connection, so you will have to specify some exchange that allows the server to be sure that it really is talking to a valid client process.
#holdenweb has already given a good answer with basic info.
If a (terminal) software sends the bytes that your application expects as a valid identification, your app will never know whether it talks to an original client or anything else.
A possible way to test for valid clients could be, that your server sends an encrypted and authenticated question (should be different at each test!), e.g. something like "what is 18:37:12 (current date and time) plus 2 (random) hours?"
Encryption/Authentication would be another issue then.
If you keep this algorithm secret, only your clients can answer it and validate themselves successfully. It can be hacked/reverse engineered, but it is safe against basic attackers.

Python websockets

Is it possible to have one protocol connect to another protocol on the same server? My goal is to accept a request for one protocol and then pass that request to a different protocol and have that second protocol return values to whatever client is connected to it.
I'm thinking you would transfer the onMessage request to the other protocol some how.
I don't have any code to show as I don't know where to start, but any code examples would be appreciated.
What you're asking for sounds like a proxy server. A proxy can simply be a middleman that speaks the same protocol out both ends (as in a typical http proxy) or it can be some sort of translator that has one protocol coming in and another protocol going out.
So, supposed you want a browser to be able to use a webSocket connection to speak to some other server that doesn't speak the webSocket protocol. You could implement a proxy server yourself that allows the browser to connect to it and then, via your proxy, it could send/receive messages with the other server that speaks a different protocol.
To implement a proxy server like this, you would do the following:
Create a server process that listens for incoming webSocket connections. This would allow the browser to connect to your proxy.
Once connected, the browser would send a message (of your own design) over the webSocket.
Your proxy would receive that message and translate it to the protocol of the other server,
Your proxy would then connect to that other server and send the message to the other server.
Your proxy could then receive a response from that other server and then, if needed, send a translated response message back to the browser over the webSocket.
It would be the proxy's responsibility to translate each message data from what it received over the webSocket to whatever format/protocol the other server speaks.
It would be an implementation choice whether you maintained a dedicated connection between the proxy and the other server for each webSocket connection or whether you directed all requests over one dedicated connection or whether you created a new connection upon demand only for the duration of a given request. Which makes the most sense depends entirely upon the characteristics of the other server, number of requests and the work that is being done.

Identifying services listening on remote ports

I'd like to elaborate a little bit on this question and, particularly, on this answer. Let's suppose I have a fixed list of services to check, say: ('ftp', 'ssh', 'http'). Opening a socket to port 22 of a remote server:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex(('my_remote_server', 22))
if(result == 0) :
print s.recv(256)
s.close()
I get the following output:
'SSH-2.0-OpenSSH_6.1p1 Debian-4\r\n'
So I can guess there's a ssh service listening on that port. Therefore my question is: where or how can I find the welcome messages (or similar) for different kind of services? Are these regulated in some way? In the case of ssh, does it always start with SSH-?
The response you get from a server depens both on the exact protocol and server configuration.
HTTP has a Server header for example, but many server out on the internet lies about what server is responding, to throw off malicious hackers trying to exploit server-specific flaws. Moreover, the server remains silent until the client has sent a request; your code has to send something before there is any response.
The best you can do is try out different protocols and see if the other side responds sensibly. Trying to send an SSH handshake to a HTTP port is likely to result in a HTTP/1.0 400 Bad Request response, for example.
In other words, there is no ready-made solution for this, you'll have to create your own heuristics based on what protocols you are trying to detect.
The best you can do is probably search for the string ssh(/ftp/http) and conclude based on that.
Even that would be a guess, of course, as this can usually be changed(see here) with a config parameter and it is considered good security practice to change it so as to not expose the server program/version.

How can I examine the network communications of the Python HTTP Client?

I'm trying to isolate a bug that exists either in Python's httplib2 HTTP client or an API. (First guess is the API.) While using httplib2 to POST data to a RESTful API, I'm getting a 401 response status (no authorization) and saving data to the API.
I'd like to examine the HTTP request and response to the client, the very strings put onto and received from the network. The httplib2 code seems too involved to easily capture the values from within it, and might possibly miss the bug.
It seems quicker to look at the network communications with the client. Is there some tool I can use to monitor the client's communications with the local network socket?
I use http://www.charlesproxy.com for all my network debugging.
http://www.wireshark.org/ enables you to monitor local sockets too.
I was able to monitor local loopback even on windows using trick whit adding route.
http://wiki.wireshark.org/CaptureSetup/Loopback check Other Alternatives
Or you can just write raw socket server that listen on client side on one port and send data to server on other port and vice versa and prints out all data. It should not take more than dozen of lines of code

Categories

Resources