summaryrefslogtreecommitdiff
path: root/tests/unit/vpn
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2017-08-19 17:04:04 -0400
committerKali Kaneko <kali@leap.se>2017-08-30 16:17:55 -0400
commit46eff942e4e3b3c7ddbecd170dd7d5078b8debc0 (patch)
tree4fd1f606d4ae7ffe87303b6372df5e43467957cb /tests/unit/vpn
parentf23f2fd7dc530e4b4502c2cf2e771f91644b35ef (diff)
[feature] add twisted protocol for handling openvpn management
Diffstat (limited to 'tests/unit/vpn')
-rw-r--r--tests/unit/vpn/session1.data34
-rw-r--r--tests/unit/vpn/session2.data38
-rw-r--r--tests/unit/vpn/test_management.py129
3 files changed, 201 insertions, 0 deletions
diff --git a/tests/unit/vpn/session1.data b/tests/unit/vpn/session1.data
new file mode 100644
index 0000000..5381bad
--- /dev/null
+++ b/tests/unit/vpn/session1.data
@@ -0,0 +1,34 @@
+>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
+SUCCESS: real-time log notification set to ON
+OpenVPN Version: OpenVPN 2.4.0 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Jun 22 2017
+Management Version: 1
+END
+SUCCESS: pid=23783
+SUCCESS: real-time state notification set to ON
+SUCCESS: bytecount interval changed
+>BYTECOUNT:26,14
+>STATE:1503010298,AUTH,,,,,,
+>LOG:1503010302,I,[otter.demo.bitmask.net] Peer Connection Initiated with [AF_INET]46.165.242.169:443
+>STATE:1503010303,GET_CONFIG,,,,,,
+>BYTECOUNT:5573,3716
+>LOG:1503010303,W,Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore.
+>LOG:1503010303,I,TUN/TAP device tun0 opened
+>LOG:1503010303,D,do_ifconfig, tt->did_ifconfig_ipv6_setup=1
+>STATE:1503010303,ASSIGN_IP,,10.42.0.18,,,,,2001:db8:123::1010
+>LOG:1503010303,I,/sbin/ip link set dev tun0 up mtu 1500
+>LOG:1503010303,I,/sbin/ip addr add dev tun0 10.42.0.18/21 broadcast 10.42.7.255
+>LOG:1503010303,I,/sbin/ip -6 addr add 2001:db8:123::1010/64 dev tun0
+>LOG:1503010303,W,ERROR: Linux route add command failed: external program exited with error status: 2
+>LOG:1503010304,I,add_route_ipv6(2000::/3 -> 2001:db8:123::1 metric -1) dev tun0
+>LOG:1503010304,I,GID set to nogroup
+>LOG:1503010304,I,UID set to nobody
+>LOG:1503010304,I,Initialization Sequence Completed
+>STATE:1503010304,CONNECTED,SUCCESS,10.42.0.18,46.165.242.169,443,,,2001:db8:123::1010
+>BYTECOUNT:6279,4102
+>BYTECOUNT:6577,4400
+>BYTECOUNT:6923,4847
+>BYTECOUNT:7237,4996
+>BYTECOUNT:7732,5443
+>BYTECOUNT:10355,6055
+>BYTECOUNT:17168,7657
+
diff --git a/tests/unit/vpn/session2.data b/tests/unit/vpn/session2.data
new file mode 100644
index 0000000..cd2ece5
--- /dev/null
+++ b/tests/unit/vpn/session2.data
@@ -0,0 +1,38 @@
+>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
+SUCCESS: real-time log notification set to ON
+OpenVPN Version: OpenVPN 2.4.0 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Jun 22 2017
+Management Version: 1
+END
+SUCCESS: pid=30641
+SUCCESS: real-time state notification set to ON
+SUCCESS: bytecount interval changed
+>BYTECOUNT:26,14
+>STATE:1503079741,AUTH,,,,,,
+>BYTECOUNT:5168,3078
+>LOG:1503079746,I,[otter.demo.bitmask.net] Peer Connection Initiated with [AF_INET]46.165.242.169:443
+>STATE:1503079747,GET_CONFIG,,,,,,
+>LOG:1503079748,W,Note: option tun-ipv6 is ignored because modern operating systems do not need special IPv6 tun handling anymore.
+>LOG:1503079748,I,TUN/TAP device tun0 opened
+>LOG:1503079748,D,do_ifconfig, tt->did_ifconfig_ipv6_setup=1
+>STATE:1503079748,ASSIGN_IP,,10.42.0.12,,,,,2001:db8:123::100a
+>LOG:1503079748,I,/sbin/ip link set dev tun0 up mtu 1500
+>LOG:1503079748,I,/sbin/ip addr add dev tun0 10.42.0.12/21 broadcast 10.42.7.255
+>LOG:1503079748,I,/sbin/ip -6 addr add 2001:db8:123::100a/64 dev tun0
+>LOG:1503079748,W,ERROR: Linux route add command failed: external program exited with error status: 2
+>LOG:1503079748,I,add_route_ipv6(2000::/3 -> 2001:db8:123::1 metric -1) dev tun0
+>LOG:1503079748,I,GID set to nogroup
+>LOG:1503079748,I,UID set to nobody
+>LOG:1503079748,I,Initialization Sequence Completed
+>STATE:1503079748,CONNECTED,SUCCESS,10.42.0.12,46.165.242.169,443,,,2001:db8:123::100a
+SUCCESS: signal SIGTERM thrown
+>LOG:1503079751,W,ERROR: Linux route delete command failed: external program exited with error status: 2
+>LOG:1503079751,W,ERROR: Linux route delete command failed: external program exited with error status: 2
+>LOG:1503079751,W,ERROR: Linux route delete command failed: external program exited with error status: 2
+>LOG:1503079751,I,delete_route_ipv6(2000::/3)
+>LOG:1503079751,W,ERROR: Linux route -6/-A inet6 del command failed: external program exited with error status: 2
+>LOG:1503079751,I,/sbin/ip addr del dev tun0 10.42.0.12/21
+>LOG:1503079751,W,Linux ip addr del failed: external program exited with error status: 2
+>LOG:1503079751,I,/sbin/ip -6 addr del 2001:db8:123::100a/64 dev tun0
+>LOG:1503079751,W,Linux ip -6 addr del failed: external program exited with error status: 2
+>LOG:1503079751,I,SIGTERM[hard,] received, process exiting
+>STATE:1503079751,EXITING,SIGTERM,,,,,
diff --git a/tests/unit/vpn/test_management.py b/tests/unit/vpn/test_management.py
new file mode 100644
index 0000000..c70d768
--- /dev/null
+++ b/tests/unit/vpn/test_management.py
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+# test_management.py
+# Copyright (C) 2017 LEAP Encryption Access Project
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Tests for the VPN Management Interface
+"""
+
+import StringIO
+
+from twisted.trial import unittest
+from leap.bitmask.vpn.management import ManagementProtocol
+
+
+session1 = open('session1.data').readlines()
+session2 = open('session2.data').readlines()
+
+
+def feed_the_protocol(protocol, data):
+ for line in data:
+ protocol.lineReceived(line)
+
+
+class StateListener(object):
+
+ def __init__(self):
+ self.states = []
+
+ def change_state(self, state):
+ self.states.append(state)
+
+
+class ManagementTestCase(unittest.TestCase):
+
+ def test_final_state_is_connected(self):
+ proto = ManagementProtocol()
+ feed_the_protocol(proto, session1)
+ assert proto.state.state == 'CONNECTED'
+ assert proto.state.simple == 'ON'
+ assert proto.remote == '46.165.242.169'
+
+ def test_final_state_stopping(self):
+ proto = ManagementProtocol()
+ feed_the_protocol(proto, session2)
+ assert proto.state.state == 'EXITING'
+ assert proto.state.simple == 'STOPPING'
+
+ def test_get_state_history(self):
+ proto = ManagementProtocol()
+ feed_the_protocol(proto, session1)
+ log = proto.getStateHistory()
+ states = [st.state for st in log.values()]
+ assert len(log) == 4
+ assert states == ['AUTH', 'GET_CONFIG', 'ASSIGN_IP', 'CONNECTED']
+
+ def test_state_listener(self):
+ proto = ManagementProtocol()
+ listener = StateListener()
+ proto.addStateListener(listener)
+ feed_the_protocol(proto, session1)
+ states = [st.state for st in listener.states]
+ assert states == ['AUTH', 'GET_CONFIG', 'ASSIGN_IP', 'CONNECTED']
+
+ def test_bytecount(self):
+ proto = ManagementProtocol()
+ feed_the_protocol(proto, session1)
+ assert proto.traffic.down == 17168
+ assert proto.traffic.up == 7657
+
+ def test_bytecount_rate(self):
+ proto = ManagementProtocol()
+ proto.traffic.update(1024, 512, 1)
+ proto.traffic.update(2048, 1024, 2)
+ print proto.traffic._buf
+ assert proto.traffic.down == 2048
+ assert proto.traffic.up == 1024
+ assert proto.traffic.get_rate() == ['1.0 K', '512.0 B']
+
+ def test_get_pid(self):
+ proto = ManagementProtocol()
+ proto.transport = StringIO.StringIO()
+ assert proto.pid == None
+ proto.get_pid()
+ pid_lines = ['SUCCESS: pid=99999']
+ feed_the_protocol(proto, pid_lines)
+ assert proto.pid == 99999
+
+ def test_parse_version_string(self):
+ proto = ManagementProtocol()
+ proto.transport = StringIO.StringIO()
+ assert proto.openvpn_version == ''
+ feed_the_protocol(proto, session1[2:4])
+ proto.getVersion()
+ feed_the_protocol(proto, ['END'])
+ assert proto.openvpn_version.startswith('OpenVPN 2.4.0')
+
+ def test_get_info(self):
+ proto = ManagementProtocol()
+ proto.transport = StringIO.StringIO()
+ feed_the_protocol(proto, session1)
+
+ feed_the_protocol(proto, session1[2:4])
+ proto.getVersion()
+ feed_the_protocol(proto, ['END'])
+ proto.get_pid()
+ pid_lines = ['SUCCESS: pid=23783']
+ feed_the_protocol(proto, pid_lines)
+
+ info = proto.getInfo()
+ assert info['remote'] == '46.165.242.169'
+ assert info['rport'] == '443'
+ assert info['state'] == 'CONNECTED'
+ assert info['state_simple'] == 'ON'
+ assert info['state_legend'] == 'Initialization Sequence Completed'
+ assert info['openvpn_version'].startswith('OpenVPN 2.4.0')
+ assert info['pid'] == 23783