2 #from binascii import hexlify |
2 #from binascii import hexlify |
3 from runtime.spawn_subprocess import call |
3 from runtime.spawn_subprocess import call |
4 |
4 |
5 restart_stunnel_cmdline = ["/etc/init.d/S50stunnel","restart"] |
5 restart_stunnel_cmdline = ["/etc/init.d/S50stunnel","restart"] |
6 |
6 |
7 # stunnel takes no encoding for psk, so we try to lose minimum entropy |
7 # stunnel takes no encoding for PSK, so we try to lose minimum entropy |
8 # by using all possible chars except '\0\n\r' (checked stunnel parser to be sure) |
8 # by using all possible chars except '\0\n\r' (checked stunnel parser to be sure) |
9 translator = ''.join([(lambda c: '#' if c in '\0\n\r' else c)(chr(i)) for i in xrange(256)]) |
9 translator = ''.join([(lambda c: '#' if c in '\0\n\r' else c)(chr(i)) for i in xrange(256)]) |
10 |
10 |
11 def pskgen(ID, pskpath): |
11 _PSKpath = None |
|
12 |
|
13 def PSKgen(ID, PSKpath): |
12 secret = os.urandom(256) # 2048 bits is still safe nowadays |
14 secret = os.urandom(256) # 2048 bits is still safe nowadays |
13 |
15 |
14 # following makes 512 length string, rejected by stunnel |
16 # following makes 512 length string, rejected by stunnel |
15 # using binascii hexlify loses 50% entropy |
17 # using binascii hexlify loses 50% entropy |
16 # secretstring = hexlify(secret) |
18 # secretstring = hexlify(secret) |
17 |
19 |
18 secretstring = secret.translate(translator) |
20 secretstring = secret.translate(translator) |
19 pskstring = ID+":"+secretstring |
21 PSKstring = ID+":"+secretstring |
20 with open(pskpath, 'w') as f: |
22 with open(PSKpath, 'w') as f: |
21 f.write(pskstring) |
23 f.write(PSKstring) |
22 call(restart_stunnel_cmdline) |
24 call(restart_stunnel_cmdline) |
23 |
25 |
24 def ensurepsk(ID, pskpath): |
26 def ensurePSK(ID, PSKpath): |
|
27 global _PSKpath |
|
28 _PSKpath = PSKpath |
25 # check if already there |
29 # check if already there |
26 if not os.path.exists(pskpath): |
30 if not os.path.exists(PSKpath): |
27 # create if needed |
31 # create if needed |
28 pskgen(ID, pskpath) |
32 PSKgen(ID, PSKpath) |
29 |
33 |
|
34 def getPSKID(): |
|
35 if _PSKpath is not None : |
|
36 if not os.path.exists(_PSKpath): |
|
37 confnodesroot.logger.write_error( |
|
38 'Error: Pre-Shared-Key Secret in %s is missing!\n' % _PSKpath) |
|
39 return None |
|
40 ID,_sep,PSK = open(_PSKpath).read().partition(':') |
|
41 PSK = PSK.rstrip('\n\r') |
|
42 return (ID,PSK) |
|
43 return None |
|
44 |