FreeOpcUa / python-opcua

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

How to implement the security ID check #782

Open okyame opened 5 years ago

okyame commented 5 years ago

I have to setup a server that allows clients to login only with username and password. It work with the example file below. But I can not disable the Anonymous connection.

import time

from opcua import ua, Server
from opcua.server.user_manager import UserManager

# users database
users_db = {
    'user1': 'passwd1',
    'user2': 'passwd2',
    'user3': 'passwd3',
}

# user manager
def user_manager(isession, username, password):
    print(isession, username, password)
    isession.user = UserManager.User
    return username in users_db and password == users_db[username]

if __name__ == "__main__":

    # setup our server
    server = Server()
    server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")

    # load server certificate and private key. This enables endpoints
    # with signing and encryption.
    server.load_certificate("certificate-example.der")
    server.load_private_key("private-key-example.pem")

    # set all possible endpoint policies for clients to connect through
    server.set_security_policy([
        # ua.SecurityPolicyType.NoSecurity,
        ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt,
        # ua.SecurityPolicyType.Basic256Sha256_Sign,
    ])

    # set the security endpoints for identification of clients
    # self.server.set_security_IDs(["Anonymous", "Basic256Sha256", "Username"])
    server.set_security_IDs(["Username"])

    # set the user_manager function
    server.user_manager.set_user_manager(user_manager)

    # starting!
    server.start()

    print("Endpoints : ", str(server.get_endpoints()).replace(',', '\n'))

    try:
        while True:
            time.sleep(5)
    finally:
        # close connection, remove subscriptions, etc
        server.stop()

In the server.py file, it's written that :

    def set_security_IDs(self, policyIDs):
        """
            Method setting up the security endpoints for identification
            of clients. During server object initialization, all possible
            endpoints are enabled:

            self._policyIDs = ["Anonymous", "Basic256Sha256", "Username"]

            E.g. to limit the number of IDs and disable anonymous clients:

                set_security_policy(["Basic256Sha256"])

            (Implementation for ID check is currently not finalized...)

        """
        self._policyIDs = policyIDs

Someone can tell me where to look to implement this ? (I'm new in opc ua world)

Thanks

AndreasHeine commented 4 years ago

this should disable it: policyIDs = ["Username"] server.set_security_IDs(policyIDs)

How do you Test it? UaExpert?

https://github.com/AndreasHeine/SecurePythonOpcUaServer https://github.com/AndreasHeine/SecurePythonOpcUaClient

EEflow commented 4 years ago

this should disable it: policyIDs = ["Username"] server.set_security_IDs(policyIDs)

How do you Test it? UaExpert?

https://github.com/AndreasHeine/SecurePythonOpcUaServer https://github.com/AndreasHeine/SecurePythonOpcUaClient

Anonymous login still works after setting this. Tested with UaExport.

saramizi commented 4 years ago

Hi, I am having the same issue. Any update on this? Thanks

srep2512 commented 4 years ago

same here using UAExpert anonymous login still works :(

AndreasHeine commented 4 years ago

Sample Server: server

Add Server in UA Expert: server_ua_expert

Connect (asking for auth): connect

Error: connect_without_username

What does you do and get from UA Expert? Code? Versions?

Iam using python 3.7.2 64bit and python-opcua v0.98.9!

srep2512 commented 4 years ago

At first I want to thank you for the response and your great work!

Ok I tried with your example from scratch and it behaves like you explained. Let me ask you one question if the following is intended.

image

I tried to change the properties after adding the server. Now the anonymous option is not grey and I can choose it.

image

image

UAExpert 1.5.1 331

oroulet commented 4 years ago

Not sure this is implemented. The focus of that library has always been compatibility, not much security so far. But hopefully it is easy to fix

AndreasHeine commented 4 years ago

Ok got ya! I can reproduse that behavior... Sadly iam not that deep into the lib...

i made a wireshark trace:

open_channel_req: open_channel_req

open_channel_res: open_channel_res

create_session_req: create_session_req

create_session_res: create_session_res

activate_session_req: activate_session_req

activate_session_res: activate_session_res

AndreasHeine commented 4 years ago

it doesn't look like there is an implementation for comparing server policieIDs with activate session request user token !?