This commit is contained in:
emdee 2022-11-06 03:57:13 +00:00
parent 6f73f766ac
commit f30a1038ad
2 changed files with 286 additions and 131 deletions

View File

@ -42,6 +42,7 @@ LOG = logging.getLogger('app.'+'ts')
class SyniToxError(BaseException): pass class SyniToxError(BaseException): pass
NAME = 'SyniTox' NAME = 'SyniTox'
sMSG = 'MSG'
SSL_TOR_RANGE = '172.' SSL_TOR_RANGE = '172.'
# possible CA locations picks the first one # possible CA locations picks the first one
lCAs = [# debian and gentoo lCAs = [# debian and gentoo
@ -237,23 +238,17 @@ class SyniTox(Tox):
context = SSL.Context(SSL.TLS_CLIENT_METHOD) # TLSv1_2_METHOD context = SSL.Context(SSL.TLS_CLIENT_METHOD) # TLSv1_2_METHOD
# SSL.OP_NO_TLSv1_1 is allowed # SSL.OP_NO_TLSv1_1 is allowed
context.set_options(SSL.OP_NO_SSLv2|SSL.OP_NO_SSLv3|SSL.OP_NO_TLSv1) context.set_options(SSL.OP_NO_SSLv2|SSL.OP_NO_SSLv3|SSL.OP_NO_TLSv1)
# this maybe necessary even for a 1.3 site to get the handshake
# in pyOpenSSL - or was it a protocol downgrade attack?
#? context.set_cipher_list("DEFAULT:SECLEVEL=1")
# im getting SSL error: ([('SSL routines', 'tls_construct_client_hello', 'no protocols available')],)
# if I use tlsv1.3 or tlsv1.2 without this on a tlsv1.3 capacble site
if self._oArgs.irc_pem: if self._oArgs.irc_crt and self._oArgs.irc_key:
key = self._oArgs.irc_pem
assert os.path.exists(key), key assert os.path.exists(key), key
val = SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT val = SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT
LOG.info('Using keyfile: %s' % self._oArgs.irc_pem) LOG.info('Using keyfile: %s' % key)
if True: if True: # required!
# key = self._oArgs.irc_pem.replace('.pem', '.crt') key = self._oArgs.irc_crt
assert os.path.exists(key), key assert os.path.exists(key), key
context.use_certificate_file(key, filetype=SSL.FILETYPE_PEM) context.use_certificate_file(key, filetype=SSL.FILETYPE_PEM)
if True: if True: # required!
# key = self._oArgs.irc_pem.replace('.pem', '.key') key = self._oArgs.irc_key
assert os.path.exists(key), key assert os.path.exists(key), key
context.use_privatekey_file(key, filetype=SSL.FILETYPE_PEM) context.use_privatekey_file(key, filetype=SSL.FILETYPE_PEM)
#? load_client_ca #? load_client_ca
@ -261,10 +256,10 @@ class SyniTox(Tox):
# where in the SSL handshake the function was called, and # where in the SSL handshake the function was called, and
# the return code from a internal function call # the return code from a internal function call
print(f"iLine={iLine}, iRet={iRet}") print(f"iLine={iLine}, iRet={iRet}")
# context.set_info_callback(SSL_hands_cb) context.set_info_callback(SSL_hands_cb)
def keylog_callback(oConn,s): def keylog_callback(oConn,s):
print(s) print(s)
context.set_keylog_callback(keylog_callback) # context.set_keylog_callback(keylog_callback)
else: else:
val = SSL.VERIFY_PEER val = SSL.VERIFY_PEER
context.set_verify(val, ssl_verify_cb(HOST, override)) context.set_verify(val, ssl_verify_cb(HOST, override))
@ -305,7 +300,7 @@ class SyniTox(Tox):
lNodes = ts.generate_nodes(oArgs=self._oArgs, lNodes = ts.generate_nodes(oArgs=self._oArgs,
ipv='ipv4', ipv='ipv4',
udp_not_tcp=True) udp_not_tcp=True)
self._settings['current_nodes_udp'] = ts.sDNSClean(lNodes) self._settings['current_nodes_udp'] = ts.lDNSClean(lNodes)
if not lNodes: if not lNodes:
LOG.warn('empty generate_nodes udp') LOG.warn('empty generate_nodes udp')
else: else:
@ -314,7 +309,7 @@ class SyniTox(Tox):
lNodes = ts.generate_nodes(oArgs=self._oArgs, lNodes = ts.generate_nodes(oArgs=self._oArgs,
ipv='ipv4', ipv='ipv4',
udp_not_tcp=False) udp_not_tcp=False)
self._settings['current_nodes_tcp'] = ts.sDNSClean(lNodes) self._settings['current_nodes_tcp'] = ts.lDNSClean(lNodes)
if not lNodes: if not lNodes:
LOG.warn('empty generate_nodes tcp') LOG.warn('empty generate_nodes tcp')
else: else:
@ -500,24 +495,28 @@ class SyniTox(Tox):
def diagnose_ciphers(self, irc): def diagnose_ciphers(self, irc):
cipher_name = irc.get_cipher_name() cipher_name = irc.get_cipher_name()
LOG.info(f"cipher_name={irc.get_cipher_name()}") LOG.info(f"diagnose_ciphers cipher_name={irc.get_cipher_name()}")
LOG.debug(f"get_cipher_list={irc.get_cipher_list()}") LOG.debug(f"diagnose_ciphers get_cipher_list={irc.get_cipher_list()}")
cipher_list=irc.get_cipher_list() cipher_list=irc.get_cipher_list()
for ci in lOPENSSL_13_CIPHERS: for ci in lOPENSSL_13_CIPHERS:
if ci in cipher_list: LOG.info(f"server supports v1.3 cipher {ci}") if ci in cipher_list: LOG.debug(f"server supports v1.3 cipher {ci}")
for cert in irc.get_peer_cert_chain():
# x509 objects - just want the /CN
LOG.debug(f"{cert.get_subject().CN} {cert.get_issuer()}")
cipher_name = irc.get_cipher_name() cipher_name = irc.get_cipher_name()
LOG.info(f"cipher_name={irc.get_cipher_name()}")
if self._oArgs.irc_ssl == 'tlsv1.2': if self._oArgs.irc_ssl == 'tlsv1.2':
assert cipher_name in lOPENSSL_12_CIPHERS, cipher_name assert cipher_name in lOPENSSL_12_CIPHERS or \
cipher_name in lOPENSSL_13_CIPHERS, cipher_name
elif self._oArgs.irc_ssl == 'tlsv1.3': elif self._oArgs.irc_ssl == 'tlsv1.3':
assert cipher_name in lOPENSSL_13_CIPHERS, cipher_name assert cipher_name in lOPENSSL_13_CIPHERS, cipher_name
for cert in irc.get_peer_cert_chain(): got = irc.get_protocol_version_name().lower()
# x509 objects - just want the /CN if got > self._oArgs.irc_ssl:
LOG.debug(f"{cert.get_subject()} {cert.get_issuer()}") LOG.debug(f"Got: {irc.get_protocol_version_name().lower()} asked for {self._oArgs.irc_ssl}")
assert irc.get_protocol_version_name().lower() == \ elif got < self._oArgs.irc_ssl:
self._oArgs.irc_ssl, \ LOG.warn(f"Got: {irc.get_protocol_version_name().lower()} asked for {self._oArgs.irc_ssl}")
irc.get_protocol_version_name().lower() LOG.info(f"diagnose_ciphers {str(irc.get_state_string(), 'UTF-8')}")
def irc_init(self): def irc_init(self):
global iSocks5Error global iSocks5Error
@ -562,7 +561,6 @@ class SyniTox(Tox):
irc.set_tlsext_host_name(None) irc.set_tlsext_host_name(None)
else: else:
irc.set_tlsext_host_name(bytes(self._oArgs.irc_host, 'UTF-8')) irc.set_tlsext_host_name(bytes(self._oArgs.irc_host, 'UTF-8'))
#? irc.set_connect_state()
while True: while True:
try: try:
irc.do_handshake() irc.do_handshake()
@ -579,21 +577,24 @@ class SyniTox(Tox):
irc.connect((ip, self._oArgs.irc_port)) irc.connect((ip, self._oArgs.irc_port))
LOG.info(f"IRC SSL={self._oArgs.irc_ssl} connected ") LOG.info(f"IRC SSL={self._oArgs.irc_ssl} connected ")
except wrapper_tests.socks.Socks5Error as e: except (wrapper_tests.socks.GeneralProxyError, wrapper_tests.socks.Socks5Error) as e:
iSocks5Error += 1 iSocks5Error += 1
if iSocks5Error >= iSocks5ErrorMax: if iSocks5Error >= iSocks5ErrorMax:
raise SyniToxError(f"{e.args}") raise SyniToxError(f"{e.args}")
if len(e.args[0]) == 2 and e.args[0][0] == 2: if len(e.args[0]) == 2:
LOG.warn(f"Socks5Error: do you have Tor SafeSocks set? {e.args[0]}") if e.args[0][0] == 2:
elif len(e.args[0]) == 2 and e.args[0][0] == 5: LOG.warn(f"Socks5Error: do you have Tor SafeSocks set? {e.args[0]}")
# (5, 'Connection refused') elif e.args[0][0] == 5:
LOG.warn(f"Socks5Error: do you have Tor running? {e.args[0]}") # (5, 'Connection refused')
raise SyniToxError(f"{e.args}") LOG.warn(f"Socks5Error: do you have Tor running? {e.args[0]}")
elif len(e.args[0]) == 2 and e.args[0][0] in [1, 6]: raise SyniToxError(f"{e.args}")
# (6, 'TTL expired'), 1, ('general SOCKS server failure') elif e.args[0][0] in [1, 6, 0]:
# Missing mapping for virtual address '172.17.140.117'. Refusing. # (0, "connection closed unexpectedly")
LOG.warn(f"Socks5Error: {e.args[0]}") # (6, 'TTL expired'),
return # 1, ('general SOCKS server failure')
# Missing mapping for virtual address '172.17.140.117'. Refusing.
LOG.warn(f"Socks5Error: {e.args[0]}")
return
else: else:
LOG.error(f"Socks5Error: {e.args}") LOG.error(f"Socks5Error: {e.args}")
raise SyniToxError(f"{e.args}") raise SyniToxError(f"{e.args}")
@ -618,12 +619,16 @@ class SyniTox(Tox):
return return
self.irc = irc self.irc = irc
if not self._oArgs.irc_ssl: self.irc.send(bytes('CAP ' + 'LS' + '\r\n', 'UTF-8' ))
self.irc.send(bytes('NICK ' + nick + '\r\n', 'UTF-8' )) self.irc.send(bytes('CAP ' + 'REQ :multi-prefix' + '\r\n', 'UTF-8'))
self.irc.send(bytes('USER %s %s bla :%s\r\n' % ( self.irc.send(bytes('CAP ' + 'END' + '\r\n', 'UTF-8' ))
self._oArgs.irc_ident, # withh or without self._oArgs.irc_pem:
self._oArgs.irc_host, LOG.info("Sent CAP sending NICK and USER")
self._oArgs.irc_name), 'UTF-8')) self.irc.send(bytes('NICK ' + nick + '\r\n', 'UTF-8' ))
self.irc.send(bytes('USER %s %s bla :%s\r\n' % (
self._oArgs.irc_ident,
self._oArgs.irc_host,
self._oArgs.irc_name), 'UTF-8'))
# OSError: [Errno 9] Bad file descriptor # OSError: [Errno 9] Bad file descriptor
@ -643,7 +648,7 @@ class SyniTox(Tox):
self.test_net() self.test_net()
lNodes = self._settings['current_nodes_tcp'] lNodes = self._settings['current_nodes_tcp']
shuffle(lNodes) shuffle(lNodes)
LOG.debug(f'TCP bootstapping 6') LOG.info(f'TCP bootstapping 6')
ts.bootstrap_tcp(lNodes[:6], [self]) ts.bootstrap_tcp(lNodes[:6], [self])
def get_all_groups(self): def get_all_groups(self):
@ -714,8 +719,8 @@ class SyniTox(Tox):
if b'NOTICE AUTH' in lines[0]: if b'NOTICE AUTH' in lines[0]:
for line in lines[:99]: for line in lines[:99]:
if b'NOTICE AUTH' not in line: return if b'NOTICE AUTH' not in line: return
line = str(line, 'UTF-8').strip() lines = str(line, 'UTF-8').strip().split()
print(line) print(' '.join(lines[1:]))
else: else:
for line in lines[:5]: for line in lines[:5]:
line = str(line, 'UTF-8').strip().lower() line = str(line, 'UTF-8').strip().lower()
@ -740,44 +745,68 @@ class SyniTox(Tox):
l = line.rstrip().split() l = line.rstrip().split()
if len(l) < 2: if len(l) < 2:
print(line) print(line)
elif l[1] not in ['372']: elif l[1] in ['PING']:
print(line)
elif l[1] in ['372']:
LOG.info('MOTD')
elif l[1] not in ['372', '353']:
i = line.find(' ') i = line.find(' ')
print(line[i+1:]) print(line[i+1:])
else:
LOG.info('MOTD')
rx = re.match(r':(.*?)!.*? PRIVMSG %s :(.*?)\r' % rx = re.match(r':(.*?)!.*? PRIVMSG %s :(.*?)\r' %
self._oArgs.irc_chan, line, re.S) self._oArgs.irc_chan, line, re.S)
if rx: if l[0] == 'QUIT':
self.relay_message(rx) LOG.info('QUIT')
return
if len(l) == 1:
self.irc_send('PING %s\r\n' % '#tor')
elif l[0] == 'PING': elif l[0] == 'PING':
self.irc_send('PONG %s\r\n' % l[1]) self.irc_send('PONG %s\r\n' % l[1])
elif rx:
self.relay_message(rx)
elif len(l) < 2: elif len(l) < 2:
pass pass
elif l[1] in ['461', '431']: elif l[1] in ['461', '431']:
pass pass
elif l[1] in ['433', '462', '477']: elif l[1] in ['433']:
# maybe should be an outright fail
if self._oArgs.irc_ssl: if self._oArgs.irc_ssl:
LOG.warn("Maybe the certificate was not received") LOG.warn("Maybe the certificate was not received")
#? raise SyniToxError(line)
# sometimes but not always:
# 433 * SyniTox :Nickname is already in use.
# app.ts ERROR SSL error: (32, 'EPIPE')
# or instead
# 451 * :Register first.
# error :closing link: 185.38.175.131 (registration timed out)
# or instead: just
# app.ts ERROR SSL error: (32, 'EPIPE')
pass
elif l[1] in ['451', '462', '477']:
if self._oArgs.irc_crt and self._oArgs.irc_key:
LOG.warn("Maybe the certificate was not received")
raise SyniToxError(line) raise SyniToxError(line)
elif l[1] in ['376']: elif l[1] in ['376']:
# :End of /MOTD command # :End of /MOTD command
if self._oArgs.irc_ssl != '': if self._oArgs.irc_crt and self._oArgs.irc_key:
pass pass
elif email == '' and pwd: elif email == '' and pwd:
LOG.info(bytes('PRIVMSG NickServ IDENTIFY %s %s\r\n' LOG.info(bytes(sMSG+' NickServ IDENTIFY %s %s\r\n'
% (nick, pwd,), 'UTF-8')) % (nick, pwd,), 'UTF-8'))
self.irc.send(bytes('PRIVMSG NickServ IDENTIFY %s %s\r\n' self.irc.send(bytes(sMSG+' NickServ IDENTIFY %s %s\r\n'
% (nick, pwd,), 'UTF-8')) % (pwd,nick, ), 'UTF-8'))
elif email != '' and pwd: elif email != '' and pwd:
LOG.info(bytes('PRIVMSG NickServ REGISTER %s %s\r\n' LOG.info(bytes(sMSG+' NickServ REGISTER %s %s\r\n'
% (pwd, email,), 'UTF-8')) % (pwd, email,), 'UTF-8'))
self.irc.send(bytes('PRIVMSG NickServ REGISTER %s %s\r\n' self.irc.send(bytes(sMSG+' NickServ REGISTER %s %s\r\n'
% (pwd, email,), 'UTF-8')) % (pwd, email,), 'UTF-8'))
else: else:
LOG.error("you must provide a password to register") LOG.error("you must provide a password to register")
raise RuntimeError("you must provide a password to register") raise RuntimeError("you must provide a password to register")
try: try:
self.irc.send(bytes('JOIN %s\r\n' % self._oArgs.irc_chan, 'UTF-8')) self.irc.send(bytes(sMSG+' NickServ set cloak on\r\n', 'UTF-8'))
if self._oArgs.irc_chan:
self.irc.send(bytes('JOIN %s\r\n' % self._oArgs.irc_chan, 'UTF-8'))
except BrokenPipeError: except BrokenPipeError:
raise SyniToxError('BrokenPipeError') raise SyniToxError('BrokenPipeError')
@ -868,7 +897,7 @@ class SyniTox(Tox):
dht_conneted = self.self_get_connection_status() dht_conneted = self.self_get_connection_status()
if not dht_conneted: if not dht_conneted:
self.dht_init() self.dht_init()
LOG.info(f'Not DHT connected {iCount} iterating {10 + iDelay} seconds') LOG.info(f'Not DHT connected {iCount} iterating {iDelay} seconds')
iDelay = iDelay + iDelay // 10 iDelay = iDelay + iDelay // 10
self.do(iDelay) self.do(iDelay)
#drop through #drop through
@ -930,7 +959,7 @@ class SyniTox(Tox):
iDelay = 10 iDelay = 10
self.irc_readlines() self.irc_readlines()
self.do(iDelay)
return 0 return 0
def quit(self): def quit(self):
@ -979,7 +1008,7 @@ class SyniTox(Tox):
if message.startswith('>'): if message.startswith('>'):
message = '\x0309%s\x03' % message message = '\x0309%s\x03' % message
self.irc_send(b'PRIVMSG %s :[%s]: %s\r\n' % self.irc_send(bsMSG+' %s :[%s]: %s\r\n' %
(self._oArgs.irc_chan, name, message)) (self._oArgs.irc_chan, name, message))
if message.startswith('^'): if message.startswith('^'):
self.handle_command(message) self.handle_command(message)
@ -991,8 +1020,8 @@ class SyniTox(Tox):
print('TOX> %s: %s' % (name, action)) print('TOX> %s: %s' % (name, action))
if action.startswith('>'): if action.startswith('>'):
action = '\x0309%s\x03' % action action = '\x0309%s\x03' % action
self.irc_send('PRIVMSG %s :\x01ACTION [%s]: %s\x01\r\n' % self.irc_send(bytes(sMSG+' %s :\x01ACTION [%s]: %s\x01\r\n' %
(self._oArgs.irc_chan, name, action)) (self._oArgs.irc_chan, name, action), 'UTF-8'))
def on_friend_request(self, pk, message): def on_friend_request(self, pk, message):
LOG.info('Friend request from %s: %s' % (pk, message)) LOG.info('Friend request from %s: %s' % (pk, message))
@ -1014,7 +1043,7 @@ class SyniTox(Tox):
def send_both(self, content): def send_both(self, content):
type_ = TOX_MESSAGE_TYPE['NORMAL'] type_ = TOX_MESSAGE_TYPE['NORMAL']
self.ensure_exe(self.group_send_message, self.sGROUP_BOT_NUM, type_, content) self.ensure_exe(self.group_send_message, self.sGROUP_BOT_NUM, type_, content)
self.irc_send('PRIVMSG %s :%s\r\n' % (self._oArgs.irc_chan, content)) self.irc_send(bytes(sMSG+' %s :%s\r\n' % (self._oArgs.irc_chan, content), 'UTF-8'))
def handle_command(self, cmd): def handle_command(self, cmd):
cmd = cmd[1:] cmd = cmd[1:]
@ -1155,8 +1184,10 @@ def oArgparse(lArgv):
parser.add_argument('--irc_cadir', type=str, parser.add_argument('--irc_cadir', type=str,
help="Certificate Authority directory", help="Certificate Authority directory",
default=CAcs[0]) default=CAcs[0])
parser.add_argument('--irc_pem', type=str, default='', parser.add_argument('--irc_crt', type=str, default='',
help="Certificate and key as pem; use openssl req -x509 -nodes -newkey rsa:2048") help="Certificate as pem; use openssl req -x509 -nodes -newkey rsa:2048")
parser.add_argument('--irc_key', type=str, default='',
help="Key as pem; use openssl req -x509 -nodes -newkey rsa:2048")
parser.add_argument('--irc_fp', type=str, default='', parser.add_argument('--irc_fp', type=str, default='',
help="fingerprint of the pem added with CERT ADD; use openssl x509 -noout -fingerprint -SHA1 -text") help="fingerprint of the pem added with CERT ADD; use openssl x509 -noout -fingerprint -SHA1 -text")
parser.add_argument('--irc_nick', type=str, default='', parser.add_argument('--irc_nick', type=str, default='',
@ -1210,6 +1241,9 @@ def main(lArgs=None):
if lArgs is None: lArgs = [] if lArgs is None: lArgs = []
global oTOX_OARGS global oTOX_OARGS
oTOX_OARGS = oArgparse(lArgs) oTOX_OARGS = oArgparse(lArgs)
ts.clean_booleans(oTOX_OARGS)
assert oTOX_OARGS.irc_host or oTOX_OARGS.irc_connect assert oTOX_OARGS.irc_host or oTOX_OARGS.irc_connect
if not oTOX_OARGS.irc_connect: if not oTOX_OARGS.irc_connect:
oTOX_OARGS.irc_connect = oTOX_OARGS.irc_host oTOX_OARGS.irc_connect = oTOX_OARGS.irc_host
@ -1217,8 +1251,10 @@ def main(lArgs=None):
assert os.path.isdir(oTOX_OARGS.irc_cadir) assert os.path.isdir(oTOX_OARGS.irc_cadir)
if oTOX_OARGS.irc_cafile: if oTOX_OARGS.irc_cafile:
assert os.path.isfile(oTOX_OARGS.irc_cafile) assert os.path.isfile(oTOX_OARGS.irc_cafile)
global oTOX_OPTIONS global oTOX_OPTIONS
oTOX_OPTIONS = oToxygenToxOptions(oTOX_OARGS) oTOX_OPTIONS = oToxygenToxOptions(oTOX_OARGS)
ts.vSetupLogging(oTOX_OARGS) ts.vSetupLogging(oTOX_OARGS)
# ts.setup_logging(oArgs) # ts.setup_logging(oArgs)

View File

@ -5,6 +5,15 @@
#export TOXCORE_LIBS=/mnt/linuxPen19/var/local/src/c-toxcore/_build #export TOXCORE_LIBS=/mnt/linuxPen19/var/local/src/c-toxcore/_build
export TOXCORE_LIBS=/mnt/o/var/local/src/tox_profile/libs export TOXCORE_LIBS=/mnt/o/var/local/src/tox_profile/libs
export PYTHONPATH=/mnt/o/var/local/src/toxygen_wrapper.git/ export PYTHONPATH=/mnt/o/var/local/src/toxygen_wrapper.git/
export https_proxy=
export http_proxy=
SOCKS_HOST=127.0.0.1
SOCKS_PORT=9050
NMAP_ARGS="-Pn --script ssl-enum-ciphers --proxies socks4://${SOCKS_HOST}:$SOCKS_PORT --reason"
CURL_ARGS="-vvvvv --cacert /etc/ssl/cacert-testforge.pem"
CURL_ARGS="$CURL_ARGS -x socks5h://${SOCKS_HOST}:$SOCKS_PORT"
CURL_ARGS="$CURL_ARGS --interface lo --dns-interface lo"
[ -f /usr/local/bin/usr_local_tput.bash ] && \ [ -f /usr/local/bin/usr_local_tput.bash ] && \
. /usr/local/bin/usr_local_tput.bash || { . /usr/local/bin/usr_local_tput.bash || {
@ -14,59 +23,120 @@ export PYTHONPATH=/mnt/o/var/local/src/toxygen_wrapper.git/
ERROR() { echo ERROR $* ; } ERROR() { echo ERROR $* ; }
} }
if true; then
HOST=irc.oftc.net HOST=irc.oftc.net
IRC_PORT=6667 IRC_PORT=6667
IRCS_PORT=6697 IRCS_PORT=6697
ONION=oftcnet6xg6roj6d7id4y4cu6dchysacqj2ldgea73qzdagufflqxrid.onion ONION=oftcnet6xg6roj6d7id4y4cu6dchysacqj2ldgea73qzdagufflqxrid.onion
NICK=SyniTox
TLS=3
PEM=$HOME/.config/ssl/$HOST/SyniTox.pem
CRT=$HOME/.config/ssl/$HOST/SyniTox.crt
KEY=$HOME/.config/ssl/$HOST/SyniTox.key
FP=$HOME/.config/ssl/$HOST/SyniTox.fp
else
HOST=libera.chat
IRC_PORT=
IRCS_PORT=6697
ONION=libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion
NICK=SyniTox
PEM=$HOME/.config/ssl/$HOST/SyniTox.pem
KEY=$HOME/.config/ssl/$HOST/SyniTox.key
CRT=$HOME/.config/ssl/$HOST/SyniTox.crt
FP=$HOME/.config/ssl/$HOST/SyniTox.fp
TLS=3
fi
TLS=0 function check_nmap() {
local retval=$1
local hfile=$2
local tag=$3
INFO $retval $hfile $tag
if ! grep /tcp $hfile ; then
ERROR check_nmap no /tcp in $hfile
return 1
# whats filtered?
elif grep '/tcp *filtered' $hfile ; then
WARN check_nmap filtered $hfile
return 2
# whats filtered?
elif grep '/tcp *open' $hfile ; then
return 0
fi
return 0
}
function check_curl() {
local retval=$1
local hfile=$2
local tag=$3
# curl: (1) Received HTTP/0.9 when not allowed
if grep "SSL_ERROR_SYSCALL" $hfile ; then
ERROR curl $tag SSL_ERROR_SYSCALL $hfile
return 2
elif ! grep "SSL connection using TLSv1" $hfile ; then
WARN check_curl curl $tag no ciphers $hfile
elif ! grep "SSL connection using TLSv1.[3$TLS]" $hfile ; then
WARN check_curl curl $tag no TLS connection in $hfile
elif [ $TLS -eq 3 ] && grep "SSL connection using TLSv1.[2]" $hfile ; then
WARN check_curl protocol downgrade attack '?' no TLSv1.3 ciphers from $HOST
elif [ $retval -gt 1 ] ; then
grep "$IRCS_PORT/" $hfile
WARN check_curl curl $tag not OK $retval $hfile
else
INFO curl $tag OK $hfile
return 0
fi
return 1
}
a=`openssl ciphers -s -v|grep -c v1.3` a=`openssl ciphers -s -v|grep -c v1.3`
if [ "$a" -lt 3 ] ; then if [ "$a" -lt 3 ] ; then
WARN no SSSL TLSv1.3 ciphers available to the client. WARN no SSL TLSv1.3 ciphers available to the client.
TLS=2
elif nmap --script ssl-enum-ciphers --proxies socks4://127.0.0.1:9050 -p $IRCS_PORT $HOST | grep -q 'TLSv1.3:' ; then
TLS=3
else
TLS=2 TLS=2
fi fi
TLS=3 [ $TLS = 2 ] && CURL_ARGS="$CURL_ARGS --tlsv1.2"
[ $TLS = 3 ] && CURL_ARGS="$CURL_ARGS --tlsv1.3"
NICK=emdee
if [ "$TLS" -ne 0 ] ; then if [ "$TLS" -ne 0 ] ; then
SD=$HOME/.config/ssl/$HOST SD=$HOME/.config/ssl/$HOST
[ -d $SD ] || mkdir -p $SD || exit 2 [ -d $SD ] || mkdir -p $SD || exit 2
if [ ! -s $SD/$nick.key ] ; then if [ ! -s $SD/$NICK.key ] ; then
# ed25519 # ed25519
openssl req -x509 -nodes -newkey rsa:2048 \ openssl req -x509 -nodes -newkey rsa:2048 \
-keyout $SD/$nick.key \ -keyout $SD/$NICK.key \
-days 3650 -out $SD/$nick.crt || exit 3 -days 3650 -out $SD/$NICK.crt || exit 3
chmod 400 $SD/$nick.key chmod 400 $SD/$NICK.key
fi fi
if [ ! -s $SD/$nick.fp ] ; then if [ ! -s $SD/$NICK.fp ] ; then
openssl x509 -noout -fingerprint -SHA1 -text \ openssl x509 -noout -fingerprint -SHA1 -text \
< $SD/$nick.crt > $SD/$nick.fp || exit 4 < $SD/$NICK.crt > $SD/$NICK.fp || exit 4
fi fi
if [ ! -s $SD/$nick.pem ] ; then if [ ! -s $SD/$NICK.pem ] ; then
cat $SD/$nick.crt $SD/$nick.key > $SD/$nick.pem cat $SD/$NICK.crt $SD/$NICK.key > $SD/$NICK.pem
chmod 400 $SD/$nick.pem || exit 5 chmod 400 $SD/$NICK.pem || exit 5
fi fi
ls -l -s $SD/$nick.pem ls -l -s $SD/$NICK.pem
fi fi
exit 0
curl -vvvvv --cacert /etc/ssl/cacert-testforge.pem \
--cert ~/.config/ssl/$HOST/SyniTox.pem \
https://$HOST:$IRCS_PORT \
2>&1| grep "SSL connection using TLSv1.$TLS"
[ $? -gt 0 ] && WARN curl not OK
declare -a RARGS declare -a RARGS
RARGS=( if [ "$DEBUG" = 1 ] ; then
--log_level 10 RARGS=(
) --log_level 10
)
else
RARGS=(
--log_level 20
)
fi
[ -n "$socks_proxy" ] && \ [ -n "$socks_proxy" ] && \
RARGS+=( RARGS+=(
--proxy_type 2 --proxy_type 2
--proxy_port 9050 --proxy_port 9050
--proxy_host 127.0.0.1 --proxy_host ${SOCKS_HOST}
--trace_enabled True
) )
declare -a LARGS declare -a LARGS
LARGS=( LARGS=(
@ -75,17 +145,32 @@ LARGS=(
--irc_ssl "" --irc_ssl ""
--irc_ident SyniTox --irc_ident SyniTox
--irc_name SyniTox --irc_name SyniTox
--irc_nick SyniTox --irc_nick $NICK
) )
DBUG $?
if [ $# -eq 0 -o "$1" = 1 ] ; then if [ $# -eq 0 -o "$1" = 1 ] && [ -n "$IRC_PORT" ] ; then
INFO No SSL INFO No SSL
python3 tox-irc-sync.py "${LARGS[@]}" "${RARGS[@]}" "$@" python3 tox-irc-sync.py "${LARGS[@]}" "${RARGS[@]}"
DBUG $? DBUG $?
fi fi
CIPHER_DOWNGRADE_OVER_TOR=" CIPHER_DOWNGRADE_OVER_TOR_LIBERA="Other addresses for libera.chat (not scanned): (null)
rDNS record for 130.239.18.116: solenoid.acc.umu.se
PORT STATE SERVICE
6697/tcp open ircs-u
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
| compressors:
| cipher preference: indeterminate
| cipher preference error: Too few ciphers supported
|_ least strength: A
'
"
CIPHER_DOWNGRADE_OVER_TOR_OFTC="
Nmap scan report for $HOST (130.239.18.116) Nmap scan report for $HOST (130.239.18.116)
Host is up (0.26s latency). Host is up (0.26s latency).
@ -112,37 +197,71 @@ LARGS=(
--irc_name SyniTox --irc_name SyniTox
--irc_nick SyniTox --irc_nick SyniTox
--irc_pass password --irc_pass password
--irc_pem $HOME/.config/ssl/$HOST/SyniTox.pem --irc_crt "$CRT"
--irc_key "$KEY"
# E178E7B9BD9E540278118193AD2C84DEF9B35E85 # E178E7B9BD9E540278118193AD2C84DEF9B35E85
--irc_fp $HOME/.config/ssl/$HOST/SyniTox.fp --irc_fp "$FP"
--irc_cafile /usr/local/etc/ssl/cacert-testforge.pem --irc_cafile /usr/local/etc/ssl/cacert-testforge.pem
) )
if [ $# -eq 0 -o "$1" = 2 ] ; then
INFO SSL v1.$TLS
python3 tox-irc-sync.py "${LARGS[@]}" "${RARGS[@]}" "$@"
DBUG $?
fi
ip=$ONION
if [ $# -eq 0 -o "$1" = 3 ] ; then
nmap --script ssl-enum-ciphers --proxies socks4://127.0.0.1:9050 -p $IRCS_PORT $ip
INFO Onion v1.$TLS
python3 tox-irc-sync.py "${LARGS[@]}" --irc_connect $ip "${RARGS[@]}" "$@"
DBUG $?
fi
ip=`tor-resolve -4 $ONION` ip=`tor-resolve -4 $ONION`
if [ $? -eq 0 -a -n "$ip" ] && [ $# -eq 0 -o "$1" = 4 ] ; then if [ -n "$ip" ] ; then
curl -vvvvv --cacert /etc/ssl/cacert-testforge.pem \ curl $CURL_ARGS \
--cert ~/.config/ssl/$HOST/SyniTox.pem \ --connect-to $ip:$IRCS_PORT \
--connect-to $ip:$IRCS_PORT \ https://$HOST:$IRCS_PORT \
https://$HOST:$IRCS_PORT \ > /tmp/TIS$$.curl 2>&1
2>&1| grep "SSL connection using TLSv1.$TLS" check_curl $? /tmp/TIS$$.curl ""
else
ERROR tor-resolve failed
exit 6
fi
[ $? -gt 0 ] && WARN curl not OK if [ $# -eq 0 -o "$1" = 2 -a $HOST = libera.chat ] ; then
nmap --script ssl-enum-ciphers --proxies socks4://127.0.0.1:9050 -p $IRCS_PORT $ip ERROR $HOST rejects tor
INFO IP $ip elif [ $# -eq 0 -o "$1" = 2 ] ; then
python3 tox-irc-sync.py "${LARGS[@]}" --irc_connect $ip "${RARGS[@]}" "$@" INFO SSL v1.$TLS
python3 tox-irc-sync.py "${LARGS[@]}" "${RARGS[@]}"
DBUG $?
fi
if [ -n "$ip" ] ; then
[ -n "$PEM" -a -f "$PEM" ] || { ERROR NO $PEM ; exit 7 ; }
ls -l $PEM || exit 7
INFO curl $CURL_ARGS \
--cert-type PEM \
--cert $PEM \
--connect-to $ip:$IRCS_PORT \
https://$HOST:$IRCS_PORT
curl $CURL_ARGS \
--cert-type PEM \
--cert $PEM \
--connect-to $ip:$IRCS_PORT \
https://$HOST:$IRCS_PORT \
> /tmp/TIS$$.cert 2>&1
check_curl $? /tmp/TIS$$.cert "--connect-to"
else
ERROR tor-resolve failed
exit 8
fi
if [ $# -eq 0 -o "$1" = 3 ] ; then
[ -n "$PEM" -a -f "$PEM" ] || { ERROR NO $PEM ; exit 7 ; }
nmap $NMAP_ARGS -p $IRCS_PORT $ip > /tmp/TIS$$.nmap 2>&1
check_nmap $? /tmp/TIS$$.nmap $1
INFO Onion v1.$TLS
python3 tox-irc-sync.py "${LARGS[@]}" --irc_connect $ONION "${RARGS[@]}"
DBUG $?
fi
if [ $? -eq 0 ] && [ $# -eq 0 -o "$1" = 4 ] ; then
[ -n "$PEM" -a -f "$PEM" ] || { ERROR NO $PEM ; exit 7 ; }
nmap $NMAP_ARGS -p $IRCS_PORT $ip > /tmp/TIS$$.nmap 2>&1
check_nmap $? /tmp/TIS$$.nmap $1
INFO Onion v1.$TLS IP $ip
python3 tox-irc-sync.py "${LARGS[@]}" --irc_connect $ip "${RARGS[@]}"
DBUG $? DBUG $?
fi fi