gopcua / opcua

Native Go OPC-UA library
MIT License
829 stars 253 forks source link

Add Fallback to set session.AuthPolicyURI #706

Open alpex8 opened 6 months ago

alpex8 commented 6 months ago

I´m using the lib in Telegraf. In a Certificate based connection I had the problem that the library raised the error error creating session signature: opcua: unsupported security policy

I was able to track the origin of that issue: The field AuthPolicyURI of the session config is not set.

When setting up the Connection the library retrieves the endpoints from the server. I set up some debug prints to show information on the received endpoint information. The Server is providing one endpoint:

Endpoint1: policy: http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256, epurl: XXXXX, secmode: 3, transportProfileURI: http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary, seclevel: 4

UserIdentityTokens of Endpoint
tokentype: , issuerendpointurl , policyid 0, security policy uri: , token type: 0
tokentype: , issuerendpointurl , policyid 1, security policy uri: , token type: 1
tokentype: , issuerendpointurl , policyid 2, security policy uri: , token type: 2

During connection setup the telegraf opcua client is calling the SecurityFromEndpoint method of the opcua library. In that method the relevant userIdeentityToken from the received Endpoint is used to set the session.AuthPolicyURI field. However the field for the security policy uri of the relevant UserIdentityToken (token type: 2 in my case) is empty. As a result the AuthPolicyURI will get no value and the connection does fail.

I was able to fix that issue for that specific server by adding some fallback logic: If the relevant UserIdentityToken does not provide the needed security policy, that one from the endpoint will be used.

However I can´t say if this change is safe in general or if it´s more like a hack to fix the connection to that specific misbehaving server.

magiconair commented 5 months ago

Hmm, good point. Is there something in the spec which describes the desired behavior?

magiconair commented 5 months ago

Can we add a test for that?

alpex8 commented 5 months ago

Hmm, good point. Is there something in the spec which describes the desired behavior?

I´m not familiar in detail with the spec. However I guess I found some relevant part of it here, which says

If this SecurityPolicy is null or empty then the Client uses the SecurityPolicy in the EndpointDescription.

alpex8 commented 5 months ago

Can we add a test for that?

I can, but that might take a while. Looking at the current tests, I wasn´t able to find out yet, how the python components are triggered when a go test is executed. Is there some documentation on this?

Edit: Nevermind, I think I´ll manage..

alpex8 commented 5 months ago

I added a check on AuthPolicyURI property in client.go to make sure it is always set. However with check several integration tests will fail since they seem to rely on the anonymous policy which if I understood that correct seems to be handled as a default case.

On the other hand when that default is set in config.go line 401 some advice is given that most clients should call the SecurityFromEndpoint option before - which is exactly where I added my fallback condition.

I a bit stuck now because as I didn´t find some information in the spec saying that each session must have an AuthPolicyUri set. I could just remove that check, which would make all tests pass.

Do you have further requirements what the test case should cover?