summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se (leap communications)>2019-07-08 18:27:11 +0200
committerKali Kaneko <kali@leap.se (leap communications)>2019-07-08 18:27:11 +0200
commit8d1f2ceadac382c6ea42ee3e29633cf99de1a58d (patch)
treeb3b32da98ea2c27aa58fa17bf0a596bf5714b477 /scripts
parent638ff1ddac9d45ad442e78bd698a39fa3469eb6d (diff)
generate eip-service.json
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/gen-shapeshifter-state.py62
-rwxr-xr-xscripts/simplevpn.py79
-rw-r--r--scripts/templates/.eip-service.json.swpbin0 -> 12288 bytes
-rw-r--r--scripts/templates/eip-service.json32
4 files changed, 173 insertions, 0 deletions
diff --git a/scripts/gen-shapeshifter-state.py b/scripts/gen-shapeshifter-state.py
new file mode 100755
index 0000000..e7b1ff2
--- /dev/null
+++ b/scripts/gen-shapeshifter-state.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+"""
+Generates the Curve25519 keypair that is needed by the shapeshifter-dispatcher
+server.
+
+Depends on python3-axolotl-curve25519 package.
+"""
+
+import base64
+import json
+import os
+
+import pysodium
+import binascii
+
+BRIDGE_PREAMBLE = "Bridge obfs4 <IP ADDRESS>:<PORT> <FINGERPRINT> cert="
+BRIDGE_END = " iat-mode=0"
+
+
+def generate(statedir):
+ try:
+ os.makedirs(statedir)
+ except Exception:
+ pass
+ print("[+] Generating shapeshifter parameters...")
+
+ public, private = pysodium.crypto_box_keypair()
+
+ priv_hex = binascii.b2a_hex(private)
+ pub_hex = binascii.b2a_hex(public)
+ node_id = os.urandom(20)
+ node_id_hex = binascii.b2a_hex(node_id)
+ drbg_seed = os.urandom(24)
+
+ def tostr(b):
+ return b.decode('utf-8')
+
+ with open(statedir + '/obfs4_state.json', 'w') as state:
+ state.write(json.dumps({
+ 'node-id': tostr(node_id_hex),
+ 'private-key': tostr(priv_hex),
+ 'public-key': tostr(pub_hex),
+ 'drbg-seed': tostr(binascii.b2a_hex(drbg_seed)),
+ 'iat-mode': 0}))
+
+ cert = base64.b64encode(node_id + pub_hex)
+ print("CERT:", cert)
+
+ with open(statedir + '/obfs4_cert.txt', 'w') as certf:
+ certf.write(tostr(cert).rstrip('='))
+
+ with open(statedir + '/obfs4_bridgeline.txt', 'w') as bridgef:
+ bridgef.write(BRIDGE_PREAMBLE + tostr(cert) + BRIDGE_END)
+ print("[+] done")
+
+
+if __name__ == "__main__":
+ import argparse
+ parser = argparse.ArgumentParser()
+ parser.add_argument("statedir")
+ args = parser.parse_args()
+ generate(args.statedir)
diff --git a/scripts/simplevpn.py b/scripts/simplevpn.py
new file mode 100755
index 0000000..7906e7c
--- /dev/null
+++ b/scripts/simplevpn.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+import argparse
+import os
+
+import yaml
+
+from jinja2 import Template
+
+
+class EIPConfig:
+ def __init__(self):
+ self.openvpn = dict()
+ self.locations = dict()
+ self.gateways = dict()
+ self.obfs4_cert = ""
+
+
+def parseConfig(provider_config):
+ with open(provider_config) as conf:
+ config = yaml.load(conf.read())
+ eip = EIPConfig()
+ eip.openvpn.update(yamlListToDict(config['openvpn']))
+
+ for loc in config['locations']:
+ eip.locations.update(yamlIdListToDict(loc))
+ for gw in config['gateways']:
+ eip.gateways.update(yamlIdListToDict(gw))
+ return eip
+
+
+def yamlListToDict(values):
+ vals = {}
+ for d in values:
+ for k, v in d.items():
+ vals[k] = v
+ return vals
+
+
+def yamlIdListToDict(data):
+ _d = {}
+ for identifier, values in data.items():
+ _d[identifier] = yamlListToDict(values)
+ return _d
+
+
+def patchObfs4Cert(config, cert):
+ for gw in config.gateways:
+ for options in config.gateways[gw]['transports']:
+ opts = {}
+ transport, _, _ = options
+ if transport == "obfs4":
+ opts['cert'] = cert
+ opts['iat-mode'] = 0
+ options.append(opts)
+ return config
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument("provider_config")
+ parser.add_argument("eip_template")
+ parser.add_argument("--obfs4_state")
+ args = parser.parse_args()
+
+ config = parseConfig(os.path.abspath(args.provider_config))
+
+ if args.obfs4_state:
+ obfs4_cert = open(
+ args.obfs4_state + '/obfs4_cert.txt').read().rstrip()
+ else:
+ obfs4_cert = None
+ patchObfs4Cert(config, obfs4_cert)
+
+ t = Template(open(args.eip_template).read())
+
+ print(t.render(
+ locations=config.locations,
+ gateways=config.gateways,
+ openvpn=config.openvpn))
diff --git a/scripts/templates/.eip-service.json.swp b/scripts/templates/.eip-service.json.swp
new file mode 100644
index 0000000..284242a
--- /dev/null
+++ b/scripts/templates/.eip-service.json.swp
Binary files differ
diff --git a/scripts/templates/eip-service.json b/scripts/templates/eip-service.json
new file mode 100644
index 0000000..8d1b0a1
--- /dev/null
+++ b/scripts/templates/eip-service.json
@@ -0,0 +1,32 @@
+{
+ "serial": 3,
+ "version": 3,
+ "locations": { {% for loc in locations %}
+ "{{loc}}": {
+ "name": "{{ locations[loc]["name"] }}",
+ "country_code": "{{ locations[loc]["country_code"] }}",
+ "hemisphere": "{{ locations[loc]["hemisphere"] }}",
+ "timezone": {{ locations[loc]["timezone"] }},
+ },{% endfor %}
+ },
+ "gateways": { {% for gw in gateways %}
+ "{{gw}}": {
+ "host": "{{ gateways[gw]["host"] }}",
+ "ip_address": "{{ gateways[gw]["ip_address"] }}",
+ "location": "{{ gateways[gw]["location"] }}",
+ "capabilities": {
+ "adblock": false,
+ "filter_dns": false,
+ "limited": false,
+ "transport": [ {% for tr, proto, port, options in gateways[gw]["transports"] %}
+ {"type": "{{ tr }}",
+ "protocols": ["{{ proto }}"],
+ "ports": [{{ port }}],{% if options %}
+ "options": {{ options | tojson }},{% endif %}
+ },{% endfor %}
+ ],
+ },
+ },{% endfor %}
+ },
+ "openvpn_configuration": {{ openvpn|tojson(indent=8) }}
+}