Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
opcua-asyncio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nikola Balog
opcua-asyncio
Commits
6a68a039
Commit
6a68a039
authored
Apr 12, 2016
by
ORD
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #153 from FreeOpcUa/history
History fixes and event support WORK IN PROGRESS
parents
eb491cfa
cb660789
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
45 additions
and
18 deletions
+45
-18
README.md
README.md
+2
-1
opcua/client/client.py
opcua/client/client.py
+7
-2
opcua/server/history.py
opcua/server/history.py
+2
-1
opcua/server/uaprocessor.py
opcua/server/uaprocessor.py
+10
-2
opcua/tools.py
opcua/tools.py
+5
-1
opcua/ua/uaprotocol_hand.py
opcua/ua/uaprotocol_hand.py
+4
-4
opcua/ua/uatypes.py
opcua/ua/uatypes.py
+3
-4
tests/tests.py
tests/tests.py
+1
-1
tests/tests_unit.py
tests/tests_unit.py
+11
-2
No files found.
README.md
View file @
6a68a039
...
@@ -74,11 +74,12 @@ Server: what works:
...
@@ -74,11 +74,12 @@ Server: what works:
*
encryption
*
encryption
*
certificate handling
*
certificate handling
*
removing nodes
*
removing nodes
*
history support
Tested clients: freeopcua C++, freeopcua Python, uaexpert, prosys, quickopc
Tested clients: freeopcua C++, freeopcua Python, uaexpert, prosys, quickopc
Server: what is not implemented
Server: what is not implemented
*
history support
*
history support
for events
*
views
*
views
*
localized text feature
*
localized text feature
*
better securty model with users and password
*
better securty model with users and password
...
...
opcua/client/client.py
View file @
6a68a039
...
@@ -318,7 +318,11 @@ class Client(object):
...
@@ -318,7 +318,11 @@ class Client(object):
params
.
RequestedSessionTimeout
=
3600000
params
.
RequestedSessionTimeout
=
3600000
params
.
MaxResponseMessageSize
=
0
# means no max size
params
.
MaxResponseMessageSize
=
0
# means no max size
response
=
self
.
uaclient
.
create_session
(
params
)
response
=
self
.
uaclient
.
create_session
(
params
)
self
.
security_policy
.
asymmetric_cryptography
.
verify
(
self
.
security_policy
.
client_certificate
+
nonce
,
response
.
ServerSignature
.
Signature
)
if
self
.
security_policy
.
client_certificate
is
None
:
data
=
nonce
else
:
data
=
self
.
security_policy
.
client_certificate
+
nonce
self
.
security_policy
.
asymmetric_cryptography
.
verify
(
data
,
response
.
ServerSignature
.
Signature
)
self
.
_server_nonce
=
response
.
ServerNonce
self
.
_server_nonce
=
response
.
ServerNonce
if
not
self
.
security_policy
.
server_certificate
:
if
not
self
.
security_policy
.
server_certificate
:
self
.
security_policy
.
server_certificate
=
response
.
ServerCertificate
self
.
security_policy
.
server_certificate
=
response
.
ServerCertificate
...
@@ -361,7 +365,8 @@ class Client(object):
...
@@ -361,7 +365,8 @@ class Client(object):
Activate session using either username and password or private_key
Activate session using either username and password or private_key
"""
"""
params
=
ua
.
ActivateSessionParameters
()
params
=
ua
.
ActivateSessionParameters
()
challenge
=
self
.
security_policy
.
server_certificate
+
self
.
_server_nonce
cert
=
self
.
security_policy
.
server_certificate
if
self
.
security_policy
.
server_certificate
is
not
None
else
b""
challenge
=
cert
+
self
.
_server_nonce
params
.
ClientSignature
.
Algorithm
=
b"http://www.w3.org/2000/09/xmldsig#rsa-sha1"
params
.
ClientSignature
.
Algorithm
=
b"http://www.w3.org/2000/09/xmldsig#rsa-sha1"
params
.
ClientSignature
.
Signature
=
self
.
security_policy
.
asymmetric_cryptography
.
signature
(
challenge
)
params
.
ClientSignature
.
Signature
=
self
.
security_policy
.
asymmetric_cryptography
.
signature
(
challenge
)
params
.
LocaleIds
.
append
(
"en"
)
params
.
LocaleIds
.
append
(
"en"
)
...
...
opcua/server/history.py
View file @
6a68a039
...
@@ -3,6 +3,7 @@ from datetime import datetime
...
@@ -3,6 +3,7 @@ from datetime import datetime
from
opcua
import
Subscription
from
opcua
import
Subscription
from
opcua
import
ua
from
opcua
import
ua
from
opcua.common
import
utils
class
HistoryStorageInterface
(
object
):
class
HistoryStorageInterface
(
object
):
...
@@ -207,7 +208,7 @@ class HistoryManager(object):
...
@@ -207,7 +208,7 @@ class HistoryManager(object):
# implementation. This is contradictory, so we assume details is
# implementation. This is contradictory, so we assume details is
# send correctly with continuation point
# send correctly with continuation point
#starttime = bytes_to_datetime(rv.ContinuationPoint)
#starttime = bytes_to_datetime(rv.ContinuationPoint)
starttime
=
ua
.
unpack_datetime
(
rv
.
ContinuationPoint
)
starttime
=
ua
.
unpack_datetime
(
utils
.
Buffer
(
rv
.
ContinuationPoint
)
)
dv
,
cont
=
self
.
storage
.
read_node_history
(
rv
.
NodeId
,
dv
,
cont
=
self
.
storage
.
read_node_history
(
rv
.
NodeId
,
starttime
,
starttime
,
...
...
opcua/server/uaprocessor.py
View file @
6a68a039
...
@@ -122,7 +122,11 @@ class UaProcessor(object):
...
@@ -122,7 +122,11 @@ class UaProcessor(object):
response
=
ua
.
CreateSessionResponse
()
response
=
ua
.
CreateSessionResponse
()
response
.
Parameters
=
sessiondata
response
.
Parameters
=
sessiondata
response
.
Parameters
.
ServerCertificate
=
self
.
_connection
.
_security_policy
.
client_certificate
response
.
Parameters
.
ServerCertificate
=
self
.
_connection
.
_security_policy
.
client_certificate
response
.
Parameters
.
ServerSignature
.
Signature
=
self
.
_connection
.
_security_policy
.
asymmetric_cryptography
.
signature
(
self
.
_connection
.
_security_policy
.
server_certificate
+
params
.
ClientNonce
)
if
self
.
_connection
.
_security_policy
.
server_certificate
is
None
:
data
=
params
.
ClientNonce
else
:
data
=
self
.
_connection
.
_security_policy
.
server_certificate
+
params
.
ClientNonce
response
.
Parameters
.
ServerSignature
.
Signature
=
self
.
_connection
.
_security_policy
.
asymmetric_cryptography
.
signature
(
data
)
response
.
Parameters
.
ServerSignature
.
Algorithm
=
"http://www.w3.org/2000/09/xmldsig#rsa-sha1"
response
.
Parameters
.
ServerSignature
.
Algorithm
=
"http://www.w3.org/2000/09/xmldsig#rsa-sha1"
self
.
logger
.
info
(
"sending create sesssion response"
)
self
.
logger
.
info
(
"sending create sesssion response"
)
...
@@ -146,7 +150,11 @@ class UaProcessor(object):
...
@@ -146,7 +150,11 @@ class UaProcessor(object):
self
.
logger
.
info
(
"request to activate non-existing session"
)
self
.
logger
.
info
(
"request to activate non-existing session"
)
raise
utils
.
ServiceError
(
ua
.
StatusCodes
.
BadSessionIdInvalid
)
raise
utils
.
ServiceError
(
ua
.
StatusCodes
.
BadSessionIdInvalid
)
self
.
_connection
.
_security_policy
.
asymmetric_cryptography
.
verify
(
self
.
_connection
.
_security_policy
.
client_certificate
+
self
.
session
.
nonce
,
params
.
ClientSignature
.
Signature
)
if
self
.
_connection
.
_security_policy
.
client_certificate
is
None
:
data
=
self
.
session
.
nonce
else
:
data
=
self
.
_connection
.
_security_policy
.
client_certificate
+
self
.
session
.
nonce
self
.
_connection
.
_security_policy
.
asymmetric_cryptography
.
verify
(
data
,
params
.
ClientSignature
.
Signature
)
result
=
self
.
session
.
activate_session
(
params
)
result
=
self
.
session
.
activate_session
(
params
)
...
...
opcua/tools.py
View file @
6a68a039
...
@@ -84,7 +84,11 @@ def parse_args(parser, requirenodeid=False):
...
@@ -84,7 +84,11 @@ def parse_args(parser, requirenodeid=False):
def
get_node
(
client
,
args
):
def
get_node
(
client
,
args
):
node
=
client
.
get_node
(
args
.
nodeid
)
node
=
client
.
get_node
(
args
.
nodeid
)
if
args
.
path
:
if
args
.
path
:
node
=
node
.
get_child
(
args
.
path
.
split
(
","
))
path
=
args
.
path
.
split
(
","
)
if
node
.
nodeid
==
ua
.
NodeId
(
84
,
0
)
and
path
[
0
]
==
"0:Root"
:
# let user specify root if not node given
path
=
path
[
1
:]
node
=
node
.
get_child
(
path
)
return
node
return
node
...
...
opcua/ua/uaprotocol_hand.py
View file @
6a68a039
...
@@ -163,8 +163,8 @@ class AsymmetricAlgorithmHeader(uatypes.FrozenClass):
...
@@ -163,8 +163,8 @@ class AsymmetricAlgorithmHeader(uatypes.FrozenClass):
def
__init__
(
self
):
def
__init__
(
self
):
self
.
SecurityPolicyURI
=
"http://opcfoundation.org/UA/SecurityPolicy#None"
self
.
SecurityPolicyURI
=
"http://opcfoundation.org/UA/SecurityPolicy#None"
self
.
SenderCertificate
=
b""
self
.
SenderCertificate
=
None
self
.
ReceiverCertificateThumbPrint
=
b""
self
.
ReceiverCertificateThumbPrint
=
None
self
.
_freeze
=
True
self
.
_freeze
=
True
def
to_binary
(
self
):
def
to_binary
(
self
):
...
@@ -308,8 +308,8 @@ class SecurityPolicy(object):
...
@@ -308,8 +308,8 @@ class SecurityPolicy(object):
self
.
asymmetric_cryptography
=
CryptographyNone
()
self
.
asymmetric_cryptography
=
CryptographyNone
()
self
.
symmetric_cryptography
=
CryptographyNone
()
self
.
symmetric_cryptography
=
CryptographyNone
()
self
.
Mode
=
auto
.
MessageSecurityMode
.
None_
self
.
Mode
=
auto
.
MessageSecurityMode
.
None_
self
.
server_certificate
=
b""
self
.
server_certificate
=
None
self
.
client_certificate
=
b""
self
.
client_certificate
=
None
def
make_symmetric_key
(
self
,
a
,
b
):
def
make_symmetric_key
(
self
,
a
,
b
):
pass
pass
...
...
opcua/ua/uatypes.py
View file @
6a68a039
...
@@ -218,8 +218,6 @@ def pack_string(string):
...
@@ -218,8 +218,6 @@ def pack_string(string):
if
isinstance
(
string
,
unicode
):
if
isinstance
(
string
,
unicode
):
string
=
string
.
encode
(
'utf-8'
)
string
=
string
.
encode
(
'utf-8'
)
length
=
len
(
string
)
length
=
len
(
string
)
if
length
==
0
:
return
b'
\
xff
\
xff
\
xff
\
xff
'
return
uatype_Int32
.
pack
(
length
)
+
string
return
uatype_Int32
.
pack
(
length
)
+
string
pack_bytes
=
pack_string
pack_bytes
=
pack_string
...
@@ -228,13 +226,14 @@ pack_bytes = pack_string
...
@@ -228,13 +226,14 @@ pack_bytes = pack_string
def
unpack_bytes
(
data
):
def
unpack_bytes
(
data
):
length
=
uatype_Int32
.
unpack
(
data
.
read
(
4
))[
0
]
length
=
uatype_Int32
.
unpack
(
data
.
read
(
4
))[
0
]
if
length
==
-
1
:
if
length
==
-
1
:
# FIXME: return None, check it does not break things
return
None
return
b''
return
data
.
read
(
length
)
return
data
.
read
(
length
)
def
py3_unpack_string
(
data
):
def
py3_unpack_string
(
data
):
b
=
unpack_bytes
(
data
)
b
=
unpack_bytes
(
data
)
if
b
is
None
:
return
b
return
b
.
decode
(
"utf-8"
)
return
b
.
decode
(
"utf-8"
)
...
...
tests/tests.py
View file @
6a68a039
...
@@ -16,7 +16,7 @@ except ImportError:
...
@@ -16,7 +16,7 @@ except ImportError:
from
tests_cmd_lines
import
TestCmdLines
from
tests_cmd_lines
import
TestCmdLines
from
tests_server
import
TestServer
from
tests_server
import
TestServer
from
tests_client
import
TestClient
from
tests_client
import
TestClient
from
tests_unit
import
Unit
from
tests_unit
import
Test
Unit
if
CRYPTOGRAPHY_AVAILABLE
:
if
CRYPTOGRAPHY_AVAILABLE
:
from
tests_crypto_connect
import
TestCryptoConnect
from
tests_crypto_connect
import
TestCryptoConnect
...
...
tests/tests_unit.py
View file @
6a68a039
...
@@ -12,7 +12,7 @@ from opcua.ua.uatypes import flatten, get_shape, reshape
...
@@ -12,7 +12,7 @@ from opcua.ua.uatypes import flatten, get_shape, reshape
class
Unit
(
unittest
.
TestCase
):
class
Test
Unit
(
unittest
.
TestCase
):
'''
'''
Simple unit test that do not need to setup a server or a client
Simple unit test that do not need to setup a server or a client
...
@@ -140,13 +140,22 @@ class Unit(unittest.TestCase):
...
@@ -140,13 +140,22 @@ class Unit(unittest.TestCase):
with
self
.
assertRaises
(
ua
.
UaError
):
with
self
.
assertRaises
(
ua
.
UaError
):
ua
.
QualifiedName
.
from_string
(
"i:::yu"
)
ua
.
QualifiedName
.
from_string
(
"i:::yu"
)
def
test_expandednodeid
(
self
):
def
test_expandednodeid
(
self
):
nid
=
ua
.
ExpandedNodeId
()
nid
=
ua
.
ExpandedNodeId
()
self
.
assertEqual
(
nid
.
NodeIdType
,
ua
.
NodeIdType
.
TwoByte
)
self
.
assertEqual
(
nid
.
NodeIdType
,
ua
.
NodeIdType
.
TwoByte
)
nid2
=
ua
.
ExpandedNodeId
.
from_binary
(
ua
.
utils
.
Buffer
(
nid
.
to_binary
()))
nid2
=
ua
.
ExpandedNodeId
.
from_binary
(
ua
.
utils
.
Buffer
(
nid
.
to_binary
()))
self
.
assertEqual
(
nid
,
nid2
)
self
.
assertEqual
(
nid
,
nid2
)
def
test_null_string
(
self
):
v
=
ua
.
Variant
(
None
,
ua
.
VariantType
.
String
)
b
=
v
.
to_binary
()
v2
=
ua
.
Variant
.
from_binary
(
ua
.
utils
.
Buffer
(
b
))
self
.
assertEqual
(
v
.
Value
,
v2
.
Value
)
v
=
ua
.
Variant
(
""
,
ua
.
VariantType
.
String
)
b
=
v
.
to_binary
()
v2
=
ua
.
Variant
.
from_binary
(
ua
.
utils
.
Buffer
(
b
))
self
.
assertEqual
(
v
.
Value
,
v2
.
Value
)
def
test_extension_object
(
self
):
def
test_extension_object
(
self
):
obj
=
ua
.
UserNameIdentityToken
()
obj
=
ua
.
UserNameIdentityToken
()
obj
.
UserName
=
"admin"
obj
.
UserName
=
"admin"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment