--- a/opc_ua/client.py Tue Sep 13 10:11:25 2022 +0200
+++ b/opc_ua/client.py Tue Sep 13 16:22:09 2022 +0200
@@ -108,9 +108,14 @@
paramList = authParams.get(AuthType, None)
for name,default in paramList:
- res[name] = cfg("AuthType."+name)
+ value = cfg("AuthType."+name) + if value == "" or value is None: + # cryptomaterial is expected to be in project's user provide file directory + if name in ["Certificate","PrivateKey"]: + value = os.path.join(self.GetCTRoot()._getProjectFilesPath(), value)
@@ -134,6 +139,8 @@
CFLAGS = ' '.join(['-I"' + path + '"' for path in Open62541IncludePaths])
+ # Note: all user provided files are systematicaly copied, including cryptomaterial return [(c_path, CFLAGS)], LDFLAGS, True
def GetVariableLocationTree(self):
--- a/opc_ua/opcua_client_maker.py Tue Sep 13 10:11:25 2022 +0200
+++ b/opc_ua/opcua_client_maker.py Tue Sep 13 16:22:09 2022 +0200
@@ -311,8 +311,13 @@
config = self.config_getter()
self.client = Client(config["URI"])
- # client.set_security_string("Basic256Sha256,SignAndEncrypt,certificate-example.der,private-key-example.pem")
+ AuthType = config["AuthType"] + if AuthType=="UserPasword": + self.client.set_user(config["User"]) + self.client.set_password(config["Password"]) + self.client.set_security_string( + "{Policy},{Mode},{Certificate},{PrivateKey}".format(**config)) self.client.load_type_definitions() # load definition of server specific structures/extension objects
@@ -499,8 +504,39 @@
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <open62541/plugin/log_stdout.h>
+#include <open62541/plugin/securitypolicy.h> +#include <open62541/types.h> +#include <open62541/types_generated_handling.h> +static UA_INLINE UA_ByteString +loadFile(const char *const path) {{ + UA_ByteString fileContents = UA_STRING_NULL; + FILE *fp = fopen(path, "rb"); + fseek(fp, 0, SEEK_END); + fileContents.length = (size_t)ftell(fp); + fileContents.data = (UA_Byte *)UA_malloc(fileContents.length * sizeof(UA_Byte)); + if(fileContents.data) {{ + fseek(fp, 0, SEEK_SET); + size_t read = fread(fileContents.data, sizeof(UA_Byte), fileContents.length, fp); + if(read != fileContents.length) + UA_ByteString_clear(&fileContents); + fileContents.length = 0; static UA_Client *client;
+static UA_ClientConfig *cc; #define DECL_VAR(ua_type, C_type, c_loc_name) \\
static UA_Variant c_loc_name##_variant; \\
@@ -516,6 +552,29 @@
+#define INIT_NoAuth() \\ + UA_ClientConfig_setDefault(cc); \\ + retval = UA_Client_connect(client, uri); +/* Note : Policy is ignored here since open62541 client supports all policies by default */ +#define INIT_x509(Policy, UpperCaseMode, PrivateKey, Certificate) \\ + /* TODO try paths given in runtime CLI */ \\ + UA_ByteString certificate = loadFile(Certificate); \\ + UA_ByteString privateKey = loadFile(PrivateKey); \\ + printf("INIT_x509 %s,%s,%s,%s\\n", #Policy, #UpperCaseMode, PrivateKey, Certificate); \\ + cc->securityMode = UA_MESSAGESECURITYMODE_##UpperCaseMode; \\ + UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey, NULL, 0, NULL, 0); \\ + retval = UA_Client_connect(client, uri); \\ + UA_ByteString_clear(&certificate); \\ + UA_ByteString_clear(&privateKey); +#define INIT_UserPassword(User, Password) \\ + printf("TODO INIT_UserPassword %s,%s\\n", User, Password); \\ + retval = UA_Client_connectUsername(client, uri, User, Password); #define INIT_READ_VARIANT(ua_type, c_loc_name) \\
UA_Variant_init(&c_loc_name##_variant);
@@ -526,11 +585,10 @@
client = UA_Client_new();
- UA_ClientConfig_setDefault(UA_Client_getConfig(client));
+ cc = UA_Client_getConfig(client); - /* Connect to server */
- retval = UA_Client_connect(client, "{uri}");
if(retval != UA_STATUSCODE_GOOD) {{
UA_Client_delete(client);
@@ -566,13 +624,25 @@
- # TODO: pass authentication code.
+ AuthType = config["AuthType"] + config["UpperCaseMode"] = config["Mode"].upper() + formatdict["init"] += """ + INIT_x509({Policy}, {UpperCaseMode}, "{PrivateKey}", "{Certificate}")""".format(**config) + elif AuthType == "UserPassword": + formatdict["init"] += """ + INIT_UserPassword("{User}", "{Password}")""".format(**config) + formatdict["init"] += """ for direction, data in self.iteritems():
iec_direction_prefix = {"input": "__I", "output": "__Q"}[direction]
@@ -586,13 +656,13 @@
DECL_VAR({ua_type}, {C_type}, {c_loc_name})""".format(**locals())
- formatdict["init"] +="""
+ formatdict["init"] += """ INIT_READ_VARIANT({ua_type}, {c_loc_name})""".format(**locals())
formatdict["retrieve"] += """
READ_VALUE({ua_type}, {ua_type_enum}, {c_loc_name}, {ua_nodeid_type}, {ua_nsidx}, {ua_node_id})""".format(**locals())
if direction == "output":
- formatdict["init"] +="""
+ formatdict["init"] += """ INIT_WRITE_VARIANT({ua_type}, {ua_type_enum}, {c_loc_name})""".format(**locals())
formatdict["publish"] += """
WRITE_VALUE({ua_type}, {c_loc_name}, {ua_nodeid_type}, {ua_nsidx}, {ua_node_id})""".format(**locals())