Compare commits

...

10 commits

Author SHA1 Message Date
emdee
f83d1c97b9 pep8 2022-11-17 12:08:38 +00:00
emdee
f30a1038ad Works 2022-11-06 03:57:13 +00:00
emdee
6f73f766ac Fixed TLS1.3 2022-11-03 05:31:50 +00:00
emdee
5ff9bd0680 SSL 1.3 maybe 2022-11-03 02:51:14 +00:00
emdee
3e093a1a41 SSL work 2022-11-02 08:18:52 +00:00
emdee
04985b1fb2 Stem 2022-10-29 18:44:37 +00:00
emdee
354f4eceb2 Added more groups support 2022-10-26 09:13:01 +00:00
emdee
1e574520b0 Extended groups code 2022-10-26 08:44:57 +00:00
emdee
0928ef551d Added SSL 2022-10-24 07:51:19 +00:00
emdee
3882fe2ec9 First refactor 2022-10-23 22:11:12 +00:00
3 changed files with 1591 additions and 157 deletions

157
README.md
View file

@ -1,3 +1,156 @@
#Tox-Sync
# Tox-Sync
A bot that sync messages between IRC and Tox NGC group chat.
## Hard Forked
Hard forked from <https://github.com/aitjcize/tox-irc-sync>
and changed to use the Python wrapping from
<https://git.plastiras.org/emdee/toxygen_wrapper>.
Just clone that repo and put the resulting directory on your
```PYTHONPATH```.
## Usage
Run: ```tox-irc-sync.py --help``` for command line arguments.
```
python3 tox-irc-sync.py \
[-h] [--proxy_host PROXY_HOST]
[--proxy_port PROXY_PORT]
[--proxy_type {0,1,2}]
[--udp_enabled {True,False}]
[--ipv6_enabled {True,False}]
[--download_nodes_list {True,False}]
[--nodes_json NODES_JSON]
[--download_nodes_url DOWNLOAD_NODES_URL]
[--logfile LOGFILE]
[--loglevel LOGLEVEL]
[--tcp_port TCP_PORT]
[--mode MODE]
[--sleep {qt,gevent,time}]
[--irc_host IRC_HOST]
[--irc_port IRC_PORT]
[--irc_chan IRC_CHAN]
[--irc_ssl {,tls1.2,tls1.3}]
[--irc_ca IRC_CA]
[--irc_pem IRC_PEM]
[--irc_fp IRC_FP]
[--irc_nick IRC_NICK]
[--irc_name IRC_NAME]
[--irc_ident IRC_IDENT]
[--irc_pass IRC_PASS]
[--irc_email IRC_EMAIL]
[--group_pass GROUP_PASS]
[--group_name GROUP_NAME]
[--group_nick GROUP_NICK]
[--group_invite GROUP_INVITE]
[--group_moderator GROUP_MODERATOR]
[--group_ignore GROUP_IGNORE]
[profile]
```
### Positional arguments
```
profile Path to Tox profile - new groups will be saved there
```
### Optional Arguments:
```
-h, --help show this help message and exit
--proxy_host PROXY_HOST, --proxy-host PROXY_HOST
proxy host
--proxy_port PROXY_PORT, --proxy-port PROXY_PORT
proxy port
--proxy_type {0,1,2}, --proxy-type {0,1,2}
proxy type 1=http, 2=socks
--udp_enabled {True,False}
En/Disable udp
--ipv6_enabled {False,False}
En/Disable ipv6 - default False
--tcp_port TCP_PORT, --tcp-port TCP_PORT for serving as a Tox relay
--mode MODE Mode: 0=chat 1=chat+audio 2=chat+audio+video default:0
--nodes_json NODES_JSON --network {old,main,local}
--download_nodes_url DOWNLOAD_NODES_URL
--download_nodes_list {True,False}
Download nodes list
--logfile LOGFILE Filename for logging
--loglevel LOGLEVEL Threshold for logging (lower is more) default: 20
--irc_host IRC_HOST irc.libera.chat will not work over Tor
--irc_port IRC_PORT default 6667, but may be 6697 with SSL
--irc_chan IRC_CHAN IRC channel to join - include the #
--irc_ssl {,tls1.2,tls1.3} TLS version; empty is no SSL
--irc_ca IRC_CA Certificate Authority file or directory
--irc_pem IRC_PEM Certificate and key as pem; use
openssl req -x509 -nodes -newkey rsa:2048
--irc_fp IRC_FP fingerprint of the pem added with CERT ADD; use
openssl x509 -noout -fingerprint -SHA1 -text
--irc_nick IRC_NICK IRC Nickname
--irc_ident IRC_IDENT First field in USER
--irc_name IRC_NAME Third field in USER
--irc_pass IRC_PASS password for INDENTIFY or REGISTER
--irc_email IRC_EMAIL Use email to REGISTER with _pass
--group_pass GROUP_PASS password for the group
--group_name GROUP_NAME name for the group
--group_nick GROUP_NICK Nickname of the group founder
--group_invite GROUP_INVITE A PK to invite to the group
--group_moderator GROUP_MODERATOR A PK to invite to the group as moderator
--group_ignore GROUP_IGNORE A PK to ignore by the group
```
### Examples
The general idea here is to use this to create a profile,
and that profile will have one user, and one group to start with.
That profile will contain the founders keypair for the group,
so protect the profile as it contains the group's secret key.
Then you use this profile to invite yourself to be a moderator,
by providing the your public key of the device you want to use to
moderate the group with the ```---group_moderator``` cmdline arg.
For the ```#tox``` group on ```libera.chat```:
```
python3 tox-irc-sync.py \
--nodes_json $HOME/.config/tox/DHTnodes.json \
--irc_chan "#tox" --irc_host irc.libera.net --irc_port 6667 \
profile_that_will_get_the_group_key.tox
```
Libera will not work over Tor, but ```irc.oftc.net#tor``` will:
```
python3 tox-irc-sync.py \
--nodes_json $HOME/.config/tox/DHTnodes.json \
--irc_chan "#tor" --irc_host irc.oftc.net --irc_port 6667 \
--proxy_type 2 --proxy_host 127.0.0.1 --proxy_port 9050 \
profile_that_will_get_the_group_key.tox
```
* OFTC has an Onion address:
```ircs://oftcnet6xg6roj6d7id4y4cu6dchysacqj2ldgea73qzdagufflqxrid.onion:6697```
* Libera has an Onion address:
```libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion```
## ChangeLog
* changed to use the Python wrapping from <https://git.plastiras.org/emdee/toxygen_wrapper>
* ```tox_irc_sync``` does SSL now.
### Future Directions
1. It's intended as a IRC->Tox NGC gateway but it could work the other way round.
2. It could be a plugin under <https://git.plastiras.org/emdee/toxygen>
which would broaden the range of callbacks that could be supported.
3. It could be a gateway to an existing NGC group with an invite bot.
A bot that sync messages between Freenode IRC #tox-ontopic and Tox group chat.

File diff suppressed because it is too large Load diff

266
tox-irc-sync_test.bash Normal file
View file

@ -0,0 +1,266 @@
#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
#export LD_LIBRARY_PATH=/usr/local/lib
#export TOXCORE_LIBS=/mnt/linuxPen19/var/local/src/c-toxcore/_build
export TOXCORE_LIBS=/mnt/o/var/local/src/tox_profile/libs
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 ] && \
. /usr/local/bin/usr_local_tput.bash || {
DBUG() { echo DEBUG $* ; }
INFO() { echo INFO $* ; }
WARN() { echo WARN $* ; }
ERROR() { echo ERROR $* ; }
}
if true; then
HOST=irc.oftc.net
IRC_PORT=6667
IRCS_PORT=6697
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
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`
if [ "$a" -lt 3 ] ; then
WARN no SSL TLSv1.3 ciphers available to the client.
TLS=2
fi
[ $TLS = 2 ] && CURL_ARGS="$CURL_ARGS --tlsv1.2"
[ $TLS = 3 ] && CURL_ARGS="$CURL_ARGS --tlsv1.3"
NICK=emdee
if [ "$TLS" -ne 0 ] ; then
SD=$HOME/.config/ssl/$HOST
[ -d $SD ] || mkdir -p $SD || exit 2
if [ ! -s $SD/$NICK.key ] ; then
# ed25519
openssl req -x509 -nodes -newkey rsa:2048 \
-keyout $SD/$NICK.key \
-days 3650 -out $SD/$NICK.crt || exit 3
chmod 400 $SD/$NICK.key
fi
if [ ! -s $SD/$NICK.fp ] ; then
openssl x509 -noout -fingerprint -SHA1 -text \
< $SD/$NICK.crt > $SD/$NICK.fp || exit 4
fi
if [ ! -s $SD/$NICK.pem ] ; then
cat $SD/$NICK.crt $SD/$NICK.key > $SD/$NICK.pem
chmod 400 $SD/$NICK.pem || exit 5
fi
ls -l -s $SD/$NICK.pem
fi
declare -a RARGS
if [ "$DEBUG" = 1 ] ; then
RARGS=(
--log_level 10
)
else
RARGS=(
--log_level 20
)
fi
[ -n "$socks_proxy" ] && \
RARGS+=(
--proxy_type 2
--proxy_port 9050
--proxy_host ${SOCKS_HOST}
--trace_enabled True
)
declare -a LARGS
LARGS=(
--irc_host $HOST
--irc_port $IRC_PORT
--irc_ssl ""
--irc_ident SyniTox
--irc_name SyniTox
--irc_nick $NICK
)
if [ $# -eq 0 -o "$1" = 1 ] && [ -n "$IRC_PORT" ] ; then
INFO No SSL
python3 tox-irc-sync.py "${LARGS[@]}" "${RARGS[@]}"
DBUG $?
fi
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)
Host is up (0.26s latency).
Other addresses for $HOST (not scanned): (null)
rDNS record for 130.239.18.116: solenoid.acc.umu.se
PORT STATE SERVICE
$IRCS_PORT/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
"
# I know that site does v1.3 3 ciphers
LARGS=(
--irc_host $HOST
--irc_port $IRCS_PORT
--irc_ssl tlsv1.$TLS
--irc_ident SyniTox
--irc_name SyniTox
--irc_nick SyniTox
--irc_pass password
--irc_crt "$CRT"
--irc_key "$KEY"
# E178E7B9BD9E540278118193AD2C84DEF9B35E85
--irc_fp "$FP"
--irc_cafile /usr/local/etc/ssl/cacert-testforge.pem
)
ip=`tor-resolve -4 $ONION`
if [ -n "$ip" ] ; then
curl $CURL_ARGS \
--connect-to $ip:$IRCS_PORT \
https://$HOST:$IRCS_PORT \
> /tmp/TIS$$.curl 2>&1
check_curl $? /tmp/TIS$$.curl ""
else
ERROR tor-resolve failed
exit 6
fi
if [ $# -eq 0 -o "$1" = 2 -a $HOST = libera.chat ] ; then
ERROR $HOST rejects tor
elif [ $# -eq 0 -o "$1" = 2 ] ; then
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 $?
fi