3
0
mirror of https://github.com/jlu5/PyLink.git synced 2025-01-12 13:12:36 +01:00

Irc: optionally validate SSL cert fingerprints (#80)

This commit is contained in:
James Lu 2015-08-12 02:00:43 -07:00
parent fe7adb716b
commit d9f5cdfeaf
2 changed files with 47 additions and 10 deletions

View File

@ -56,9 +56,14 @@ servers:
# Toggles SSL for this network. Defaults to false if not specified, and requires the # Toggles SSL for this network. Defaults to false if not specified, and requires the
# ssl_certfile and ssl_keyfile options to work. # ssl_certfile and ssl_keyfile options to work.
# ssl: true # ssl: true
# ssl_certfile: pylink-cert.pem # ssl_certfile: pylink-cert.pem
# ssl_keyfile: pylink-key.pem # ssl_keyfile: pylink-key.pem
# Optionally, you can set this option to verify the SSL certificate
# fingerprint (SHA1) of your uplink.
# ssl_fingerprint: "e0fee1adf795c84eec4735f039503eb18d9c35cc"
ts6net: ts6net:
ip: 127.0.0.1 ip: 127.0.0.1
port: 7000 port: 7000

52
main.py
View File

@ -8,6 +8,7 @@ import sys
from collections import defaultdict from collections import defaultdict
import threading import threading
import ssl import ssl
import hashlib
from log import log from log import log
import conf import conf
@ -75,31 +76,62 @@ class Irc():
port = self.serverdata["port"] port = self.serverdata["port"]
while True: while True:
self.initVars() self.initVars()
checks_ok = True
try: try:
self.socket = socket.socket() self.socket = socket.socket()
self.socket.setblocking(0) self.socket.setblocking(0)
# Initial connection timeout is a lot smaller than the timeout after # Initial connection timeout is a lot smaller than the timeout after
# we've connected; this is intentional. # we've connected; this is intentional.
self.socket.settimeout(self.pingfreq) self.socket.settimeout(self.pingfreq)
self.ssl = self.serverdata.get('ssl')
if self.serverdata.get('ssl'): if self.ssl:
log.info('(%s) Attempting SSL for this connection...', self.name) log.info('(%s) Attempting SSL for this connection...', self.name)
certfile = self.serverdata.get('ssl_certfile') certfile = self.serverdata.get('ssl_certfile')
keyfile = self.serverdata.get('ssl_keyfile') keyfile = self.serverdata.get('ssl_keyfile')
if certfile and keyfile: if certfile and keyfile:
self.socket = ssl.wrap_socket(self.socket, certfile=certfile, keyfile=keyfile) self.socket = ssl.wrap_socket(self.socket, certfile=certfile, keyfile=keyfile)
else: else:
log.warning('(%s) SSL certfile/keyfile was not set correctly. ' log.error('(%s) SSL certfile/keyfile was not set '
'SSL will be disabled for this connection.', self.name) 'correctly, aborting... ', self.name)
checks_ok = False
log.info("Connecting to network %r on %s:%s", self.name, ip, port) log.info("Connecting to network %r on %s:%s", self.name, ip, port)
self.socket.connect((ip, port)) self.socket.connect((ip, port))
self.socket.settimeout(self.pingtimeout) self.socket.settimeout(self.pingtimeout)
self.proto.connect(self)
self.spawnMain() if self.ssl and checks_ok:
log.info('(%s) Starting ping schedulers....', self.name) peercert = self.socket.getpeercert(binary_form=True)
self.schedulePing() sha1fp = hashlib.sha1(peercert).hexdigest()
log.info('(%s) Server ready; listening for data.', self.name) expected_fp = self.serverdata.get('ssl_fingerprint')
self.run() if expected_fp:
if sha1fp != expected_fp:
log.error('(%s) Uplink\'s SSL certificate '
'fingerprint (SHA1) does not match the '
'one configured: expected %r, got %r; '
'disconnecting...', self.name,
expected_fp, sha1fp)
checks_ok = False
else:
log.info('(%s) Uplink SSL certificate fingerprint '
'(SHA1) verified: %r', self.name, sha1fp)
else:
log.info('(%s) Uplink\'s SSL certificate fingerprint '
'is %r. You can enhance the security of your '
'link by specifying this in a "ssl_fingerprint"'
' option in your server block.', self.name,
sha1fp)
if checks_ok:
self.proto.connect(self)
self.spawnMain()
log.info('(%s) Starting ping schedulers....', self.name)
self.schedulePing()
log.info('(%s) Server ready; listening for data.', self.name)
self.run()
else:
log.error('(%s) A configuration error was encountered '
'trying to set up this connection. Please check'
' your configuration file and try again.',
self.name)
except (socket.error, classes.ProtocolError, ConnectionError) as e: except (socket.error, classes.ProtocolError, ConnectionError) as e:
log.warning('(%s) Disconnected from IRC: %s: %s', log.warning('(%s) Disconnected from IRC: %s: %s',
self.name, type(e).__name__, str(e)) self.name, type(e).__name__, str(e))