Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] OPC UA #1569

Closed
wants to merge 78 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
ef76757
Some initial work on implementing the OPC UA packet structure
mlgiraud Nov 7, 2017
f7da226
Continue implementing builtins + message structure
mlgiraud Nov 30, 2017
2f7a4ff
Added NodeId implementation
mlgiraud Nov 30, 2017
c6f902a
Split SecureConversation into sym and asym
mlgiraud Nov 30, 2017
123c4a5
Add first version of schema parser, more NodeIds
mlgiraud Dec 4, 2017
4819488
Add NodeIds file
mlgiraud Dec 8, 2017
b6054e0
Fixed ExpandedNodeIds
mlgiraud Dec 8, 2017
08e001e
SchemaParser now suppoerts arrays/length fields
mlgiraud Dec 8, 2017
622ead4
Link messages to SecureConversation via ids
mlgiraud Dec 8, 2017
9154665
Fix python2 incompatibility
mlgiraud Dec 11, 2017
5299873
Improve Null (Byte)String handling
mlgiraud Dec 15, 2017
4f9a5f1
Add DiagnosticInfo implementation
mlgiraud Dec 15, 2017
4b5417c
Reduce complexity with function generator
mlgiraud Dec 15, 2017
89218d8
Implement DataValue and vastly increase efficiency
mlgiraud Dec 16, 2017
7736566
First working version of Extension objects
mlgiraud Dec 19, 2017
b0c202f
Add flatten function
mlgiraud Dec 24, 2017
43fac0c
Implement Variant builtin
mlgiraud Dec 24, 2017
4c9985b
Fix Variant bug
mlgiraud Dec 24, 2017
28b6c3e
Fix encoding/decoding of variants
mlgiraud Dec 26, 2017
9f28920
Fix incorrect NodeId
mlgiraud Jan 3, 2018
3787e1f
Make checks more pythonic
mlgiraud Jan 3, 2018
383ac93
Fix ExtensionObject raw bytes
mlgiraud Jan 3, 2018
ab8e8ed
Fix tcp post_build
mlgiraud Jan 4, 2018
261096b
Start implementing client automaton
mlgiraud Jan 4, 2018
2f3a2ba
Add types.py, continue automaton impl
mlgiraud Jan 5, 2018
ecaab67
Add documentation
mlgiraud Jan 7, 2018
2872321
Add documentation and sensible default values
mlgiraud Jan 7, 2018
bdec69f
Work on client automaton
mlgiraud Jan 7, 2018
ba5cbbb
Start implementing cryptography
mlgiraud Jan 10, 2018
8648c60
Add certificate and thumbprint handling if policy not none
mlgiraud Jan 12, 2018
9ab1094
Finish asymmetric encryption
mlgiraud Jan 14, 2018
fcdf83e
Implement asymmetric decryption
mlgiraud Jan 14, 2018
cf45fb8
Add experimental changes
mlgiraud Jan 14, 2018
4120c7b
Add connectionContext and some post_build.
mlgiraud Jan 15, 2018
a367185
Add symmetric encryption
mlgiraud Jan 15, 2018
92e5ec3
Do not attempt to decode chunked data.
mlgiraud Jan 17, 2018
bd61bdc
Fix bug when policy is Sign only
mlgiraud Jan 17, 2018
919bc36
Add chunking. Dechunking still missing
mlgiraud Jan 17, 2018
d0f83d5
Add status code descriptions
mlgiraud Jan 17, 2018
f586b8b
Calculate chunk data size correctly
mlgiraud Jan 17, 2018
cce5ef6
chunkify now is a generator.
mlgiraud Jan 19, 2018
d7d8c7e
Implement dechunking/reassembly
mlgiraud Jan 19, 2018
7c184ed
Fix imports
mlgiraud Jan 22, 2018
fa93b92
Added post_build to Hello message
mlgiraud Jan 22, 2018
e0bac05
First version of ua tcp automaton
mlgiraud Jan 22, 2018
8e78bfb
Bugfixes and further work on tcpClient
mlgiraud Jan 25, 2018
264ef74
Rename
mlgiraud Feb 11, 2018
fa7989c
Exclude private keys, certs and venv
mlgiraud Feb 11, 2018
1c0ac72
Fix i2h bug
mlgiraud Feb 11, 2018
cf96139
First version of SecureConversation client
mlgiraud Feb 27, 2018
4e1f844
Add default for SecurityMode if SecurityPolicy#None is used
mlgiraud Feb 28, 2018
e9a7011
Only overwrite policy if data is none
mlgiraud Mar 1, 2018
6472ef6
Don't store packets. Really.... Why????
mlgiraud Mar 1, 2018
e80b5ec
Correctly infer CLO message type and send CLO messages in automaton
mlgiraud Mar 2, 2018
a08cf10
Fix Automaton resource deallocation
mlgiraud Mar 3, 2018
3a7ef9c
Fix messages changing before they are sent
mlgiraud Mar 3, 2018
58eb90a
Wait for socket to close before reopening
mlgiraud Mar 4, 2018
9695df0
Add timeout to atmt and fix connectionContext inconsitencies
mlgiraud Mar 6, 2018
c98744d
Add first version of session client
mlgiraud Mar 7, 2018
94bb5bb
Maybe fix automaton crashing after 2^16 packets
mlgiraud Mar 7, 2018
12bbd35
Fix everything
mlgiraud Mar 7, 2018
1a7d2ab
Add activate session to sessionClient
mlgiraud Mar 7, 2018
ade4f90
Reset the security token
mlgiraud Mar 8, 2018
2fafd23
Remove print
mlgiraud Mar 8, 2018
318cf4e
Add datetime conversion
mlgiraud Mar 8, 2018
1e77c43
Isutest hacks
mlgiraud Mar 8, 2018
d1ae55c
Fix session close
mlgiraud Mar 8, 2018
4d79c1d
Fix multithreading issues
mlgiraud Mar 8, 2018
2caf82b
Implement TODO
mlgiraud Mar 8, 2018
dbf4396
Add reset state for isutest
mlgiraud Mar 10, 2018
3770bea
Fix string encoding/decoding error
mlgiraud Mar 10, 2018
137f60f
Fix NodeId error
mlgiraud Mar 12, 2018
61a9af8
Bugfixes and compatibility fixes
mlgiraud Mar 15, 2018
82ed886
Implement session signature
mlgiraud Mar 20, 2018
4ca2a24
Rename module
mlgiraud Mar 22, 2018
49b1b4d
Minor fix
mlgiraud Mar 25, 2018
0efef82
Add documentation
mlgiraud Mar 26, 2018
10d5081
Add documentation
mlgiraud Mar 27, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ scapy/VERSION
test/*.html
.tox
doc/scapy/_build

.idea/
/venv*/
*.der
*.pem
3 changes: 3 additions & 0 deletions scapy/contrib/opcua/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Tools for handling OPC UA communication
"""
Empty file.
111 changes: 111 additions & 0 deletions scapy/contrib/opcua/binary/automaton.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# coding=utf-8
"""
This module contains an automaton prototype with methods that are used by both the client and server automaton.
"""
import copy
import logging
from scapy.automaton import Automaton, Message, _ATMT_Command, select_objects
from scapy.contrib.opcua.helpers import UaConnectionContext
import os


class _UaAutomaton(Automaton):

def __init__(self, *args, **kwargs):
super(_UaAutomaton, self).__init__(*args, **kwargs)
self._stopped = False

def parse_args(self, debug=0, store=False, connectionContext=UaConnectionContext(), target="localhost",
targetPort=4840, timeout=None, **kwargs):
super(_UaAutomaton, self).parse_args(debug, store, **kwargs)
self.target = target
self.targetPort = targetPort
self._connectionContextProto = copy.copy(connectionContext)
self._connectionContext = connectionContext
self._timeout = timeout
self.send_sock_class = lambda **x: None
self.recv_sock_class = lambda **x: None
self.send_sock = None
self.listen_sock = None

def __del__(self):
if not self._stopped:
super(_UaAutomaton, self).__del__()

def stop(self):
"""
Stops the automaton.
This method is overridden to make sure the automaton is ended in a graceful manner.
This requires sending a message on the shutdown socket so that the automaton can
perform the necessary steps to correctly close the connection.
"""
self.io.shutdown.send(None)
ended = self.started.acquire(timeout=2)
if ended:
self.started.release()
else:
self.cmdin.send(Message(type=_ATMT_Command.STOP))
with self.started:
# Flush command pipes
while True:
r = select_objects([self.cmdin, self.cmdout], 0)
if not r:
break
for fd in r:
fd.recv()
self._close_sockets()
self._stopped = True

def _close_sockets(self):
"""
Closes all sockets used by the automaton.
The network sockets shall be closed by the automaton itself upon receiving the shutdown message.
"""
for name in self.ionames:
try:
os.close(self.ioin[name].rd)
except OSError:
pass
try:
os.close(self.ioin[name].wr)
except OSError:
pass
try:
os.close(self.ioout[name].rd)
except OSError:
pass
try:
os.close(self.ioout[name].wr)
except OSError:
pass
try:
os.close(self.cmdin.wr)
except OSError:
pass
try:
os.close(self.cmdin.rd)
except OSError:
pass
try:
os.close(self.cmdout.wr)
except OSError:
pass
try:
os.close(self.cmdout.rd)
except OSError:
pass

self.send_sock.close()

def _flush_buffers(self):
fds = [self.cmdin, self.cmdout]
for name in self.ionames:
fds.append(self.ioin[name])
fds.append(self.ioout[name])

while True:
r = select_objects(fds, 0)
if not r:
break
for fd in r:
fd.recv()
14 changes: 14 additions & 0 deletions scapy/contrib/opcua/binary/bindings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# coding=utf-8
"""
This module contains bindings to bind the OPC UA layers to the TCP layer (note: OPC UA TCP is a layer on top of TCP)
"""
from scapy.contrib.opcua.binary.tcp import UaTcp
from scapy.layers.inet import TCP
from scapy.packet import bind_layers


# Bind standard ports
# TODO: Make better layer bindings that do not depend on port numbers.
# TODO: investigate if possible to determine from MessageType
bind_layers(TCP, UaTcp, dport=4840) # We only need to bind UaTcp, since the dispatch_hook is used to determine
bind_layers(TCP, UaTcp, sport=4840) # whether we are dealing with UaTcp or UaSecureConversation
Loading