FreeOpcUa / python-opcua

LGPL Pure Python OPC-UA Client and Server
http://freeopcua.github.io/
GNU Lesser General Public License v3.0
1.36k stars 658 forks source link

Setting username and password option in OPC UA Server using sockets #986

Open abhinav0927 opened 4 years ago

abhinav0927 commented 4 years ago

Hi

Thanks for this awesome library. I have been using it a lot and its easy to create servers and connect to server as a client.

Currently there is no option of setting the username and password feature while creating a server. Do you think something like below can be created to have this in free opcua library:

Server Side:

  1. Create a opc server
  2. Create a standard socket server
  3. Save username password as hash somewhere in the server (may be as a json)

Client Side

  1. Create a opc client
  2. Create a standard socket client
  3. Send username and password to socket server. Socket server will decode the hash of username password if it matches, it will return true.
  4. If true, client will get access to server or else no connection.

Something like this

  1. https://www.youtube.com/watch?v=6Q3J8SVsFco&list=PLWw98q-Xe7iGf-c4b6zF0bnJA9avEN_mF&index=8

  2. https://www.youtube.com/watch?v=mMpVQ6dxsRs&list=PLWw98q-Xe7iGf-c4b6zF0bnJA9avEN_mF&index=9

zerox1212 commented 4 years ago

We would need to read the OPC UA spec to see how it is supposed to be implemented. From what I know you would not have the client send a hashed password. You would just enable encryption then server would hash the password for storage.

zerox1212 commented 4 years ago

Also, there is some code already made to do basic user management. You can get an idea from https://github.com/FreeOpcUa/python-opcua/pull/691 .

abhinav0927 commented 4 years ago

So idea is that, server would have the username and password stored somewhere in it in hash format. Server will also save salt which was used to convert username and password into hash.

Client will connect to server socket and will send username and password something like below:

client_socket = socket.socket()
client_socket.connect((server_ip, 5000))
credentials = "username,password"
client_socket.send(credentials.encode())
result = client_socket.receive().decode() 

server will receive the username passwoed and using the stored salt, it will convert those into hash and will check if it matches with the original username and password hash. If it matches, server will send True to client which on client side will be received in result = client_socket.receive().decode(). Once True, client will connect to server.

If you think this is worth trying, let me know. We can connect further on this to discuss

zerox1212 commented 4 years ago

I think it should actually be easier than that. You create a server with encryption (cert). The server has user name and password hash saved in a user_manager. Then client connects to the server using the cert. When the client connects it provides user name and password in the URI.

I think some of this is already existing in https://github.com/FreeOpcUa/python-opcua/blob/913325635c9fa38b26c8b6227e9a0a6d3582f1bb/opcua/server/user_manager.py ?