]> git.llucax.com Git - software/pymin.git/blob - pymin/services/vpn/__init__.py
VPN support added.
[software/pymin.git] / pymin / services / vpn / __init__.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 import os
4 from os import path
5
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
10
11
12 class Host(Sequence):
13     def __init__(self, vpn_src, ip, vpn_src_net, key):
14         self.name = vpn_src
15         self.ip = ip
16         self.src_net = vpn_src_net
17         self.pub_key = key
18         self.dele = False
19
20     def as_tuple(self):
21         return(self.name, self.ip, self.src_net, self.pub_key)
22
23 class HostHandler(DictComposedSubHandler):
24
25     handler_help = u"Manage hosts for a vpn"
26     _comp_subhandler_cont = 'vpns'
27     _comp_subhandler_attr = 'hosts'
28     _comp_subhandler_class = Host
29
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
36
37
38 class Vpn(Sequence):
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
46         self.hosts = dict()
47         self.dele = False
48
49     def as_tuple(self):
50         return(self.vpn_src, self.vpn_dst, self.vpn_src_ip, self.vpn_src_mask, self.pub_key, self.priv_key)
51
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
59
60
61 class VpnHandler(Restorable, ConfigWriter,
62                    TransactionalHandler, DictSubHandler):
63
64     handler_help = u"Manage vpn service"
65
66     _cont_subhandler_attr = 'vpns'
67     _cont_subhandler_class = Vpn
68
69     _persistent_attrs = ('vpns','hosts')
70
71     _restorable_defaults = dict(
72             vpns = dict(),
73             hosts = dict(),
74     )
75
76     _config_writer_files = ('tinc.conf','tinc-up','host')
77     _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
78
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()
84         self._restore()
85         self.host = HostHandler(self)
86
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
94
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;
99
100
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))
105
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()
111                 try:
112                     os.kill(int(pid.strip()), SIGTERM)
113                 except OSError:
114                     pass # XXX report error?
115
116     def _write_config(self):
117         for v in self.vpns.values():
118             #chek whether it's been created or not.
119             if not v.dele:
120                 if v.pub_key is None :
121                     try:
122                         print 'douugh'
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')
131                         priv = f.read()
132                         f.close()
133                         f = file(path.join(self._config_writer_cfg_dir, v.vpn_src ,'rsa_key.pub'), 'r')
134                         pub = f.read()
135                         f.close()
136                         v.pub_key = pub
137                         v.priv_key = priv
138                     except ExecutionError, e:
139                         print e
140
141                 vars = dict(
142                     vpn = v,
143                 )
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():
147                     if not h.dele:
148                         vars = dict(
149                             host = h,
150                         )
151                         self._write_single_config('host',path.join(v.vpn_src,'hosts',h.name),vars)
152                     else:
153                         try:
154                             call(('rm','-f', path.join(v.vpn_src,'hosts',h.name)))
155                             del v.hosts[h.name]
156                         except ExecutionError, e:
157                             print e
158             else:
159                 #delete the vpn root at tinc dir
160                 if path.exists('/etc/tinc/' + v.vpn_src):
161                     self.stop(v.vpn_src)
162                     call(('rm','-rf','/etc/tinc/' + v.vpn_src))
163                     del self.vpns[v.vpn_src]
164
165
166 if __name__ == '__main__':
167     v = VpnHandler()
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')
170     v.delete('test')
171     v.commit()