1 # vim: set encoding=utf-8 et sw=4 sts=4 :
6 from pymin.seqtools import Sequence
7 from pymin.dispatcher import Handler, handler, HandlerError
8 from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
9 TransactionalHandler, DictSubHandler, DictComposedSubHandler, call, ExecutionError
13 def __init__(self, vpn_src, ip, vpn_src_net, key):
16 self.src_net = vpn_src_net
21 return(self.name, self.ip, self.src_net, self.pub_key)
23 class HostHandler(DictComposedSubHandler):
25 handler_help = u"Manage hosts for a vpn"
26 _comp_subhandler_cont = 'vpns'
27 _comp_subhandler_attr = 'hosts'
28 _comp_subhandler_class = Host
30 @handler('usage: add <vpn_src> <ip> <vpn_src_net> <key>')
31 def delete(self, vpn_src, host):
32 DictComposedSubHandler.delete(self, vpn_src, host)
33 if vpn_src in parent.vpns:
34 if host in parent.vpns[vpn_src].hosts:
35 parent.vpns[vpn_src].hosts[host].dele = True
39 def __init__(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, pub_key, priv_key):
40 self.vpn_src = vpn_src
41 self.vpn_dst = vpn_dst
42 self.vpn_src_ip = vpn_src_ip
43 self.vpn_src_mask = vpn_src_mask
44 self.pub_key = pub_key
45 self.priv_key = priv_key
50 return(self.vpn_src, self.vpn_dst, self.vpn_src_ip, self.vpn_src_mask, self.pub_key, self.priv_key)
52 def update(self, vpn_dst=None, vpn_src_ip=None, vpn_src_mask=None):
53 if vpn_dst is not None:
54 self.vpn_dst = vpn_dst
55 if vpn_src_ip is not None:
56 self.vpn_src_ip = vpn_src_ip
57 if vpn_src_mask is not None:
58 self.vpn_src_mask = vpn_src_mask
61 class VpnHandler(Restorable, ConfigWriter,
62 TransactionalHandler, DictSubHandler):
64 handler_help = u"Manage vpn service"
66 _cont_subhandler_attr = 'vpns'
67 _cont_subhandler_class = Vpn
69 _persistent_attrs = ('vpns','hosts')
71 _restorable_defaults = dict(
76 _config_writer_files = ('tinc.conf','tinc-up','host')
77 _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
79 def __init__(self, pickle_dir='.', config_dir='/etc/tinc'):
80 DictSubHandler.__init__(self,self)
81 self._config_writer_cfg_dir = config_dir
82 self._persistent_dir = pickle_dir
83 self._config_build_templates()
85 self.host = HostHandler(self)
87 @handler('usage : add <vpn_name> <vpn_dst> <vpn_src_ip> <vpn_src_mask>')
88 def add(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask):
89 if not vpn_src in self.vpns:
90 DictSubHandler.add(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, None, None)
91 elif vpn_src in self.vpns:
92 if self.vpns[vpn_src].dele :
93 self.vpns[vpn_src] = False
95 @handler('usage : delete <vpn_name>')
96 def delete(self, vpn_src):
97 if vpn_src in self.vpns:
98 self.vpns[vpn_src].dele = True;
101 @handler('usage: start <vpn_name>')
102 def start(self, vpn_src):
103 if vpn_src in self.vpns:
104 call(('tincd','--net=',vpn_src))
106 @handler('usage: stop <vpn_name>')
107 def stop(self, vpn_src):
108 if vpn_src in self.vpns:
109 if path.exists('/var/lib/run/tincd.' + vpn_src + '.pid'):
110 pid = file('/var/lib/run/tincd.' + vpn_src + '.pid').readline()
112 os.kill(int(pid.strip()), SIGTERM)
114 pass # XXX report error?
116 def _write_config(self):
117 for v in self.vpns.values():
118 #chek whether it's been created or not.
120 if v.pub_key is None :
123 #first create the directory for the vpn
124 call(('mkdir','-p', path.join(self._config_writer_cfg_dir, v.vpn_src ,'hosts')))
125 #this command should generate 2 files inside the vpn
126 #dir, one rsa_key.priv and one rsa_key.pub
127 #for some reason debian does not work like this
128 call(('tincd','-n', v.vpn_src,'-K','<','/dev/null'))
129 #open the created files and load the keys
130 f = file(path.join(self._config_writer_cfg_dir, v.vpn_src , 'rsa_key.priv'), 'r')
133 f = file(path.join(self._config_writer_cfg_dir, v.vpn_src ,'rsa_key.pub'), 'r')
138 except ExecutionError, e:
144 self._write_single_config('tinc.conf',path.join(v.vpn_src,'tinc.conf'),vars)
145 self._write_single_config('tinc-up',path.join(v.vpn_src,'tinc-up'),vars)
146 for h in v.hosts.values():
151 self._write_single_config('host',path.join(v.vpn_src,'hosts',h.name),vars)
154 call(('rm','-f', path.join(v.vpn_src,'hosts',h.name)))
156 except ExecutionError, e:
159 #delete the vpn root at tinc dir
160 if path.exists('/etc/tinc/' + v.vpn_src):
162 call(('rm','-rf','/etc/tinc/' + v.vpn_src))
163 del self.vpns[v.vpn_src]
166 if __name__ == '__main__':
168 v.add('test','127.0.0.1','192.168.0.1','255.255.255.0')
169 #v.host.add('test', 'sarasa' ,'127.0.0.1', '205.25.36.36','kjdhfkbdskljvkjblkbjeslkjbvkljbselvslberjhbvslbevlhb')