Commit 5539f577 authored by Joanne Hugé's avatar Joanne Hugé

Add communities

parent f1e95660
...@@ -7,3 +7,4 @@ hello 4 ...@@ -7,3 +7,4 @@ hello 4
client-count 2 client-count 2
tunnel-refresh 100 tunnel-refresh 100
ipv4 10.42.0.0/16 8 ipv4 10.42.0.0/16 8
community registry/community.conf
...@@ -45,6 +45,9 @@ def main(): ...@@ -45,6 +45,9 @@ def main():
_('--anonymous', action='store_true', _('--anonymous', action='store_true',
help="Request an anonymous certificate. No email is required but the" help="Request an anonymous certificate. No email is required but the"
" registry may deliver a longer prefix.") " registry may deliver a longer prefix.")
_('--country',
help="Specify country for the community assignment (default:"
" country is detected based on IP in X-Forwarded-For header")
config = parser.parse_args() config = parser.parse_args()
if config.dir: if config.dir:
os.chdir(config.dir) os.chdir(config.dir)
...@@ -141,7 +144,8 @@ def main(): ...@@ -141,7 +144,8 @@ def main():
# to avoid using our token for nothing. # to avoid using our token for nothing.
cert_fd = os.open(cert_path, os.O_CREAT | os.O_WRONLY, 0666) cert_fd = os.open(cert_path, os.O_CREAT | os.O_WRONLY, 0666)
print "Requesting certificate ..." print "Requesting certificate ..."
cert = s.requestCertificate(token, req) cert = s.requestCertificate(token, req, country=config.country) \
if config.country else s.requestCertificate(token, req)
if not cert: if not cert:
token_advice = None token_advice = None
sys.exit("Error: invalid or expired token") sys.exit("Error: invalid or expired token")
......
...@@ -110,6 +110,8 @@ def main(): ...@@ -110,6 +110,8 @@ def main():
help="Reject nodes that are too old. Current is %s." % version.protocol) help="Reject nodes that are too old. Current is %s." % version.protocol)
_('--authorized-origin', action='append', default=['127.0.0.1', '::1'], _('--authorized-origin', action='append', default=['127.0.0.1', '::1'],
help="Authorized IPs to access origin-restricted RPC.") help="Authorized IPs to access origin-restricted RPC.")
_('--community',
help="File containing community configuration")
_ = parser.add_argument_group('routing').add_argument _ = parser.add_argument_group('routing').add_argument
_('--hello', type=int, default=15, _('--hello', type=int, default=15,
......
...@@ -68,6 +68,13 @@ class RegistryServer(object): ...@@ -68,6 +68,13 @@ class RegistryServer(object):
self.sessions = {} self.sessions = {}
self.sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) self.sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
# Community
self.community_map = {}
if config.community:
with open(config.community, 'r') as f:
self.community_map = {country: prefix
for country, prefix in [l[:-1].split(' ') for l in f]}
# Database initializing # Database initializing
db_dir = os.path.dirname(self.config.db) db_dir = os.path.dirname(self.config.db)
db_dir and utils.makedirs(db_dir) db_dir and utils.makedirs(db_dir)
...@@ -88,7 +95,11 @@ class RegistryServer(object): ...@@ -88,7 +95,11 @@ class RegistryServer(object):
"prefix TEXT PRIMARY KEY NOT NULL", "prefix TEXT PRIMARY KEY NOT NULL",
"email TEXT", "email TEXT",
"cert TEXT") "cert TEXT")
self.db.execute("INSERT OR IGNORE INTO cert VALUES ('',null,null)") for c in self.community_map:
self.db.execute(
"INSERT OR IGNORE INTO cert VALUES (?,null,null)", (self.community_map[c],))
if not self.community_map:
self.db.execute("INSERT OR IGNORE INTO cert VALUES ('',null,null)")
utils.sqliteCreateTable(self.db, "crl", utils.sqliteCreateTable(self.db, "crl",
"serial INTEGER PRIMARY KEY NOT NULL", "serial INTEGER PRIMARY KEY NOT NULL",
# Expiration date of revoked certificate. # Expiration date of revoked certificate.
...@@ -279,6 +290,8 @@ class RegistryServer(object): ...@@ -279,6 +290,8 @@ class RegistryServer(object):
request.headers.get("X-Forwarded-For") or request.headers.get("X-Forwarded-For") or
request.headers.get("host"), request.headers.get("host"),
request.headers.get("user-agent")) request.headers.get("user-agent"))
if 'ip' in kw:
kw['ip'] = request.headers.get("X-Forwarded-For") or request.headers.get("host")
try: try:
result = m(**kw) result = m(**kw)
except HTTPError, e: except HTTPError, e:
...@@ -385,12 +398,13 @@ class RegistryServer(object): ...@@ -385,12 +398,13 @@ class RegistryServer(object):
s.sendmail(self.email, email, msg.as_string()) s.sendmail(self.email, email, msg.as_string())
s.quit() s.quit()
def newPrefix(self, prefix_len): def newPrefix(self, prefix_len, country=''):
max_len = 128 - len(self.network) max_len = 128 - len(self.network)
assert 0 < prefix_len <= max_len assert 0 < prefix_len <= max_len
try: try:
prefix, = self.db.execute("""SELECT prefix FROM cert WHERE length(prefix) <= ? AND cert is null prefix, = self.db.execute("""SELECT prefix FROM cert WHERE length(prefix) <= ? AND cert is null
ORDER BY length(prefix) DESC""", (prefix_len,)).next() AND prefix LIKE ? ORDER BY length(prefix) DESC""",
(prefix_len, self.community_map.get(country, '') + '%')).next()
except StopIteration: except StopIteration:
logging.error('No more free /%u prefix available', prefix_len) logging.error('No more free /%u prefix available', prefix_len)
raise raise
...@@ -401,10 +415,10 @@ class RegistryServer(object): ...@@ -401,10 +415,10 @@ class RegistryServer(object):
if len(prefix) < max_len or '1' in prefix: if len(prefix) < max_len or '1' in prefix:
return prefix return prefix
self.db.execute("UPDATE cert SET cert = 'reserved' WHERE prefix = ?", (prefix,)) self.db.execute("UPDATE cert SET cert = 'reserved' WHERE prefix = ?", (prefix,))
return self.newPrefix(prefix_len) return self.newPrefix(prefix_len, country)
@rpc @rpc
def requestCertificate(self, token, req): def requestCertificate(self, token, req, country='', ip=''):
req = crypto.load_certificate_request(crypto.FILETYPE_PEM, req) req = crypto.load_certificate_request(crypto.FILETYPE_PEM, req)
with self.lock: with self.lock:
with self.db: with self.db:
...@@ -424,7 +438,9 @@ class RegistryServer(object): ...@@ -424,7 +438,9 @@ class RegistryServer(object):
if not prefix_len: if not prefix_len:
raise HTTPError(httplib.FORBIDDEN) raise HTTPError(httplib.FORBIDDEN)
email = None email = None
prefix = self.newPrefix(prefix_len) country = country if country else self._geoiplookup(ip)
prefix = self.newPrefix(prefix_len,
country if country in self.community_map else '_')
self.db.execute("UPDATE cert SET email = ? WHERE prefix = ?", self.db.execute("UPDATE cert SET email = ? WHERE prefix = ?",
(email, prefix)) (email, prefix))
if self.prefix is None: if self.prefix is None:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment