]> git.llucax.com Git - software/pymin.git/commitdiff
VPN support added.
authorNicolas Emiliani <nemiliani@integratech.com.ar>
Sat, 10 Nov 2007 19:48:52 +0000 (16:48 -0300)
committerNicolas Emiliani <nemiliani@integratech.com.ar>
Sat, 10 Nov 2007 19:48:52 +0000 (16:48 -0300)
pymin/services/vpn/__init__.py [new file with mode: 0644]
pymin/services/vpn/templates/host [new file with mode: 0644]
pymin/services/vpn/templates/tinc-up [new file with mode: 0644]
pymin/services/vpn/templates/tinc.conf [new file with mode: 0644]

diff --git a/pymin/services/vpn/__init__.py b/pymin/services/vpn/__init__.py
new file mode 100644 (file)
index 0000000..789d137
--- /dev/null
@@ -0,0 +1,171 @@
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+import os
+from os import path
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
+                                TransactionalHandler, DictSubHandler, DictComposedSubHandler, call, ExecutionError
+
+
+class Host(Sequence):
+    def __init__(self, vpn_src, ip, vpn_src_net, key):
+        self.name = vpn_src
+        self.ip = ip
+        self.src_net = vpn_src_net
+        self.pub_key = key
+        self.dele = False
+
+    def as_tuple(self):
+        return(self.name, self.ip, self.src_net, self.pub_key)
+
+class HostHandler(DictComposedSubHandler):
+
+    handler_help = u"Manage hosts for a vpn"
+    _comp_subhandler_cont = 'vpns'
+    _comp_subhandler_attr = 'hosts'
+    _comp_subhandler_class = Host
+
+    @handler('usage: add <vpn_src> <ip> <vpn_src_net> <key>')
+    def delete(self, vpn_src, host):
+        DictComposedSubHandler.delete(self, vpn_src, host)
+        if vpn_src in parent.vpns:
+            if host in parent.vpns[vpn_src].hosts:
+                parent.vpns[vpn_src].hosts[host].dele = True
+
+
+class Vpn(Sequence):
+    def __init__(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, pub_key, priv_key):
+        self.vpn_src = vpn_src
+        self.vpn_dst = vpn_dst
+        self.vpn_src_ip = vpn_src_ip
+        self.vpn_src_mask = vpn_src_mask
+        self.pub_key = pub_key
+        self.priv_key = priv_key
+        self.hosts = dict()
+        self.dele = False
+
+    def as_tuple(self):
+        return(self.vpn_src, self.vpn_dst, self.vpn_src_ip, self.vpn_src_mask, self.pub_key, self.priv_key)
+
+    def update(self, vpn_dst=None, vpn_src_ip=None, vpn_src_mask=None):
+        if vpn_dst is not None:
+            self.vpn_dst = vpn_dst
+        if vpn_src_ip is not None:
+            self.vpn_src_ip = vpn_src_ip
+        if vpn_src_mask is not None:
+            self.vpn_src_mask = vpn_src_mask
+
+
+class VpnHandler(Restorable, ConfigWriter,
+                   TransactionalHandler, DictSubHandler):
+
+    handler_help = u"Manage vpn service"
+
+    _cont_subhandler_attr = 'vpns'
+    _cont_subhandler_class = Vpn
+
+    _persistent_attrs = ('vpns','hosts')
+
+    _restorable_defaults = dict(
+            vpns = dict(),
+            hosts = dict(),
+    )
+
+    _config_writer_files = ('tinc.conf','tinc-up','host')
+    _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+    def __init__(self,  pickle_dir='.', config_dir='/etc/tinc'):
+        DictSubHandler.__init__(self,self)
+        self._config_writer_cfg_dir = config_dir
+        self._persistent_dir = pickle_dir
+        self._config_build_templates()
+        self._restore()
+        self.host = HostHandler(self)
+
+    @handler('usage : add <vpn_name> <vpn_dst> <vpn_src_ip> <vpn_src_mask>')
+    def add(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask):
+        if not vpn_src in self.vpns:
+            DictSubHandler.add(self,  vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, None, None)
+        elif vpn_src in self.vpns:
+            if self.vpns[vpn_src].dele :
+                self.vpns[vpn_src] = False
+
+    @handler('usage : delete <vpn_name>')
+    def delete(self, vpn_src):
+        if vpn_src in self.vpns:
+            self.vpns[vpn_src].dele = True;
+
+
+    @handler('usage: start <vpn_name>')
+    def start(self, vpn_src):
+        if vpn_src in self.vpns:
+            call(('tincd','--net=',vpn_src))
+
+    @handler('usage: stop <vpn_name>')
+    def stop(self, vpn_src):
+        if vpn_src in self.vpns:
+            if path.exists('/var/lib/run/tincd.' + vpn_src + '.pid'):
+                pid = file('/var/lib/run/tincd.' + vpn_src + '.pid').readline()
+                try:
+                    os.kill(int(pid.strip()), SIGTERM)
+                except OSError:
+                    pass # XXX report error?
+
+    def _write_config(self):
+        for v in self.vpns.values():
+            #chek whether it's been created or not.
+            if not v.dele:
+                if v.pub_key is None :
+                    try:
+                        print 'douugh'
+                        #first create the directory for the vpn
+                        call(('mkdir','-p', path.join(self._config_writer_cfg_dir, v.vpn_src ,'hosts')))
+                        #this command should generate 2 files inside the vpn
+                        #dir, one rsa_key.priv and one rsa_key.pub
+                        #for some reason debian does not work like this
+                        call(('tincd','-n', v.vpn_src,'-K','<','/dev/null'))
+                        #open the created files and load the keys
+                        f = file(path.join(self._config_writer_cfg_dir, v.vpn_src , 'rsa_key.priv'), 'r')
+                        priv = f.read()
+                        f.close()
+                        f = file(path.join(self._config_writer_cfg_dir, v.vpn_src ,'rsa_key.pub'), 'r')
+                        pub = f.read()
+                        f.close()
+                        v.pub_key = pub
+                        v.priv_key = priv
+                    except ExecutionError, e:
+                        print e
+
+                vars = dict(
+                    vpn = v,
+                )
+                self._write_single_config('tinc.conf',path.join(v.vpn_src,'tinc.conf'),vars)
+                self._write_single_config('tinc-up',path.join(v.vpn_src,'tinc-up'),vars)
+                for h in v.hosts.values():
+                    if not h.dele:
+                        vars = dict(
+                            host = h,
+                        )
+                        self._write_single_config('host',path.join(v.vpn_src,'hosts',h.name),vars)
+                    else:
+                        try:
+                            call(('rm','-f', path.join(v.vpn_src,'hosts',h.name)))
+                            del v.hosts[h.name]
+                        except ExecutionError, e:
+                            print e
+            else:
+                #delete the vpn root at tinc dir
+                if path.exists('/etc/tinc/' + v.vpn_src):
+                    self.stop(v.vpn_src)
+                    call(('rm','-rf','/etc/tinc/' + v.vpn_src))
+                    del self.vpns[v.vpn_src]
+
+
+if __name__ == '__main__':
+    v = VpnHandler()
+    v.add('test','127.0.0.1','192.168.0.1','255.255.255.0')
+    #v.host.add('test', 'sarasa' ,'127.0.0.1', '205.25.36.36','kjdhfkbdskljvkjblkbjeslkjbvkljbselvslberjhbvslbevlhb')
+    v.delete('test')
+    v.commit()
diff --git a/pymin/services/vpn/templates/host b/pymin/services/vpn/templates/host
new file mode 100644 (file)
index 0000000..c2a2acb
--- /dev/null
@@ -0,0 +1,3 @@
+Address = ${host.ip}
+Subnet = ${host.src_net}
+${host.pub_key}
diff --git a/pymin/services/vpn/templates/tinc-up b/pymin/services/vpn/templates/tinc-up
new file mode 100644 (file)
index 0000000..fa9b987
--- /dev/null
@@ -0,0 +1 @@
+ifconfig $INTERFACE ${vpn.vpn_src_ip} netmask ${vpn.vpn_src_mask}
diff --git a/pymin/services/vpn/templates/tinc.conf b/pymin/services/vpn/templates/tinc.conf
new file mode 100644 (file)
index 0000000..a3e45ff
--- /dev/null
@@ -0,0 +1,4 @@
+Name = ${vpn.vpn_src}
+Device = /dev/net/tun
+PrivateKeyFile = /etc/tinc/${vpn.vpn_src}/rsa_key.priv
+ConnectTo = ${vpn.vpn_dst}