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
2
Issues
2
List
Boards
Labels
Milestones
Merge Requests
4
Merge Requests
4
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
nexedi
re6stnet
Commits
8ebdd500
Commit
8ebdd500
authored
Mar 06, 2015
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Certificate revocation, with broadcast of CRL
parent
f73c51ec
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
181 additions
and
90 deletions
+181
-90
TODO
TODO
+5
-0
re6st/cache.py
re6st/cache.py
+9
-1
re6st/ovpn-client
re6st/ovpn-client
+4
-4
re6st/ovpn-server
re6st/ovpn-server
+9
-8
re6st/plib.py
re6st/plib.py
+3
-4
re6st/registry.py
re6st/registry.py
+47
-6
re6st/tunnel.py
re6st/tunnel.py
+85
-53
re6st/x509.py
re6st/x509.py
+8
-6
re6stnet
re6stnet
+11
-8
No files found.
TODO
View file @
8ebdd500
...
...
@@ -20,3 +20,8 @@
- registry: add '--home PATH' command line option so that / display an HTML
page from PATH (use new str.format for templating)
- Better UI to revoke certificates, for example with a HTML form.
Currently, one have to forge the URL manually. Examples:
wget -O /dev/null http://re6st.example.com/revoke?cn_or_serial=123
wget -O /dev/null http://re6st.example.com/revoke?cn_or_serial=4/16
re6st/cache.py
View file @
8ebdd500
...
...
@@ -4,6 +4,8 @@ from . import utils, version, x509
class
Cache
(
object
):
crl
=
()
def
__init__
(
self
,
db_path
,
registry
,
cert
,
db_size
=
200
):
self
.
_prefix
=
cert
.
prefix
self
.
_db_size
=
db_size
...
...
@@ -40,6 +42,7 @@ class Cache(object):
# when it tried to send us new parameters.
or
self
.
_prefix
==
self
.
registry_prefix
):
self
.
updateConfig
()
self
.
next_renew
=
cert
.
maybeRenew
(
self
.
_registry
,
self
.
crl
)
if
version
.
protocol
<
self
.
min_protocol
:
logging
.
critical
(
"Your version of re6stnet is too old."
" Please update."
)
...
...
@@ -64,7 +67,11 @@ class Cache(object):
cls
=
self
.
__class__
logging
.
debug
(
"Loading network parameters:"
)
for
k
,
v
in
config
:
hasattr
(
cls
,
k
)
or
setattr
(
self
,
k
,
v
)
if
k
==
'crl'
:
v
=
set
(
json
.
loads
(
v
))
elif
hasattr
(
cls
,
k
):
continue
setattr
(
self
,
k
,
v
)
logging
.
debug
(
"- %s: %r"
,
k
,
v
)
def
updateConfig
(
self
):
...
...
@@ -77,6 +84,7 @@ class Cache(object):
config
=
dict
((
str
(
k
),
v
.
decode
(
'base64'
)
if
k
in
base64
else
str
(
v
)
if
type
(
v
)
is
unicode
else
v
)
for
k
,
v
in
config
.
iteritems
())
config
[
'crl'
]
=
json
.
dumps
(
config
[
'crl'
])
except
socket
.
error
,
e
:
logging
.
warning
(
e
)
return
...
...
re6st/ovpn-client
View file @
8ebdd500
...
...
@@ -9,7 +9,7 @@ if script_type == 'up':
os
.
execlp
(
'ip'
,
'ip'
,
'link'
,
'set'
,
os
.
environ
[
'dev'
],
'up'
,
'mtu'
,
os
.
environ
[
'tun_mtu'
])
# Write into pipe external ip address received
import
time
os
.
write
(
int
(
sys
.
argv
[
1
]),
"%s %s %s %s
\
n
"
%
(
script_type
,
os
.
environ
[
'common_name'
],
time
.
time
(),
os
.
environ
[
'OPENVPN_external_ip'
]
))
if
script_type
==
'route-up'
:
import
time
os
.
write
(
int
(
sys
.
argv
[
1
]),
repr
((
os
.
environ
[
'common_name'
],
time
.
time
()
,
int
(
os
.
environ
[
'tls_serial_0'
]),
os
.
environ
[
'OPENVPN_external_ip'
])
))
re6st/ovpn-server
View file @
8ebdd500
...
...
@@ -2,15 +2,16 @@
import
os
,
sys
script_type
=
os
.
environ
[
'script_type'
]
external_ip
=
lambda
:
os
.
getenv
(
'trusted_ip'
)
or
os
.
environ
[
'trusted_ip6'
]
external_ip
=
os
.
getenv
(
'trusted_ip'
)
or
os
.
environ
[
'trusted_ip6'
]
# Write into pipe connect/disconnect events
fd
=
int
(
sys
.
argv
[
1
])
os
.
write
(
fd
,
repr
((
script_type
,
(
os
.
environ
[
'common_name'
],
os
.
environ
[
'dev'
],
int
(
os
.
environ
[
'tls_serial_0'
]),
external_ip
))))
if
script_type
==
'client-connect'
:
if
os
.
read
(
fd
,
1
)
==
'
\
0
'
:
sys
.
exit
(
1
)
# Send client its external ip address
with
open
(
sys
.
argv
[
2
],
'w'
)
as
f
:
f
.
write
(
'push "setenv-safe external_ip %s"
\
n
'
%
external_ip
())
# Write into pipe connect/disconnect events
arg1
=
sys
.
argv
[
1
]
if
arg1
!=
'None'
:
os
.
write
(
int
(
arg1
),
'%s %s %s
\
n
'
%
(
script_type
,
os
.
environ
[
'common_name'
],
external_ip
()))
f
.
write
(
'push "setenv-safe external_ip %s"
\
n
'
%
external_ip
)
re6st/plib.py
View file @
8ebdd500
...
...
@@ -25,10 +25,8 @@ def openvpn(iface, encrypt, *args, **kw):
ovpn_link_mtu_dict
=
{
'udp'
:
1481
,
'udp6'
:
1450
}
def
server
(
iface
,
max_clients
,
dh_path
,
pipe_fd
,
port
,
proto
,
encrypt
,
*
args
,
**
kw
):
client_script
=
'%s %s'
%
(
ovpn_server
,
pipe_fd
)
if
pipe_fd
is
not
None
:
args
=
(
'--client-disconnect'
,
client_script
)
+
args
def
server
(
iface
,
max_clients
,
dh_path
,
fd
,
port
,
proto
,
encrypt
,
*
args
,
**
kw
):
client_script
=
'%s %s'
%
(
ovpn_server
,
fd
)
try
:
args
=
(
'--link-mtu'
,
str
(
ovpn_link_mtu_dict
[
proto
]),
# mtu-disc ignored for udp6 due to a bug in OpenVPN
...
...
@@ -39,6 +37,7 @@ def server(iface, max_clients, dh_path, pipe_fd, port, proto, encrypt, *args, **
'--tls-server'
,
'--mode'
,
'server'
,
'--client-connect'
,
client_script
,
'--client-disconnect'
,
client_script
,
'--dh'
,
dh_path
,
'--max-clients'
,
str
(
max_clients
),
'--port'
,
str
(
port
),
...
...
re6st/registry.py
View file @
8ebdd500
...
...
@@ -25,6 +25,7 @@ from collections import defaultdict, deque
from
datetime
import
datetime
from
BaseHTTPServer
import
HTTPServer
,
BaseHTTPRequestHandler
from
email.mime.text
import
MIMEText
from
operator
import
itemgetter
from
OpenSSL
import
crypto
from
urllib
import
splittype
,
splithost
,
splitport
,
urlencode
from
.
import
ctl
,
tunnel
,
utils
,
version
,
x509
...
...
@@ -71,6 +72,20 @@ class RegistryServer(object):
"email TEXT"
,
"cert TEXT"
):
self
.
db
.
execute
(
"INSERT INTO cert VALUES ('',null,null)"
)
if
utils
.
sqliteCreateTable
(
self
.
db
,
"crl"
,
"serial INTEGER PRIMARY KEY NOT NULL"
,
# Expiration date of revoked certificate.
# TODO: purge rows with dates in the past.
"date INTEGER NOT NULL"
):
# Revoke certificates produced by previous version.
# They all have serial 0.
try
:
date
=
max
(
x509
.
notAfter
(
x
[
0
])
for
x
in
self
.
iterCert
())
except
ValueError
:
pass
else
:
if
time
.
time
()
<
date
:
self
.
db
.
execute
(
"INSERT INTO crl VALUES (0,?)"
,
(
date
,))
self
.
cert
=
x509
.
Cert
(
self
.
config
.
ca
,
self
.
config
.
key
)
# Get vpn network prefix
...
...
@@ -97,9 +112,11 @@ class RegistryServer(object):
self
.
db
.
execute
(
"INSERT OR REPLACE INTO config VALUES (?, ?)"
,
name_value
)
def
updateNetworkConfig
(
self
):
def
updateNetworkConfig
(
self
,
_it0
=
itemgetter
(
0
)
):
kw
=
{
'babel_default'
:
'max-rtt-penalty 5000 rtt-max 500 rtt-decay 125'
,
'crl'
:
map
(
_it0
,
self
.
db
.
execute
(
"SELECT serial FROM crl ORDER BY serial"
)),
'protocol'
:
version
.
protocol
,
'registry_prefix'
:
self
.
prefix
,
}
...
...
@@ -220,7 +237,7 @@ class RegistryServer(object):
def
handle_request
(
self
,
request
,
method
,
kw
,
_localhost
=
(
'127.0.0.1'
,
'::1'
)):
m
=
getattr
(
self
,
method
)
if
method
in
(
'versions'
,
'topology'
):
if
method
in
(
'
revoke'
,
'
versions'
,
'topology'
):
x_forwarded_for
=
request
.
headers
.
get
(
'X-Forwarded-For'
)
if
request
.
client_address
[
0
]
not
in
_localhost
or
\
x_forwarded_for
and
x_forwarded_for
not
in
_localhost
:
...
...
@@ -393,15 +410,16 @@ class RegistryServer(object):
@
rpc
def
renewCertificate
(
self
,
cn
):
with
self
.
lock
:
with
self
.
db
:
with
self
.
db
as
db
:
pem
=
self
.
getCert
(
cn
)
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
pem
)
if
x509
.
notAfter
(
cert
)
-
RENEW_PERIOD
<
time
.
time
():
not_after
=
None
elif
cert
.
get_serial_number
():
return
pem
else
:
elif
db
.
execute
(
"SELECT count(*) FROM crl WHERE serial=?"
,
(
cert
.
get_serial_number
(),)).
fetchone
()[
0
]:
not_after
=
cert
.
get_notAfter
()
else
:
return
pem
return
self
.
createCertificate
(
cn
,
cert
.
get_subject
(),
cert
.
get_pubkey
(),
not_after
)
...
...
@@ -452,6 +470,29 @@ class RegistryServer(object):
logging
.
info
(
"Sending bootstrap peer: %s"
,
msg
)
return
x509
.
encrypt
(
cert
,
msg
)
@
rpc
def
revoke
(
self
,
cn_or_serial
):
with
self
.
lock
:
with
self
.
db
:
q
=
self
.
db
.
execute
try
:
serial
=
int
(
cn_or_serial
)
except
ValueError
:
prefix
=
utils
.
binFromSubnet
(
cn_or_serial
)
cert
=
self
.
getCert
(
prefix
)
q
(
"UPDATE cert SET email=null, cert=null WHERE prefix=?"
,
(
prefix
,))
cert
=
crypto
.
load_certificate
(
crypto
.
FILETYPE_PEM
,
cert
)
serial
=
cert
.
get_serial_number
()
self
.
sessions
.
pop
(
prefix
,
None
)
else
:
cert
,
=
(
cert
for
cert
,
prefix
,
email
in
self
.
iterCert
()
if
cert
.
get_serial_number
()
==
serial
)
not_after
=
x509
.
notAfter
(
cert
)
if
time
.
time
()
<
not_after
:
q
(
"INSERT INTO crl VALUES (?,?)"
,
(
serial
,
not_after
))
self
.
updateNetworkConfig
()
@
rpc
def
versions
(
self
):
with
self
.
peers_lock
:
...
...
re6st/tunnel.py
View file @
8ebdd500
import
errno
,
logging
,
os
,
random
,
socket
,
subprocess
,
time
,
weakref
import
errno
,
logging
,
os
,
random
,
socket
,
subprocess
,
struct
,
time
,
weakref
from
collections
import
defaultdict
,
deque
from
bisect
import
bisect
,
insort
from
OpenSSL
import
crypto
...
...
@@ -40,6 +40,7 @@ class MultiGatewayManager(dict):
class
Connection
(
object
):
_retry
=
0
serial
=
None
time
=
float
(
'inf'
)
def
__init__
(
self
,
tunnel_manager
,
address_list
,
iface
,
prefix
):
...
...
@@ -69,15 +70,19 @@ class Connection(object):
'--connect-retry-max'
,
'3'
,
'--tls-exit'
,
'--remap-usr1'
,
'SIGTERM'
,
'--ping-exit'
,
str
(
tm
.
timeout
),
'--route-up'
,
'%s %u'
%
(
plib
.
ovpn_client
,
tm
.
write_
pipe
),
'--route-up'
,
'%s %u'
%
(
plib
.
ovpn_client
,
tm
.
write_
sock
.
fileno
()
),
*
tm
.
ovpn_args
)
tm
.
resetTunnelRefresh
()
self
.
_retry
+=
1
def
connected
(
self
):
def
connected
(
self
,
serial
):
cache
=
self
.
tunnel_manager
.
cache
if
serial
in
cache
.
crl
:
self
.
tunnel_manager
.
_kill
(
self
.
_prefix
)
return
self
.
serial
=
serial
i
=
self
.
_retry
-
1
self
.
_retry
=
None
cache
=
self
.
tunnel_manager
.
cache
if
i
:
cache
.
addPeer
(
self
.
_prefix
,
','
.
join
(
self
.
address_list
[
i
]),
True
)
else
:
...
...
@@ -167,14 +172,14 @@ class BaseTunnelManager(object):
_forward
=
None
def
__init__
(
self
,
cache
,
cert
,
cert_renew
,
address
=
()):
def
__init__
(
self
,
cache
,
cert
,
address
=
()):
self
.
cert
=
cert
self
.
_network
=
cert
.
network
self
.
_prefix
=
cert
.
prefix
self
.
cache
=
cache
self
.
_connecting
=
set
()
self
.
_connection_dict
=
{}
self
.
_served
=
set
(
)
self
.
_served
=
defaultdict
(
dict
)
self
.
_version
=
cache
.
version
address_dict
=
defaultdict
(
list
)
...
...
@@ -190,9 +195,9 @@ class BaseTunnelManager(object):
self
.
sock
.
bind
((
'::'
,
PORT
))
p
=
x509
.
Peer
(
self
.
_prefix
)
p
.
stop_date
=
c
er
t_renew
p
.
stop_date
=
c
ache
.
nex
t_renew
self
.
_peers
=
[
p
]
self
.
_timeouts
=
[(
cert_renew
,
self
.
invalidatePeers
)]
self
.
_timeouts
=
[(
p
.
stop_date
,
self
.
invalidatePeers
)]
def
select
(
self
,
r
,
w
,
t
):
r
[
self
.
sock
]
=
self
.
handlePeerEvent
...
...
@@ -307,6 +312,9 @@ class BaseTunnelManager(object):
cert
=
self
.
cert
.
loadVerify
(
msg
,
True
,
crypto
.
FILETYPE_ASN1
)
stop_date
=
x509
.
notAfter
(
cert
)
serial
=
cert
.
get_serial_number
()
if
serial
in
self
.
cache
.
crl
:
raise
ValueError
(
"revoked"
)
except
(
x509
.
VerifyError
,
ValueError
),
e
:
logging
.
debug
(
'ignored invalid certificate from %r (%s)'
,
address
,
e
.
args
[
-
1
])
...
...
@@ -320,6 +328,7 @@ class BaseTunnelManager(object):
peer
=
x509
.
Peer
(
p
)
insort
(
self
.
_peers
,
peer
)
peer
.
cert
=
cert
peer
.
serial
=
serial
peer
.
stop_date
=
stop_date
self
.
selectTimeout
(
stop_date
,
self
.
invalidatePeers
,
False
)
if
seqno
:
...
...
@@ -398,7 +407,7 @@ class BaseTunnelManager(object):
raise
utils
.
ReexecException
(
"Restart with new network parameters"
)
def
broadcast
Version
(
self
):
def
_new
Version
(
self
):
pass
def
newVersion
(
self
):
...
...
@@ -410,32 +419,77 @@ class BaseTunnelManager(object):
logging
.
info
(
"changed: %r"
,
changed
)
self
.
selectTimeout
(
None
,
self
.
newVersion
)
self
.
_version
=
self
.
cache
.
version
self
.
broadcast
Version
()
self
.
_new
Version
()
self
.
cache
.
warnProtocol
()
if
not
self
.
NEED_RESTART
.
isdisjoint
(
changed
)
or
\
version
.
protocol
<
self
.
cache
.
min_protocol
:
crl
=
self
.
cache
.
crl
for
i
in
reversed
([
i
for
i
,
peer
in
enumerate
(
self
.
_peers
)
if
peer
.
serial
in
crl
]):
del
self
.
_peers
[
i
]
if
self
.
cert
.
cert
.
get_serial_number
()
in
crl
:
raise
utils
.
ReexecException
(
"Our certificate has just been revoked."
" Let's try to renew it."
)
if
(
not
self
.
NEED_RESTART
.
isdisjoint
(
changed
)
or
version
.
protocol
<
self
.
cache
.
min_protocol
# TODO: With --management, we could kill clients without restarting.
or
not
all
(
crl
.
isdisjoint
(
serials
.
itervalues
())
for
serials
in
self
.
_served
.
itervalues
())):
# Wait at least 1 second to broadcast new version to neighbours.
# If re6stnet is too old, don't abort now, because a new version
# may have been installed without restart.
self
.
selectTimeout
(
time
.
time
()
+
1
+
self
.
cache
.
delay_restart
,
self
.
_restart
)
def
handleServerEvent
(
self
,
sock
):
event
,
args
=
eval
(
sock
.
recv
(
65536
))
logging
.
debug
(
"%s%r"
,
event
,
args
)
r
=
getattr
(
self
,
'_ovpn_'
+
event
.
replace
(
'-'
,
'_'
))(
*
args
)
if
r
is
not
None
:
sock
.
send
(
chr
(
r
))
def
_ovpn_client_connect
(
self
,
common_name
,
iface
,
serial
,
trusted_ip
):
if
serial
in
self
.
cache
.
crl
:
return
False
prefix
=
utils
.
binFromSubnet
(
common_name
)
self
.
_served
[
prefix
][
iface
]
=
serial
if
isinstance
(
self
,
TunnelManager
):
# XXX
if
self
.
_gateway_manager
is
not
None
:
self
.
_gateway_manager
.
add
(
trusted_ip
,
False
)
if
prefix
in
self
.
_connection_dict
and
self
.
_prefix
<
prefix
:
self
.
_kill
(
prefix
)
self
.
cache
.
connecting
(
prefix
,
0
)
return
True
def
_ovpn_client_disconnect
(
self
,
common_name
,
iface
,
serial
,
trusted_ip
):
prefix
=
utils
.
binFromSubnet
(
common_name
)
serials
=
self
.
_served
.
get
(
prefix
)
try
:
del
serials
[
iface
]
except
(
KeyError
,
TypeError
):
logging
.
exception
(
"ovpn_client_disconnect%r"
,
(
common_name
,
iface
,
serial
,
trusted_ip
))
return
if
not
serials
:
del
self
.
_served
[
prefix
]
if
isinstance
(
self
,
TunnelManager
):
# XXX
self
.
_abortTunnelKiller
(
prefix
,
iface
)
if
self
.
_gateway_manager
is
not
None
:
self
.
_gateway_manager
.
remove
(
trusted_ip
)
class
TunnelManager
(
BaseTunnelManager
):
NEED_RESTART
=
BaseTunnelManager
.
NEED_RESTART
.
union
((
'client_count'
,
'max_clients'
,
'tunnel_refresh'
))
def
__init__
(
self
,
control_socket
,
cache
,
cert
,
cert_renew
,
openvpn_args
,
def
__init__
(
self
,
control_socket
,
cache
,
cert
,
openvpn_args
,
timeout
,
client_count
,
iface_list
,
address
,
ip_changed
,
remote_gateway
,
disable_proto
,
neighbour_list
=
()):
super
(
TunnelManager
,
self
).
__init__
(
cache
,
cert
,
cert_renew
,
address
)
super
(
TunnelManager
,
self
).
__init__
(
cache
,
cert
,
address
)
self
.
ctl
=
ctl
.
Babel
(
control_socket
,
weakref
.
proxy
(
self
),
self
.
_network
)
self
.
ovpn_args
=
openvpn_args
self
.
timeout
=
timeout
# Create and open read_only pipe to get server events
r
,
self
.
write_pipe
=
os
.
pipe
()
self
.
_read_pipe
=
os
.
fdopen
(
r
)
self
.
_read_sock
,
self
.
write_sock
=
socket
.
socketpair
(
socket
.
AF_UNIX
,
socket
.
SOCK_DGRAM
)
self
.
_disconnected
=
0
self
.
_distant_peers
=
[]
self
.
_iface_to_prefix
=
{}
...
...
@@ -497,7 +551,7 @@ class TunnelManager(BaseTunnelManager):
def
select
(
self
,
r
,
w
,
t
):
super
(
TunnelManager
,
self
).
select
(
r
,
w
,
t
)
r
[
self
.
_read_
pipe
]
=
self
.
handleTunnel
Event
r
[
self
.
_read_
sock
]
=
self
.
handleClient
Event
if
self
.
_next_refresh
:
t
.
append
((
self
.
_next_refresh
,
self
.
refresh
))
self
.
ctl
.
select
(
r
,
w
,
t
)
...
...
@@ -572,10 +626,12 @@ class TunnelManager(BaseTunnelManager):
prefix
=
min
(
peer_set
,
key
=
self
.
_tunnelScore
)
self
.
_killing
[
prefix
]
=
TunnelKiller
(
prefix
,
self
,
True
)
def
_abortTunnelKiller
(
self
,
prefix
):
def
_abortTunnelKiller
(
self
,
prefix
,
iface
=
None
):
tunnel_killer
=
self
.
_killing
.
get
(
prefix
)
if
tunnel_killer
:
if
tunnel_killer
.
state
:
if
not
iface
or
\
iface
==
self
.
ctl
.
interfaces
[
tunnel_killer
.
ifindex
]:
tunnel_killer
.
abort
()
else
:
del
self
.
_killing
[
prefix
]
...
...
@@ -719,42 +775,15 @@ class TunnelManager(BaseTunnelManager):
for
prefix
in
self
.
_connection_dict
.
keys
():
self
.
_kill
(
prefix
)
def
handleTunnelEvent
(
self
):
try
:
msg
=
self
.
_read_pipe
.
readline
().
rstrip
()
args
=
msg
.
split
()
m
=
getattr
(
self
,
'_ovpn_'
+
args
.
pop
(
0
).
replace
(
'-'
,
'_'
))
except
(
AttributeError
,
ValueError
):
logging
.
warning
(
"Unknown message received from OpenVPN: %s"
,
msg
)
else
:
logging
.
debug
(
msg
)
m
(
*
args
)
def
_ovpn_client_connect
(
self
,
common_name
,
trusted_ip
):
prefix
=
utils
.
binFromSubnet
(
common_name
)
self
.
_served
.
add
(
prefix
)
if
self
.
_gateway_manager
is
not
None
:
self
.
_gateway_manager
.
add
(
trusted_ip
,
False
)
if
prefix
in
self
.
_connection_dict
and
self
.
_prefix
<
prefix
:
self
.
_kill
(
prefix
)
self
.
cache
.
connecting
(
prefix
,
0
)
def
_ovpn_client_disconnect
(
self
,
common_name
,
trusted_ip
):
prefix
=
utils
.
binFromSubnet
(
common_name
)
try
:
self
.
_served
.
remove
(
prefix
)
except
KeyError
:
return
self
.
_abortTunnelKiller
(
prefix
)
if
self
.
_gateway_manager
is
not
None
:
self
.
_gateway_manager
.
remove
(
trusted_ip
)
def
_ovpn_route_up
(
self
,
common_name
,
time
,
ip
):
def
handleClientEvent
(
self
):
msg
=
self
.
_read_sock
.
recv
(
65536
)
logging
.
debug
(
"route_up%s"
,
msg
)
common_name
,
time
,
serial
,
ip
=
eval
(
msg
)
prefix
=
utils
.
binFromSubnet
(
common_name
)
c
=
self
.
_connection_dict
.
get
(
prefix
)
if
c
and
c
.
time
<
float
(
time
):
try
:
c
.
connected
()
c
.
connected
(
serial
)
except
(
KeyError
,
TypeError
),
e
:
logging
.
error
(
"%s (route_up %s)"
,
e
,
common_name
)
else
:
...
...
@@ -765,7 +794,7 @@ class TunnelManager(BaseTunnelManager):
if
address
:
self
.
_address
[
family
]
=
utils
.
dump_address
(
address
)
def
broadcast
Version
(
self
):
def
_new
Version
(
self
):
for
prefix
in
self
.
ctl
.
neighbours
:
if
prefix
:
peer
=
self
.
_getPeer
(
prefix
)
...
...
@@ -774,3 +803,6 @@ class TunnelManager(BaseTunnelManager):
elif
(
peer
.
version
<
self
.
_version
and
self
.
sendto
(
prefix
,
'
\
0
'
+
self
.
_version
)):
peer
.
version
=
self
.
_version
for
prefix
,
c
in
self
.
_connection_dict
.
items
():
if
c
.
serial
in
self
.
cache
.
crl
:
self
.
_kill
(
prefix
)
re6st/x509.py
View file @
8ebdd500
...
...
@@ -42,10 +42,12 @@ def encrypt(cert, data):
def
fingerprint
(
cert
,
alg
=
'sha1'
):
return
hashlib
.
new
(
alg
,
crypto
.
dump_certificate
(
crypto
.
FILETYPE_ASN1
,
cert
))
def
maybe_renew
(
path
,
cert
,
info
,
renew
):
def
maybe_renew
(
path
,
cert
,
info
,
renew
,
force
=
False
):
from
.registry
import
RENEW_PERIOD
while
True
:
if
cert
.
get_serial_number
():
if
force
:
force
=
False
else
:
next_renew
=
notAfter
(
cert
)
-
RENEW_PERIOD
if
time
.
time
()
<
next_renew
:
return
cert
,
next_renew
...
...
@@ -110,11 +112,10 @@ class Cert(object):
'--cert'
,
self
.
cert_path
,
'--key'
,
self
.
key_path
)
def
maybeRenew
(
self
,
registry
):
from
.registry
import
RegistryClient
registry
=
RegistryClient
(
registry
,
self
)
def
maybeRenew
(
self
,
registry
,
crl
):
self
.
cert
,
next_renew
=
maybe_renew
(
self
.
cert_path
,
self
.
cert
,
"Certificate"
,
lambda
:
registry
.
renewCertificate
(
self
.
prefix
))
"Certificate"
,
lambda
:
registry
.
renewCertificate
(
self
.
prefix
),
self
.
cert
.
get_serial_number
()
in
crl
)
self
.
ca
,
ca_renew
=
maybe_renew
(
self
.
ca_path
,
self
.
ca
,
"CA Certificate"
,
registry
.
getCa
)
return
min
(
next_renew
,
ca_renew
)
...
...
@@ -181,6 +182,7 @@ class Peer(object):
"""
_hello
=
_last
=
0
_key
=
newHmacSecret
()
serial
=
None
stop_date
=
float
(
'inf'
)
version
=
''
...
...
re6stnet
View file @
8ebdd500
...
...
@@ -2,6 +2,7 @@
import
atexit
,
errno
,
logging
,
os
,
shutil
,
signal
import
socket
,
subprocess
,
sys
,
time
,
threading
from
collections
import
deque
from
functools
import
partial
from
re6st
import
plib
,
tunnel
,
utils
,
version
,
x509
from
re6st.cache
import
Cache
from
re6st.utils
import
exit
,
ReexecException
...
...
@@ -130,7 +131,6 @@ def main():
exit
.
signal
(
0
,
signal
.
SIGINT
,
signal
.
SIGTERM
)
exit
.
signal
(
-
1
,
signal
.
SIGHUP
,
signal
.
SIGUSR2
)
next_renew
=
cert
.
maybeRenew
(
config
.
registry
)
cache
=
Cache
(
db_path
,
config
.
registry
,
cert
)
network
=
cert
.
network
...
...
@@ -249,14 +249,12 @@ def main():
control_socket
=
os
.
path
.
join
(
config
.
run
,
'babeld.sock'
)
if
config
.
client_count
and
not
config
.
client
:
tunnel_manager
=
tunnel
.
TunnelManager
(
control_socket
,
cache
,
cert
,
next_renew
,
config
.
openvpn_args
,
timeout
,
cache
,
cert
,
config
.
openvpn_args
,
timeout
,
config
.
client_count
,
config
.
iface_list
,
address
,
ip_changed
,
remote_gateway
,
config
.
disable_proto
,
config
.
neighbour
)
tunnel_interfaces
+=
tunnel_manager
.
new_iface_list
write_pipe
=
tunnel_manager
.
write_pipe
else
:
write_pipe
=
None
tunnel_manager
=
tunnel
.
BaseTunnelManager
(
cache
,
cert
,
next_renew
)
tunnel_manager
=
tunnel
.
BaseTunnelManager
(
cache
,
cert
)
cleanup
.
append
(
tunnel_manager
.
sock
.
close
)
try
:
...
...
@@ -275,6 +273,7 @@ def main():
# an public IP so Babel must be changed to set a source
# address on routes it installs.
ip
(
'addrlabel'
,
'prefix'
,
my_network
,
'label'
,
'99'
)
R
=
{}
# prepare persistent interfaces
if
config
.
client
:
address_list
=
[
x
for
x
in
utils
.
parse_address
(
config
.
client
)
...
...
@@ -288,9 +287,13 @@ def main():
elif
server_tunnels
:
required
(
'dh'
)
for
iface
,
(
port
,
proto
)
in
server_tunnels
.
iteritems
():
r
,
x
=
socket
.
socketpair
(
socket
.
AF_UNIX
,
socket
.
SOCK_DGRAM
)
cleanup
.
append
(
plib
.
server
(
iface
,
config
.
max_clients
,
config
.
dh
,
write_pipe
,
port
,
proto
,
cache
.
encrypt
,
'--ping-exit'
,
str
(
timeout
),
*
config
.
openvpn_args
).
stop
)
config
.
dh
,
x
.
fileno
(),
port
,
proto
,
cache
.
encrypt
,
'--ping-exit'
,
str
(
timeout
),
*
config
.
openvpn_args
,
preexec_fn
=
r
.
close
).
stop
)
R
[
r
]
=
partial
(
tunnel_manager
.
handleServerEvent
,
r
)
x
.
close
()
ip
(
'addr'
,
my_ip
,
'dev'
,
config
.
main_interface
)
if_rt
=
[
'ip'
,
'-6'
,
'route'
,
'del'
,
...
...
@@ -371,7 +374,7 @@ def main():
select_list
=
[
forwarder
.
select
]
if
forwarder
else
[]
select_list
+=
tunnel_manager
.
select
,
utils
.
select
while
True
:
args
=
{}
,
{},
[]
args
=
R
.
copy
()
,
{},
[]
for
s
in
select_list
:
s
(
*
args
)
finally
:
...
...
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