Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
R
re6stnet
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boris Kocherov
re6stnet
Commits
7977404a
Commit
7977404a
authored
Feb 05, 2015
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactoring: move crypto code to a new file
parent
5be3cc90
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
163 additions
and
130 deletions
+163
-130
draft/re6st-cn
draft/re6st-cn
+2
-2
re6st-conf
re6st-conf
+4
-4
re6st/db.py
re6st/db.py
+6
-8
re6st/registry.py
re6st/registry.py
+16
-21
re6st/tunnel.py
re6st/tunnel.py
+7
-7
re6st/utils.py
re6st/utils.py
+1
-33
re6st/x509.py
re6st/x509.py
+117
-0
re6stnet
re6stnet
+10
-55
No files found.
draft/re6st-cn
View file @
7977404a
#!/usr/bin/python
#!/usr/bin/python
import
sqlite3
,
sys
import
sqlite3
,
sys
import
os
;
sys
.
path
[
0
]
=
os
.
path
.
dirname
(
sys
.
path
[
0
])
import
os
;
sys
.
path
[
0
]
=
os
.
path
.
dirname
(
sys
.
path
[
0
])
from
re6st
import
utils
from
re6st
import
utils
,
x509
from
OpenSSL
import
crypto
from
OpenSSL
import
crypto
with
open
(
"/etc/re6stnet/ca.crt"
)
as
f
:
with
open
(
"/etc/re6stnet/ca.crt"
)
as
f
:
ca
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
ca
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
network
=
utils
.
networkFromCa
(
ca
)
network
=
x509
.
networkFromCa
(
ca
)
db
=
sqlite3
.
connect
(
"/var/lib/re6stnet/registry.db"
)
db
=
sqlite3
.
connect
(
"/var/lib/re6stnet/registry.db"
)
for
x
in
sys
.
argv
[
1
:]:
for
x
in
sys
.
argv
[
1
:]:
...
...
re6st-conf
View file @
7977404a
#!/usr/bin/python
#!/usr/bin/python
import
argparse
,
atexit
,
errno
,
os
,
subprocess
,
sqlite3
,
sys
,
time
import
argparse
,
atexit
,
errno
,
os
,
subprocess
,
sqlite3
,
sys
,
time
from
OpenSSL
import
crypto
from
OpenSSL
import
crypto
from
re6st
import
registry
,
utils
from
re6st
import
registry
,
utils
,
x509
def
create
(
path
,
text
=
None
,
mode
=
0666
):
def
create
(
path
,
text
=
None
,
mode
=
0666
):
fd
=
os
.
open
(
path
,
os
.
O_CREAT
|
os
.
O_WRONLY
|
os
.
O_TRUNC
,
mode
)
fd
=
os
.
open
(
path
,
os
.
O_CREAT
|
os
.
O_WRONLY
|
os
.
O_TRUNC
,
mode
)
...
@@ -54,7 +54,7 @@ def main():
...
@@ -54,7 +54,7 @@ def main():
# Get CA
# Get CA
ca
=
s
.
getCa
()
ca
=
s
.
getCa
()
network
=
utils
.
networkFromCa
(
loadCert
(
ca
))
network
=
x509
.
networkFromCa
(
loadCert
(
ca
))
if
config
.
is_needed
:
if
config
.
is_needed
:
route
,
err
=
subprocess
.
Popen
((
'ip'
,
'-6'
,
'-o'
,
'route'
,
'get'
,
route
,
err
=
subprocess
.
Popen
((
'ip'
,
'-6'
,
'-o'
,
'route'
,
'get'
,
utils
.
ipFromBin
(
network
)),
utils
.
ipFromBin
(
network
)),
...
@@ -143,7 +143,7 @@ def main():
...
@@ -143,7 +143,7 @@ def main():
os
.
close
(
cert_fd
)
os
.
close
(
cert_fd
)
cert
=
loadCert
(
cert
)
cert
=
loadCert
(
cert
)
not_after
=
utils
.
notAfter
(
cert
)
not_after
=
x509
.
notAfter
(
cert
)
print
(
"Setup complete. Certificate is valid until %s UTC"
print
(
"Setup complete. Certificate is valid until %s UTC"
" and will be automatically renewed after %s UTC.
\
n
"
" and will be automatically renewed after %s UTC.
\
n
"
"Do not forget to backup to your private key (%s) or"
"Do not forget to backup to your private key (%s) or"
...
@@ -169,7 +169,7 @@ dh %s
...
@@ -169,7 +169,7 @@ dh %s
"""
%
(
config
.
registry
,
ca_path
,
cert_path
,
key_path
,
dh_path
))
"""
%
(
config
.
registry
,
ca_path
,
cert_path
,
key_path
,
dh_path
))
print
"Sample configuration file created."
print
"Sample configuration file created."
cn
=
utils
.
subnetFromCert
(
cert
)
cn
=
x509
.
subnetFromCert
(
cert
)
subnet
=
network
+
utils
.
binFromSubnet
(
cn
)
subnet
=
network
+
utils
.
binFromSubnet
(
cn
)
print
"Your subnet: %s/%u (CN=%s)"
\
print
"Your subnet: %s/%u (CN=%s)"
\
%
(
utils
.
ipFromBin
(
subnet
),
len
(
subnet
),
cn
)
%
(
utils
.
ipFromBin
(
subnet
),
len
(
subnet
),
cn
)
...
...
re6st/db.py
View file @
7977404a
import
logging
,
sqlite3
,
socket
,
subprocess
,
time
import
logging
,
sqlite3
,
socket
,
subprocess
,
time
from
.
import
utils
from
re6st.registry
import
RegistryClient
class
PeerDB
(
object
):
class
PeerDB
(
object
):
# internal ip = temp arg/attribute
# internal ip = temp arg/attribute
def
__init__
(
self
,
db_path
,
registry
,
key_path
,
network
,
prefix
,
def
__init__
(
self
,
db_path
,
registry
,
cert
,
db_size
=
200
):
db_size
=
200
):
self
.
_prefix
=
cert
.
prefix
self
.
_prefix
=
prefix
self
.
_db_size
=
db_size
self
.
_db_size
=
db_size
self
.
_
key_path
=
key_path
self
.
_
decrypt
=
cert
.
decrypt
self
.
_registry
=
registry
self
.
_registry
=
RegistryClient
(
registry
,
cert
)
logging
.
info
(
'Initialize cache ...'
)
logging
.
info
(
'Initialize cache ...'
)
self
.
_db
=
sqlite3
.
connect
(
db_path
,
isolation_level
=
None
)
self
.
_db
=
sqlite3
.
connect
(
db_path
,
isolation_level
=
None
)
...
@@ -100,7 +98,7 @@ class PeerDB(object):
...
@@ -100,7 +98,7 @@ class PeerDB(object):
logging
.
info
(
'Getting Boot peer...'
)
logging
.
info
(
'Getting Boot peer...'
)
try
:
try
:
bootpeer
=
self
.
_registry
.
getBootstrapPeer
(
self
.
_prefix
)
bootpeer
=
self
.
_registry
.
getBootstrapPeer
(
self
.
_prefix
)
prefix
,
address
=
utils
.
decrypt
(
self
.
_key_path
,
bootpeer
).
split
()
prefix
,
address
=
self
.
_decrypt
(
bootpeer
).
split
()
except
(
socket
.
error
,
subprocess
.
CalledProcessError
,
ValueError
),
e
:
except
(
socket
.
error
,
subprocess
.
CalledProcessError
,
ValueError
),
e
:
logging
.
warning
(
'Failed to bootstrap (%s)'
,
logging
.
warning
(
'Failed to bootstrap (%s)'
,
e
if
bootpeer
else
'no peer returned'
)
e
if
bootpeer
else
'no peer returned'
)
...
...
re6st/registry.py
View file @
7977404a
...
@@ -27,7 +27,7 @@ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
...
@@ -27,7 +27,7 @@ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from
email.mime.text
import
MIMEText
from
email.mime.text
import
MIMEText
from
OpenSSL
import
crypto
from
OpenSSL
import
crypto
from
urllib
import
splittype
,
splithost
,
splitport
,
urlencode
from
urllib
import
splittype
,
splithost
,
splitport
,
urlencode
from
.
import
ctl
,
tunnel
,
utils
,
version
from
.
import
ctl
,
tunnel
,
utils
,
version
,
x509
HMAC_HEADER
=
"Re6stHMAC"
HMAC_HEADER
=
"Re6stHMAC"
RENEW_PERIOD
=
30
*
86400
RENEW_PERIOD
=
30
*
86400
...
@@ -79,16 +79,12 @@ class RegistryServer(object):
...
@@ -79,16 +79,12 @@ class RegistryServer(object):
else
:
else
:
self
.
db
.
execute
(
"INSERT INTO cert VALUES ('',null,null)"
)
self
.
db
.
execute
(
"INSERT INTO cert VALUES ('',null,null)"
)
# Loading certificates
self
.
cert
=
x509
.
Cert
(
self
.
config
.
ca
,
self
.
config
.
key
)
with
open
(
self
.
config
.
ca
)
as
f
:
self
.
ca
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
with
open
(
self
.
config
.
key
)
as
f
:
self
.
key
=
crypto
.
load_privatekey
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
# Get vpn network prefix
# Get vpn network prefix
self
.
network
=
utils
.
networkFromCa
(
self
.
ca
)
self
.
network
=
self
.
cert
.
network
logging
.
info
(
"Network: %s/%u"
,
utils
.
ipFromBin
(
self
.
network
),
logging
.
info
(
"Network: %s/%u"
,
utils
.
ipFromBin
(
self
.
network
),
len
(
self
.
network
))
len
(
self
.
network
))
self
.
email
=
self
.
ca
.
get_subject
().
emailAddress
self
.
email
=
self
.
c
ert
.
c
a
.
get_subject
().
emailAddress
self
.
peers_lock
=
threading
.
Lock
()
self
.
peers_lock
=
threading
.
Lock
()
self
.
ctl
=
ctl
.
Babel
(
config
.
control_socket
,
self
.
ctl
=
ctl
.
Babel
(
config
.
control_socket
,
...
@@ -141,7 +137,7 @@ class RegistryServer(object):
...
@@ -141,7 +137,7 @@ class RegistryServer(object):
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
except
crypto
.
Error
:
except
crypto
.
Error
:
continue
continue
x
=
utils
.
notAfter
(
cert
)
x
=
x509
.
notAfter
(
cert
)
if
x
<=
old
:
if
x
<=
old
:
if
prefix
==
self
.
prefix
:
if
prefix
==
self
.
prefix
:
logging
.
critical
(
"Refuse to delete certificate"
logging
.
critical
(
"Refuse to delete certificate"
...
@@ -205,8 +201,8 @@ class RegistryServer(object):
...
@@ -205,8 +201,8 @@ class RegistryServer(object):
key
=
hashlib
.
sha1
(
struct
.
pack
(
'Q'
,
key
=
hashlib
.
sha1
(
struct
.
pack
(
'Q'
,
random
.
getrandbits
(
64
))).
digest
()
random
.
getrandbits
(
64
))).
digest
()
self
.
sessions
.
setdefault
(
client_prefix
,
[])[
1
:]
=
key
,
self
.
sessions
.
setdefault
(
client_prefix
,
[])[
1
:]
=
key
,
key
=
utils
.
encrypt
(
cert
,
key
)
key
=
x509
.
encrypt
(
cert
,
key
)
sign
=
crypto
.
sign
(
self
.
key
,
key
,
'sha1'
)
sign
=
self
.
cert
.
sign
(
key
)
assert
len
(
key
)
==
len
(
sign
)
assert
len
(
key
)
==
len
(
sign
)
return
key
+
sign
return
key
+
sign
...
@@ -303,11 +299,11 @@ class RegistryServer(object):
...
@@ -303,11 +299,11 @@ class RegistryServer(object):
cert
.
set_serial_number
(
0
)
# required for libssl < 1.0
cert
.
set_serial_number
(
0
)
# required for libssl < 1.0
cert
.
gmtime_adj_notBefore
(
0
)
cert
.
gmtime_adj_notBefore
(
0
)
cert
.
gmtime_adj_notAfter
(
self
.
cert_duration
)
cert
.
gmtime_adj_notAfter
(
self
.
cert_duration
)
cert
.
set_issuer
(
self
.
ca
.
get_subject
())
cert
.
set_issuer
(
self
.
c
ert
.
c
a
.
get_subject
())
subject
.
CN
=
"%u/%u"
%
(
int
(
client_prefix
,
2
),
len
(
client_prefix
))
subject
.
CN
=
"%u/%u"
%
(
int
(
client_prefix
,
2
),
len
(
client_prefix
))
cert
.
set_subject
(
subject
)
cert
.
set_subject
(
subject
)
cert
.
set_pubkey
(
pubkey
)
cert
.
set_pubkey
(
pubkey
)
cert
.
sign
(
self
.
key
,
'sha1'
)
cert
.
sign
(
self
.
cert
.
key
,
'sha1'
)
cert
=
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
cert
=
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
self
.
db
.
execute
(
"UPDATE cert SET cert = ? WHERE prefix = ?"
,
self
.
db
.
execute
(
"UPDATE cert SET cert = ? WHERE prefix = ?"
,
(
cert
,
client_prefix
))
(
cert
,
client_prefix
))
...
@@ -320,14 +316,14 @@ class RegistryServer(object):
...
@@ -320,14 +316,14 @@ class RegistryServer(object):
with
self
.
db
:
with
self
.
db
:
pem
=
self
.
getCert
(
cn
)
pem
=
self
.
getCert
(
cn
)
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
pem
)
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
pem
)
if
utils
.
notAfter
(
cert
)
-
RENEW_PERIOD
<
time
.
time
():
if
x509
.
notAfter
(
cert
)
-
RENEW_PERIOD
<
time
.
time
():
pem
=
self
.
createCertificate
(
cn
,
cert
.
get_subject
(),
pem
=
self
.
createCertificate
(
cn
,
cert
.
get_subject
(),
cert
.
get_pubkey
())
cert
.
get_pubkey
())
return
pem
return
pem
@
rpc
@
rpc
def
getCa
(
self
):
def
getCa
(
self
):
return
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
self
.
ca
)
return
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
self
.
c
ert
.
c
a
)
@
rpc
@
rpc
def
getPrefix
(
self
,
cn
):
def
getPrefix
(
self
,
cn
):
...
@@ -374,7 +370,7 @@ class RegistryServer(object):
...
@@ -374,7 +370,7 @@ class RegistryServer(object):
return
return
cert
=
self
.
getCert
(
cn
)
cert
=
self
.
getCert
(
cn
)
logging
.
info
(
"Sending bootstrap peer: %s"
,
msg
)
logging
.
info
(
"Sending bootstrap peer: %s"
,
msg
)
return
utils
.
encrypt
(
cert
,
msg
)
return
x509
.
encrypt
(
cert
,
msg
)
@
rpc
@
rpc
def
versions
(
self
):
def
versions
(
self
):
...
@@ -451,9 +447,8 @@ class RegistryClient(object):
...
@@ -451,9 +447,8 @@ class RegistryClient(object):
_hmac
=
None
_hmac
=
None
user_agent
=
"re6stnet/"
+
version
.
version
user_agent
=
"re6stnet/"
+
version
.
version
def
__init__
(
self
,
url
,
key_path
=
None
,
ca
=
None
,
auto_close
=
True
):
def
__init__
(
self
,
url
,
cert
=
None
,
auto_close
=
True
):
self
.
key_path
=
key_path
self
.
cert
=
cert
self
.
ca
=
ca
self
.
auto_close
=
auto_close
self
.
auto_close
=
auto_close
scheme
,
host
=
splittype
(
url
)
scheme
,
host
=
splittype
(
url
)
host
,
path
=
splithost
(
host
)
host
,
path
=
splithost
(
host
)
...
@@ -483,8 +478,8 @@ class RegistryClient(object):
...
@@ -483,8 +478,8 @@ class RegistryClient(object):
retry
=
False
retry
=
False
h
=
self
.
hello
(
client_prefix
)
h
=
self
.
hello
(
client_prefix
)
n
=
len
(
h
)
//
2
n
=
len
(
h
)
//
2
crypto
.
verify
(
self
.
ca
,
h
[
n
:],
h
[:
n
],
'sha1'
)
self
.
cert
.
verify
(
h
[
n
:],
h
[:
n
]
)
key
=
utils
.
decrypt
(
self
.
key_path
,
h
[:
n
])
key
=
self
.
cert
.
decrypt
(
h
[:
n
])
h
=
hmac
.
HMAC
(
key
,
query
,
hashlib
.
sha1
).
digest
()
h
=
hmac
.
HMAC
(
key
,
query
,
hashlib
.
sha1
).
digest
()
key
=
hashlib
.
sha1
(
key
).
digest
()
key
=
hashlib
.
sha1
(
key
).
digest
()
self
.
_hmac
=
hashlib
.
sha1
(
key
).
digest
()
self
.
_hmac
=
hashlib
.
sha1
(
key
).
digest
()
...
...
re6st/tunnel.py
View file @
7977404a
...
@@ -160,11 +160,12 @@ class TunnelKiller(object):
...
@@ -160,11 +160,12 @@ class TunnelKiller(object):
class
TunnelManager
(
object
):
class
TunnelManager
(
object
):
def
__init__
(
self
,
control_socket
,
peer_db
,
openvpn_args
,
timeout
,
def
__init__
(
self
,
control_socket
,
peer_db
,
cert
,
openvpn_args
,
timeout
,
refresh
,
client_count
,
iface_list
,
network
,
prefix
,
refresh
,
client_count
,
iface_list
,
address
,
ip_changed
,
address
,
ip_changed
,
encrypt
,
remote_gateway
,
disable_proto
,
encrypt
,
remote_gateway
,
disable_proto
,
neighbour_list
=
()):
neighbour_list
=
()):
self
.
cert
=
cert
self
.
ctl
=
ctl
.
Babel
(
control_socket
,
weakref
.
proxy
(
self
),
network
)
self
.
_network
=
cert
.
network
self
.
ctl
=
ctl
.
Babel
(
control_socket
,
weakref
.
proxy
(
self
),
self
.
_network
)
self
.
encrypt
=
encrypt
self
.
encrypt
=
encrypt
self
.
ovpn_args
=
openvpn_args
self
.
ovpn_args
=
openvpn_args
self
.
peer_db
=
peer_db
self
.
peer_db
=
peer_db
...
@@ -178,9 +179,8 @@ class TunnelManager(object):
...
@@ -178,9 +179,8 @@ class TunnelManager(object):
self
.
_distant_peers
=
[]
self
.
_distant_peers
=
[]
self
.
_iface_to_prefix
=
{}
self
.
_iface_to_prefix
=
{}
self
.
_refresh_time
=
refresh
self
.
_refresh_time
=
refresh
self
.
_network
=
network
self
.
_iface_list
=
iface_list
self
.
_iface_list
=
iface_list
self
.
_prefix
=
prefix
self
.
_prefix
=
cert
.
prefix
address_dict
=
defaultdict
(
list
)
address_dict
=
defaultdict
(
list
)
for
family
,
address
in
address
:
for
family
,
address
in
address
:
address_dict
[
family
]
+=
address
address_dict
[
family
]
+=
address
...
...
re6st/utils.py
View file @
7977404a
import
argparse
,
calendar
,
errno
,
logging
,
os
,
select
as
_select
,
shlex
,
signal
import
argparse
,
errno
,
logging
,
os
,
select
as
_select
,
shlex
,
signal
import
socket
,
struct
,
subprocess
,
sys
,
textwrap
,
threading
,
time
,
traceback
import
socket
,
struct
,
subprocess
,
sys
,
textwrap
,
threading
,
time
,
traceback
try
:
try
:
subprocess
.
CalledProcessError
(
0
,
''
,
''
)
subprocess
.
CalledProcessError
(
0
,
''
,
''
)
...
@@ -207,15 +207,6 @@ def ipFromBin(ip, suffix=''):
...
@@ -207,15 +207,6 @@ def ipFromBin(ip, suffix=''):
return
socket
.
inet_ntop
(
socket
.
AF_INET6
,
return
socket
.
inet_ntop
(
socket
.
AF_INET6
,
struct
.
pack
(
'>QQ'
,
int
(
ip
[:
64
],
2
),
int
(
ip
[
64
:],
2
)))
struct
.
pack
(
'>QQ'
,
int
(
ip
[:
64
],
2
),
int
(
ip
[
64
:],
2
)))
def
networkFromCa
(
ca
):
return
bin
(
ca
.
get_serial_number
())[
3
:]
def
subnetFromCert
(
cert
):
return
cert
.
get_subject
().
CN
def
notAfter
(
cert
):
return
calendar
.
timegm
(
time
.
strptime
(
cert
.
get_notAfter
(),
'%Y%m%d%H%M%SZ'
))
def
dump_address
(
address
):
def
dump_address
(
address
):
return
';'
.
join
(
map
(
','
.
join
,
address
))
return
';'
.
join
(
map
(
','
.
join
,
address
))
...
@@ -232,26 +223,3 @@ def parse_address(address_list):
...
@@ -232,26 +223,3 @@ def parse_address(address_list):
def
binFromSubnet
(
subnet
):
def
binFromSubnet
(
subnet
):
p
,
l
=
subnet
.
split
(
'/'
)
p
,
l
=
subnet
.
split
(
'/'
)
return
bin
(
int
(
p
))[
2
:].
rjust
(
int
(
l
),
'0'
)
return
bin
(
int
(
p
))[
2
:].
rjust
(
int
(
l
),
'0'
)
def
decrypt
(
key_path
,
data
):
p
=
Popen
((
'openssl'
,
'rsautl'
,
'-decrypt'
,
'-inkey'
,
key_path
),
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
)
out
,
err
=
p
.
communicate
(
data
)
if
p
.
returncode
:
raise
subprocess
.
CalledProcessError
(
p
.
returncode
,
'openssl'
,
err
)
return
out
def
encrypt
(
cert
,
data
):
r
,
w
=
os
.
pipe
()
try
:
threading
.
Thread
(
target
=
os
.
write
,
args
=
(
w
,
cert
)).
start
()
p
=
Popen
((
'openssl'
,
'rsautl'
,
'-encrypt'
,
'-certin'
,
'-inkey'
,
'/proc/self/fd/%u'
%
r
),
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
)
out
,
err
=
p
.
communicate
(
data
)
finally
:
os
.
close
(
r
)
os
.
close
(
w
)
if
p
.
returncode
:
raise
subprocess
.
CalledProcessError
(
p
.
returncode
,
'openssl'
,
err
)
return
out
re6st/x509.py
0 → 100644
View file @
7977404a
import
calendar
,
logging
,
os
,
subprocess
,
threading
,
time
from
OpenSSL
import
crypto
from
.
import
utils
def
networkFromCa
(
ca
):
return
bin
(
ca
.
get_serial_number
())[
3
:]
def
subnetFromCert
(
cert
):
return
cert
.
get_subject
().
CN
def
notAfter
(
cert
):
return
calendar
.
timegm
(
time
.
strptime
(
cert
.
get_notAfter
(),
'%Y%m%d%H%M%SZ'
))
def
openssl
(
*
args
):
return
utils
.
Popen
((
'openssl'
,)
+
args
,
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
def
encrypt
(
cert
,
data
):
r
,
w
=
os
.
pipe
()
try
:
threading
.
Thread
(
target
=
os
.
write
,
args
=
(
w
,
cert
)).
start
()
p
=
openssl
(
'rsautl'
,
'-encrypt'
,
'-certin'
,
'-inkey'
,
'/proc/self/fd/%u'
%
r
)
out
,
err
=
p
.
communicate
(
data
)
finally
:
os
.
close
(
r
)
os
.
close
(
w
)
if
p
.
returncode
:
raise
subprocess
.
CalledProcessError
(
p
.
returncode
,
'openssl'
,
err
)
return
out
def
maybe_renew
(
path
,
cert
,
info
,
renew
):
from
.registry
import
RENEW_PERIOD
while
True
:
next_renew
=
notAfter
(
cert
)
-
RENEW_PERIOD
if
time
.
time
()
<
next_renew
:
return
cert
,
next_renew
try
:
pem
=
renew
()
if
not
pem
or
pem
==
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
cert
):
exc_info
=
0
break
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
pem
)
except
Exception
:
exc_info
=
1
break
new_path
=
path
+
'.new'
with
open
(
new_path
,
'w'
)
as
f
:
f
.
write
(
pem
)
try
:
s
=
os
.
stat
(
path
)
os
.
chown
(
new_path
,
s
.
st_uid
,
s
.
st_gid
)
except
OSError
:
pass
os
.
rename
(
new_path
,
path
)
logging
.
info
(
"%s renewed until %s UTC"
,
info
,
time
.
asctime
(
time
.
gmtime
(
notAfter
(
cert
))))
logging
.
error
(
"%s not renewed. Will retry tomorrow."
,
info
,
exc_info
=
exc_info
)
return
cert
,
time
.
time
()
+
86400
class
VerifyError
(
Exception
):
pass
class
Cert
(
object
):
def
__init__
(
self
,
ca
,
key
,
cert
=
None
):
self
.
ca_path
=
ca
self
.
cert_path
=
cert
self
.
key_path
=
key
with
open
(
ca
)
as
f
:
self
.
ca
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
with
open
(
key
)
as
f
:
self
.
key
=
crypto
.
load_privatekey
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
if
cert
:
with
open
(
cert
)
as
f
:
cert
=
f
.
read
()
self
.
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
@
property
def
prefix
(
self
):
return
utils
.
binFromSubnet
(
subnetFromCert
(
self
.
cert
))
@
property
def
network
(
self
):
return
networkFromCa
(
self
.
ca
)
@
property
def
openvpn_args
(
self
):
return
(
'--ca'
,
self
.
ca_path
,
'--cert'
,
self
.
cert_path
,
'--key'
,
self
.
key_path
)
def
maybeRenew
(
self
,
registry
):
from
.registry
import
RegistryClient
registry
=
RegistryClient
(
registry
,
self
)
self
.
cert
,
next_renew
=
maybe_renew
(
self
.
cert_path
,
self
.
cert
,
"Certificate"
,
lambda
:
registry
.
renewCertificate
(
self
.
prefix
))
self
.
ca
,
ca_renew
=
maybe_renew
(
self
.
ca_path
,
self
.
ca
,
"CA Certificate"
,
registry
.
getCa
)
return
min
(
next_renew
,
ca_renew
)
def
verify
(
self
,
sign
,
data
):
crypto
.
verify
(
self
.
ca
,
sign
,
data
,
'sha1'
)
def
sign
(
self
,
data
):
return
crypto
.
sign
(
self
.
key
,
data
,
'sha1'
)
def
decrypt
(
self
,
data
):
p
=
openssl
(
'rsautl'
,
'-decrypt'
,
'-inkey'
,
self
.
key_path
)
out
,
err
=
p
.
communicate
(
data
)
if
p
.
returncode
:
raise
subprocess
.
CalledProcessError
(
p
.
returncode
,
'openssl'
,
err
)
return
out
re6stnet
View file @
7977404a
...
@@ -2,9 +2,7 @@
...
@@ -2,9 +2,7 @@
import
atexit
,
errno
,
logging
,
os
,
signal
,
socket
import
atexit
,
errno
,
logging
,
os
,
signal
,
socket
import
sqlite3
,
subprocess
,
sys
,
time
,
threading
import
sqlite3
,
subprocess
,
sys
,
time
,
threading
from
collections
import
deque
from
collections
import
deque
from
OpenSSL
import
crypto
from
re6st
import
ctl
,
db
,
plib
,
tunnel
,
utils
,
version
,
x509
from
re6st
import
ctl
,
db
,
plib
,
tunnel
,
utils
,
version
from
re6st.registry
import
RegistryClient
,
RENEW_PERIOD
from
re6st.utils
import
exit
from
re6st.utils
import
exit
class
ReexecException
(
Exception
):
class
ReexecException
(
Exception
):
...
@@ -22,7 +20,7 @@ def getConfig():
...
@@ -22,7 +20,7 @@ def getConfig():
"- any: ask peers our IP
\
n
"
"- any: ask peers our IP
\
n
"
" (default: like 'upnp' if miniupnpc is installed,
\
n
"
" (default: like 'upnp' if miniupnpc is installed,
\
n
"
" otherwise like 'any')"
)
" otherwise like 'any')"
)
_
(
'--registry'
,
metavar
=
'URL'
,
_
(
'--registry'
,
metavar
=
'URL'
,
required
=
True
,
help
=
"Public HTTP URL of the registry, for bootstrapping."
)
help
=
"Public HTTP URL of the registry, for bootstrapping."
)
_
(
'-l'
,
'--log'
,
default
=
'/var/log/re6stnet'
,
_
(
'-l'
,
'--log'
,
default
=
'/var/log/re6stnet'
,
help
=
"Path to the directory used for log files:
\
n
"
help
=
"Path to the directory used for log files:
\
n
"
...
@@ -126,48 +124,11 @@ def getConfig():
...
@@ -126,48 +124,11 @@ def getConfig():
return
parser
.
parse_args
()
return
parser
.
parse_args
()
def
maybe_renew
(
path
,
cert
,
info
,
renew
):
while
True
:
next_renew
=
utils
.
notAfter
(
cert
)
-
RENEW_PERIOD
if
time
.
time
()
<
next_renew
:
return
cert
,
next_renew
try
:
pem
=
renew
()
if
not
pem
or
pem
==
crypto
.
dump_certificate
(
crypto
.
FILETYPE_PEM
,
cert
):
exc_info
=
0
break
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
pem
)
except
Exception
:
exc_info
=
1
break
new_path
=
path
+
'.new'
with
open
(
new_path
,
'w'
)
as
f
:
f
.
write
(
pem
)
try
:
s
=
os
.
stat
(
path
)
os
.
chown
(
new_path
,
s
.
st_uid
,
s
.
st_gid
)
except
OSError
:
pass
os
.
rename
(
new_path
,
path
)
logging
.
info
(
"%s renewed until %s UTC"
,
info
,
time
.
asctime
(
time
.
gmtime
(
utils
.
notAfter
(
cert
))))
logging
.
error
(
"%s not renewed. Will retry tomorrow."
,
info
,
exc_info
=
exc_info
)
return
cert
,
time
.
time
()
+
86400
def
main
():
def
main
():
# Get arguments
# Get arguments
config
=
getConfig
()
config
=
getConfig
()
with
open
(
config
.
ca
)
as
f
:
cert
=
x509
.
Cert
(
config
.
ca
,
config
.
key
,
config
.
cert
)
ca
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
config
.
openvpn_args
+=
cert
.
openvpn_args
with
open
(
config
.
cert
)
as
f
:
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
f
.
read
())
prefix
=
utils
.
binFromSubnet
(
utils
.
subnetFromCert
(
cert
))
config
.
openvpn_args
+=
(
'--ca'
,
config
.
ca
,
'--cert'
,
config
.
cert
,
'--key'
,
config
.
key
)
# TODO: verify certificates (should we moved to M2Crypto ?)
# TODO: verify certificates (should we moved to M2Crypto ?)
if
config
.
test
:
if
config
.
test
:
...
@@ -186,13 +147,8 @@ def main():
...
@@ -186,13 +147,8 @@ def main():
exit
.
signal
(
0
,
signal
.
SIGINT
,
signal
.
SIGTERM
)
exit
.
signal
(
0
,
signal
.
SIGINT
,
signal
.
SIGTERM
)
exit
.
signal
(
-
1
,
signal
.
SIGHUP
,
signal
.
SIGUSR2
)
exit
.
signal
(
-
1
,
signal
.
SIGHUP
,
signal
.
SIGUSR2
)
registry
=
RegistryClient
(
config
.
registry
,
config
.
key
,
ca
)
next_renew
=
cert
.
maybeRenew
(
config
.
registry
)
cert
,
next_renew
=
maybe_renew
(
config
.
cert
,
cert
,
"Certificate"
,
network
=
cert
.
network
lambda
:
registry
.
renewCertificate
(
prefix
))
ca
,
ca_renew
=
maybe_renew
(
config
.
ca
,
ca
,
"CA Certificate"
,
registry
.
getCa
)
if
next_renew
>
ca_renew
:
next_renew
=
ca_renew
network
=
utils
.
networkFromCa
(
ca
)
if
config
.
max_clients
is
None
:
if
config
.
max_clients
is
None
:
config
.
max_clients
=
config
.
client_count
*
2
config
.
max_clients
=
config
.
client_count
*
2
...
@@ -288,7 +244,7 @@ def main():
...
@@ -288,7 +244,7 @@ def main():
cleanup
.
append
(
lambda
:
subprocess
.
call
(
args
))
cleanup
.
append
(
lambda
:
subprocess
.
call
(
args
))
try
:
try
:
subnet
=
network
+
prefix
subnet
=
network
+
cert
.
prefix
my_ip
=
utils
.
ipFromBin
(
subnet
,
'1'
)
my_ip
=
utils
.
ipFromBin
(
subnet
,
'1'
)
my_subnet
=
'%s/%u'
%
(
utils
.
ipFromBin
(
subnet
),
len
(
subnet
))
my_subnet
=
'%s/%u'
%
(
utils
.
ipFromBin
(
subnet
),
len
(
subnet
))
my_network
=
"%s/%u"
%
(
utils
.
ipFromBin
(
network
),
len
(
network
))
my_network
=
"%s/%u"
%
(
utils
.
ipFromBin
(
network
),
len
(
network
))
...
@@ -303,12 +259,11 @@ def main():
...
@@ -303,12 +259,11 @@ def main():
timeout
=
4
*
config
.
hello
timeout
=
4
*
config
.
hello
cleanup
=
[]
cleanup
=
[]
if
config
.
client_count
and
not
config
.
client
:
if
config
.
client_count
and
not
config
.
client
:
required
(
'registry'
)
peer_db
=
db
.
PeerDB
(
db_path
,
config
.
registry
,
cert
)
peer_db
=
db
.
PeerDB
(
db_path
,
registry
,
config
.
key
,
network
,
prefix
)
cleanup
.
append
(
lambda
:
peer_db
.
cacheMinimize
(
config
.
client_count
))
cleanup
.
append
(
lambda
:
peer_db
.
cacheMinimize
(
config
.
client_count
))
tunnel_manager
=
tunnel
.
TunnelManager
(
config
.
control_socket
,
tunnel_manager
=
tunnel
.
TunnelManager
(
config
.
control_socket
,
peer_db
,
c
onfig
.
openvpn_args
,
timeout
,
config
.
tunnel_refresh
,
peer_db
,
c
ert
,
config
.
openvpn_args
,
timeout
,
config
.
client_count
,
config
.
iface_list
,
network
,
prefix
,
config
.
tunnel_refresh
,
config
.
client_count
,
config
.
iface_list
,
address
,
ip_changed
,
config
.
encrypt
,
remote_gateway
,
address
,
ip_changed
,
config
.
encrypt
,
remote_gateway
,
config
.
disable_proto
,
config
.
neighbour
)
config
.
disable_proto
,
config
.
neighbour
)
cleanup
.
append
(
tunnel_manager
.
sock
.
close
)
cleanup
.
append
(
tunnel_manager
.
sock
.
close
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment