]> git.llucax.com Git - software/pymin.git/blob - pymin/services/vpn/__init__.py
Merge branch 'master' of git.llucax.com.ar:/var/lib/git/software/pymin into procman
[software/pymin.git] / pymin / services / vpn / __init__.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 import os
4 import signal
5 from os import path
6
7
8 from pymin.seqtools import Sequence
9 from pymin.dispatcher import Handler, handler, HandlerError
10 from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
11                                 TransactionalHandler, DictSubHandler, DictComposedSubHandler, call, ExecutionError
12
13
14 class Host(Sequence):
15     def __init__(self, vpn_src, ip, vpn_src_net, key):
16         self.name = vpn_src
17         self.ip = ip
18         self.src_net = vpn_src_net
19         self.pub_key = key
20         self.dele = False
21
22     def as_tuple(self):
23         return(self.name, self.ip, self.src_net, self.pub_key)
24
25 class HostHandler(DictComposedSubHandler):
26
27     handler_help = u"Manage hosts for a vpn"
28     _comp_subhandler_cont = 'vpns'
29     _comp_subhandler_attr = 'hosts'
30     _comp_subhandler_class = Host
31
32     @handler('usage: add <vpn_src> <ip> <vpn_src_net> <key>')
33     def delete(self, vpn_src, host):
34         DictComposedSubHandler.delete(self, vpn_src, host)
35         if vpn_src in parent.vpns:
36             if host in parent.vpns[vpn_src].hosts:
37                 parent.vpns[vpn_src].hosts[host].dele = True
38
39
40 class Vpn(Sequence):
41     def __init__(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, pub_key, priv_key):
42         self.vpn_src = vpn_src
43         self.vpn_dst = vpn_dst
44         self.vpn_src_ip = vpn_src_ip
45         self.vpn_src_mask = vpn_src_mask
46         self.pub_key = pub_key
47         self.priv_key = priv_key
48         self.hosts = dict()
49         self.dele = False
50
51     def as_tuple(self):
52         return(self.vpn_src, self.vpn_dst, self.vpn_src_ip, self.vpn_src_mask, self.pub_key, self.priv_key)
53
54     def update(self, vpn_dst=None, vpn_src_ip=None, vpn_src_mask=None):
55         if vpn_dst is not None:
56             self.vpn_dst = vpn_dst
57         if vpn_src_ip is not None:
58             self.vpn_src_ip = vpn_src_ip
59         if vpn_src_mask is not None:
60             self.vpn_src_mask = vpn_src_mask
61
62
63 class VpnHandler(Restorable, ConfigWriter,
64                    TransactionalHandler, DictSubHandler):
65
66     handler_help = u"Manage vpn service"
67
68     _cont_subhandler_attr = 'vpns'
69     _cont_subhandler_class = Vpn
70
71     _persistent_attrs = ('vpns','hosts')
72
73     _restorable_defaults = dict(
74             vpns = dict(),
75             hosts = dict(),
76     )
77
78     _config_writer_files = ('tinc.conf','tinc-up','host')
79     _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
80
81     def __init__(self,  pickle_dir='.', config_dir='/etc/tinc'):
82         DictSubHandler.__init__(self,self)
83         self._config_writer_cfg_dir = config_dir
84         self._persistent_dir = pickle_dir
85         self._config_build_templates()
86         self._restore()
87         self.host = HostHandler(self)
88
89     @handler('usage : add <vpn_name> <vpn_dst> <vpn_src_ip> <vpn_src_mask>')
90     def add(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask):
91         if not vpn_src in self.vpns:
92             DictSubHandler.add(self,  vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask, None, None)
93         elif vpn_src in self.vpns:
94             if self.vpns[vpn_src].dele :
95                 self.vpns[vpn_src] = False
96
97     @handler('usage : delete <vpn_name>')
98     def delete(self, vpn_src):
99         if vpn_src in self.vpns:
100             self.vpns[vpn_src].dele = True;
101
102
103     @handler('usage: start <vpn_name>')
104     def start(self, vpn_src):
105         if vpn_src in self.vpns:
106             call(('tincd','--net='+ vpn_src))
107
108     @handler('usage: stop <vpn_name>')
109     def stop(self, vpn_src):
110         if vpn_src in self.vpns:
111             if path.exists('/var/run/tinc.' + vpn_src + '.pid'):
112                 pid = file('/var/run/tinc.' + vpn_src + '.pid').readline()
113                 try:
114                     os.kill(int(pid.strip()), signal.SIGTERM)
115                 except OSError:
116                     pass # XXX report error?
117
118     def _write_config(self):
119         for v in self.vpns.values():
120             #chek whether it's been created or not.
121             if not v.dele:
122                 if v.pub_key is None :
123                     try:
124                         print 'douugh'
125                         #first create the directory for the vpn
126                         call(('mkdir','-p', path.join(self._config_writer_cfg_dir, v.vpn_src ,'hosts')))
127                         #this command should generate 2 files inside the vpn
128                         #dir, one rsa_key.priv and one rsa_key.pub
129                         #for some reason debian does not work like this
130                         call(('tincd','-n', v.vpn_src,'-K','<','/dev/null'))
131                         #open the created files and load the keys
132                         f = file(path.join(self._config_writer_cfg_dir, v.vpn_src , 'rsa_key.priv'), 'r')
133                         priv = f.read()
134                         f.close()
135                         f = file(path.join(self._config_writer_cfg_dir, v.vpn_src ,'rsa_key.pub'), 'r')
136                         pub = f.read()
137                         f.close()
138                         v.pub_key = pub
139                         v.priv_key = priv
140                     except ExecutionError, e:
141                         print e
142
143                 vars = dict(
144                     vpn = v,
145                 )
146                 self._write_single_config('tinc.conf',path.join(v.vpn_src,'tinc.conf'),vars)
147                 self._write_single_config('tinc-up',path.join(v.vpn_src,'tinc-up'),vars)
148                 for h in v.hosts.values():
149                     if not h.dele:
150                         vars = dict(
151                             host = h,
152                         )
153                         self._write_single_config('host',path.join(v.vpn_src,'hosts',h.name),vars)
154                     else:
155                         try:
156                             call(('rm','-f', path.join(v.vpn_src,'hosts',h.name)))
157                             del v.hosts[h.name]
158                         except ExecutionError, e:
159                             print e
160             else:
161                 #delete the vpn root at tinc dir
162                 if path.exists('/etc/tinc/' + v.vpn_src):
163                     self.stop(v.vpn_src)
164                     call(('rm','-rf','/etc/tinc/' + v.vpn_src))
165                     del self.vpns[v.vpn_src]
166
167
168 if __name__ == '__main__':
169     v = VpnHandler()
170     v.add('prueba','sarasa','192.168.0.188','255.255.255.0')
171     v.host.add('prueba', 'azazel' ,'192.168.0.77', '192.168.0.0','kjdhfkbdskljvkjblkbjeslkjbvkljbselvslberjhbvslbevlhb')
172     v.commit()