diff --git a/Makefile b/Makefile index abb09ff..9c55ae6 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,10 @@ CFLAGS += '-DPACKAGE_DATADIR="$(abspath $(DATADIR))"' CFLAGS += $(USER_CFLAGS) LDFLAGS = $(USER_LDFLAGS) -OBJ = chat.o chat_commands.o configdir.o execute.o file_transfers.o notify.o -OBJ += friendlist.o global_commands.o groupchat.o line_info.o input.o help.o autocomplete.o -OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o message_queue.o -OBJ += group_commands.o term_mplex.o avatars.o name_lookup.o qr_code.o bootstrap.o +OBJ = autocomplete.o avatars.o bootstrap.o chat.o chat_commands.o configdir.o curl_util.o execute.o +OBJ += file_transfers.o friendlist.o global_commands.o group_commands.o groupchat.o help.o input.o +OBJ += line_info.o log.o message_queue.o misc_tools.o name_lookup.o notify.o prompt.o qr_code.o settings.o +OBJ += term_mplex.o toxic.o toxic_strings.o windows.o # Check on wich system we are running UNAME_S = $(shell uname -s) diff --git a/cfg/global_vars.mk b/cfg/global_vars.mk index 2fa9723..0503b90 100644 --- a/cfg/global_vars.mk +++ b/cfg/global_vars.mk @@ -16,7 +16,7 @@ MISC_DIR = $(BASE_DIR)/misc # Project files MANFILES = toxic.1 toxic.conf.5 -DATAFILES = DHTnodes nameservers toxic.conf.example +DATAFILES = nameservers toxic.conf.example DESKFILE = toxic.desktop SNDFILES = ToxicContactOnline.wav ToxicContactOffline.wav ToxicError.wav SNDFILES += ToxicRecvMessage.wav ToxicOutgoingCall.wav ToxicIncomingCall.wav diff --git a/doc/toxic.1 b/doc/toxic.1 index 9878cb1..a5c72eb 100644 --- a/doc/toxic.1 +++ b/doc/toxic.1 @@ -2,12 +2,12 @@ .\" Title: toxic .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 2015-12-07 +.\" Date: 2016-04-25 .\" Manual: Toxic Manual .\" Source: toxic __VERSION__ .\" Language: English .\" -.TH "TOXIC" "1" "2015\-12\-07" "toxic __VERSION__" "Toxic Manual" +.TH "TOXIC" "1" "2016\-04\-25" "toxic __VERSION__" "Toxic Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -82,8 +82,7 @@ Show help message .RS 4 Use specified \fInodes\-file\fR -for DHT bootstrap nodes, instead of -\fI__DATADIR__/DHTnodes\fR +for DHT bootstrap nodes, instead of the default .RE .PP \-o, \-\-noconnect @@ -122,9 +121,10 @@ Unencrypt a data file\&. A warning will appear if this option is used with a dat .RE .SH "FILES" .PP -__DATADIR__/DHTnodes +~/\&.config/tox/DHTnodes .RS 4 -Default list of DHT bootstrap nodes\&. +Default location for list of DHT bootstrap nodes (list obtained at +https://nodes\&.tox\&.chat)\&. This list is automatically updated every 30 days\&. .RE .PP ~/\&.config/tox/toxic_profile\&.tox diff --git a/doc/toxic.1.asc b/doc/toxic.1.asc index 20d3c00..b97af86 100644 --- a/doc/toxic.1.asc +++ b/doc/toxic.1.asc @@ -41,8 +41,7 @@ OPTIONS Show help message -n, --nodes nodes-file:: - Use specified 'nodes-file' for DHT bootstrap nodes, instead of - '{datadir}/DHTnodes' + Use specified 'nodes-file' for DHT bootstrap nodes, instead of the default -o, --noconnect:: Do not connect to the DHT network @@ -68,8 +67,9 @@ OPTIONS FILES ----- -{datadir}/DHTnodes:: - Default list of DHT bootstrap nodes. +~/.config/tox/DHTnodes:: + Default location for list of DHT bootstrap nodes (list obtained at https://nodes.tox.chat). + This list is automatically updated every 30 days. ~/.config/tox/toxic_profile.tox:: Savestate which contains your personal info (nickname, Tox ID, contacts, diff --git a/misc/DHTnodes b/misc/DHTnodes deleted file mode 100644 index bdaefc6..0000000 --- a/misc/DHTnodes +++ /dev/null @@ -1 +0,0 @@ -{"last_scan":1474137109,"nodes":[{"ipv4":"tox.zodiaclabs.org","ipv6":"v6.tox.zodiaclabs.org","port":33445,"tcp_ports":[33445,3389],"public_key":"A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074","maintainer":"stal","location":"US","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"I am the bone of my code;\nNIH is my body and str8c is my blood.\nI have overflowed a thousand buffers.\nUnknown to SIGSEGV, nor to abort();\nHave withstood pain to create fast programs;\nYet my code will always be unsafe.\nSo as I pray, rock solid straight C.","last_ping":1474137098},{"ipv4":"biribiri.org","ipv6":"-","port":33445,"tcp_ports":[33445,3389],"public_key":"F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67","maintainer":"nurupo","location":"US","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Welcome, stranger #3783. I'm up for 1d 14h 23m 12s, running since Sep 16 04:08:25 UTC. If I get outdated, please ping my maintainer at nurupo.contributions@gmail.com","last_ping":1474137098},{"ipv4":"178.62.250.138","ipv6":"2a03:b0c0:2:d0::16:1","port":33445,"tcp_ports":[3389,33445],"public_key":"788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B","maintainer":"Impyy","location":"NL","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Impy's kickin' bootstrap node","last_ping":1474137097},{"ipv4":"130.133.110.14","ipv6":"2001:6f8:1c3c:babe::14:1","port":33445,"tcp_ports":[33445],"public_key":"461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F","maintainer":"Manolis","location":"DE","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Spline tox bootstrap node","last_ping":1474137101},{"ipv4":"205.185.116.116","ipv6":"-","port":33445,"tcp_ports":[3389,33445],"public_key":"A179B09749AC826FF01F37A9613F6B57118AE014D4196A0E1105A98F93A54702","maintainer":"Busindre","location":"US","status_udp":true,"status_tcp":true,"version":"2014101200","motd":"tox-bootstrapd","last_ping":1474137098},{"ipv4":"198.98.51.198","ipv6":"2605:6400:1:fed5:22:45af:ec10:f329","port":33445,"tcp_ports":[33445,3389,443],"public_key":"1D5A5F2F5D6233058BF0259B09622FB40B482E4FA0931EB8FD3AB8E7BF7DAF6F","maintainer":"Busindre","location":"US","status_udp":true,"status_tcp":true,"version":"2014101200","motd":"tox-bootstrapd","last_ping":1474137098},{"ipv4":"139.162.217.110","ipv6":"-","port":33445,"tcp_ports":[33445,3389],"public_key":"0EEBE6304F4B3F6549F39A87FBB45751929F4833BA6AC5F35B6DFA79D01B4523","maintainer":"Kr9r0x","location":"GB","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-bootstrapd","last_ping":1474137097},{"ipv4":"194.249.212.109","ipv6":"2001:1470:fbfe::109","port":33445,"tcp_ports":[3389,443,33445],"public_key":"3CEE1F054081E7A011234883BC4FC39F661A55B73637A5AC293DDF1251D9432B","maintainer":"fluke571","location":"SI","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-bootstrapd","last_ping":1474137098},{"ipv4":"185.25.116.107","ipv6":"2a00:7a60:0:746b::3","port":33445,"tcp_ports":[33445,3389],"public_key":"DA4E4ED4B697F2E9B000EEFE3A34B554ACD3F45F5C96EAEA2516DD7FF9AF7B43","maintainer":"MAH69K","location":"UA","status_udp":true,"status_tcp":true,"version":"","motd":"","last_ping":1474137102},{"ipv4":"192.99.168.140","ipv6":"-","port":33445,"tcp_ports":[33445,3389],"public_key":"6A4D0607A296838434A6A7DDF99F50EF9D60A2C510BBF31FE538A25CB6B4652F","maintainer":"WIeschie","location":"CA","status_udp":true,"status_tcp":true,"version":"2014101200","motd":"tox-bootstrapd","last_ping":1474137098},{"ipv4":"95.215.46.114","ipv6":"2a02:7aa0:1619::bdbd:17b8","port":33445,"tcp_ports":[33445,3389],"public_key":"5823FB947FF24CF83DDFAC3F3BAA18F96EA2018B16CC08429CB97FA502F40C23","maintainer":"Rotkaermota","location":"SE","status_udp":true,"status_tcp":true,"version":"","motd":"","last_ping":1474137102},{"ipv4":"5.189.176.217","ipv6":"2a02:c200:1:10:3:1:605:1337","port":5190,"tcp_ports":[33445,5190,3389],"public_key":"2B2137E094F743AC8BD44652C55F41DFACC502F125E99E4FE24D40537489E32F","maintainer":"tastytea","location":"DE","status_udp":true,"status_tcp":true,"version":"","motd":"","last_ping":1474137101},{"ipv4":"148.251.23.146","ipv6":"2a01:4f8:201:8493::2","port":2306,"tcp_ports":[33445,2306],"public_key":"7AED21F94D82B05774F697B209628CD5A9AD17E0C073D9329076A4C28ED28147","maintainer":"pucetox","location":"DE","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"by pucetox,\n sync your nodes here tox.0x10k.com/bootstrapd-conf , \n for communication: 1D1C0B992DEB6D7F18561176F7F5E572BCC7F2BA5CFA7E9E437B9134122CE96D906A6119F9D2","last_ping":1474137097},{"ipv4":"104.223.122.15","ipv6":"2607:ff48:aa81:800::35eb:1","port":33445,"tcp_ports":[3389,33445],"public_key":"0FB96EEBFB1650DDB52E70CF773DDFCABE25A95CC3BB50FC251082E4B63EF82A","maintainer":"ru_maniac","location":"US","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox id for queries and general info: EBD2A7B649ABB10ED9F47E5113F04000F39D46F087CEB62FCCE1069471FD6915256D197F2A97","last_ping":1474137098},{"ipv4":"tox.verdict.gg","ipv6":"-","port":33445,"tcp_ports":[33445,3389],"public_key":"1C5293AEF2114717547B39DA8EA6F1E331E5E358B35F9B6B5F19317911C5F976","maintainer":"Deliran","location":"DE","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Since 2015","last_ping":1474137098},{"ipv4":"d4rk4.ru","ipv6":"-","port":1813,"tcp_ports":[1813],"public_key":"53737F6D47FA6BD2808F378E339AF45BF86F39B64E79D6D491C53A1D522E7039","maintainer":"D4rk4","location":"RU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"TOX ID: 35EDC07AEB18B163E07EE33F6CDDA63969F394FF6A617CEAB22A7EBBEAAAF854C0EDFBD46898","last_ping":1474137102},{"ipv4":"81.4.110.149","ipv6":"2a00:d880:3:2::8bdc:f19","port":33445,"tcp_ports":[33445,3389],"public_key":"9E7BD4793FFECA7F32238FA2361040C09025ED3333744483CA6F3039BFF0211E","maintainer":"tibietigni","location":"NL","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Tibietigni.com node. Tox_id for communication: D36CC0B702621F48FDBC540A57124A744E5133C932E65ACCEBCABF2586A02455171717175989","last_ping":1474137097},{"ipv4":"95.31.20.151","ipv6":"-","port":33445,"tcp_ports":[3389],"public_key":"9CA69BB74DE7C056D1CC6B16AB8A0A38725C0349D187D8996766958584D39340","maintainer":"IgorNovgorodov","location":"RU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"happy-new-year","last_ping":1474137101},{"ipv4":"51.254.84.212","ipv6":"2001:41d0:a:1a3b::18","port":33445,"tcp_ports":[3389,33445],"public_key":"AEC204B9A4501412D5F0BB67D9C81B5DB3EE6ADA64122D32A3E9B093D544327D","maintainer":"a68366","location":"FR","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Since 26.12.2015","last_ping":1474137097},{"ipv4":"5.135.59.163","ipv6":"-","port":33445,"tcp_ports":[3389,33445],"public_key":"2D320F971EF2CA18004416C2AAE7BA52BF7949DB34EA8E2E21AF67BD367BE211","maintainer":"Skey","location":"FR","status_udp":true,"status_tcp":true,"version":"2014101200","motd":"tox-bootstrapd","last_ping":1474137097},{"ipv4":"185.58.206.164","ipv6":"2a02:f680:1:1100::3313","port":33445,"tcp_ports":[3389,33445],"public_key":"24156472041E5F220D1FA11D9DF32F7AD697D59845701CDD7BE7D1785EB9DB39","maintainer":"ru_maniac","location":"RU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"please note: running on iphy's fork!\nmore info on the matter: goo.gl/Gz5KhK \u0026 goo.gl/i2TZJr\n\ntox id for queries and general info: EBD2A7B649ABB10ED9F47E5113F04000F39D46F087CEB62FCCE1069471FD6915256D197F2A97","last_ping":1474137098},{"ipv4":"128.199.199.197","ipv6":"2400:6180:0:d0::17a:a001","port":33445,"tcp_ports":[3389,33445],"public_key":"B05C8869DBB4EDDD308F43C1A974A20A725A36EACCA123862FDE9945BF9D3E09","maintainer":"wiiaam","location":"SG","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"apt-get install antox","last_ping":1474137098},{"ipv4":"bootybay.club","ipv6":"-","port":33445,"tcp_ports":[3389,33445],"public_key":"0CB9D8D636F8E3D71CF44A3019408A846B7BEDFA2810853355DB58C0A36BFE38","maintainer":"AssPirate","location":"AU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-bootstrapd","last_ping":1474137098},{"ipv4":"91.121.66.124","ipv6":"2001:41d0:1:757c::1","port":33445,"tcp_ports":[33445],"public_key":"4E3F7D37295664BBD0741B6DBCB6431D6CD77FC4105338C2FC31567BF5C8224A","maintainer":"h4nt3r","location":"FR","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox id for queries and general info: 3BC3C6875508A2EC86BE3E35E4FA9155E444CFA96671AE7D7D0D2585A0A5FA38E071A5E463E5","last_ping":1474137097},{"ipv4":"195.93.190.6","ipv6":"2a01:d0:ffff:a8a::2","port":33445,"tcp_ports":[33445],"public_key":"FB4CE0DDEFEED45F26917053E5D24BDDA0FA0A3D83A672A9DA2375928B37023D","maintainer":"strngr","location":"UA","status_udp":true,"status_tcp":true,"version":"","motd":"","last_ping":1474137105},{"ipv4":"loki.uplinklabs.net","ipv6":"loki.uplinklabs.net","port":33445,"tcp_ports":[3389,33445],"public_key":"1A56EA3EDF5DF4C0AEABBF3C2E4E603890F87E983CAC8A0D532A335F2C6E3E1F","maintainer":"AbacusAvenger","location":"US","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-bootstrapd","last_ping":1474137098},{"ipv4":"95.215.44.78","ipv6":"2a02:7aa0:1619::c6fe:d0cb","port":33445,"tcp_ports":[33445,3389],"public_key":"672DBE27B4ADB9D5FB105A6BB648B2F8FDB89B3323486A7A21968316E012023C","maintainer":"HooinKyoma","location":"SE","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Thanx to Hooin Kyoma","last_ping":1474137098},{"ipv4":"tox.ntp.moscow","ipv6":"tox.ntp.moscow","port":33445,"tcp_ports":[33445,3389],"public_key":"80EF8660D9C5ACE1577BAB031375A0F08284CBFD9F810A857955DCC87377FC4D","maintainer":"abbat","location":"RU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-easy-bootstrap","last_ping":1474137098},{"ipv4":"146.185.136.123","ipv6":"2a03:b0c0:0:1010::389:1","port":33445,"tcp_ports":[33445,443,3389],"public_key":"09993FAF174DFFDC515B398A2EFC5639C4E6D7B736FC864F89786B50EAF88C1A","maintainer":"LittleVulpix","location":"NL","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"LittleTox - your friendly neighbourhood tox node from the land of windmills!","last_ping":1474137097},{"ipv4":"163.172.136.118","ipv6":"2001:bc8:4400:2100::1c:50f","port":33445,"tcp_ports":[33445,3389],"public_key":"2C289F9F37C20D09DA83565588BF496FAB3764853FA38141817A72E3F18ACA0B","maintainer":"LittleVulpix","location":"FR","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"LittleTox - your friendly neighbourhood tox node!","last_ping":1474137097},{"ipv4":"37.97.185.116","ipv6":"-","port":33445,"tcp_ports":[33445],"public_key":"E59A0E71ADA20D35BD1B0957059D7EF7E7792B3D680AE25C6F4DBBA09114D165","maintainer":"Yani","location":"NL","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Yani's node of pleasure and leisure","last_ping":1474137097},{"ipv4":"193.124.186.205","ipv6":"2a02:f680:1:1100::542a","port":5228,"tcp_ports":[443,3389,33445],"public_key":"9906D65F2A4751068A59D30505C5FC8AE1A95E0843AE9372EAFA3BAB6AC16C2C","maintainer":"Cactus","location":"RU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-bootstrapd","last_ping":1474137098},{"ipv4":"80.87.193.193","ipv6":"2a01:230:2:6::46a8","port":33445,"tcp_ports":[33445,3389],"public_key":"B38255EE4B054924F6D79A5E6E5889EC94B6ADF6FE9906F97A3D01E3D083223A","maintainer":"linxon","location":"RU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Free Linxon's TOX Bootstrap node","last_ping":1474137098},{"ipv4":"initramfs.io","ipv6":"-","port":33445,"tcp_ports":[33445,3389],"public_key":"3F0A45A268367C1BEA652F258C85F4A66DA76BCAA667A49E770BCC4917AB6A25","maintainer":"initramfs","location":"TW","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"initramfs' Tox DHT Node","last_ping":1474137099},{"ipv4":"tox.neverlocate.me","ipv6":"-","port":33445,"tcp_ports":[33445],"public_key":"49183DBF0E865713154069D1C7C7A2732ED78CF32C4D76AF5304FE31C5FEB81A","maintainer":"brandon","location":"US","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-bootstrapd","last_ping":1474137102},{"ipv4":"shigure.eve.moe","ipv6":"shigure.eve.moe","port":33445,"tcp_ports":[3389,33445],"public_key":"1A480A53FAF2CBBFCC382D786C43E69EEE23F22C7C23A7CFEB6180A373E23E54","maintainer":"EveNeko","location":"GB","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"tox-bootstrapd@shigure.eve.moe","last_ping":1474137098},{"ipv4":"tox.deadteam.org","ipv6":"tox.deadteam.org","port":33445,"tcp_ports":[33445],"public_key":"C7D284129E83877D63591F14B3F658D77FF9BA9BA7293AEB2BDFBFE1A803AF47","maintainer":"DeadTeam","location":"DE","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Vive le TOX","last_ping":1474137101},{"ipv4":"prok.pw","ipv6":"-","port":33445,"tcp_ports":[3389,33445],"public_key":"69C3FEBB977687B64FA0213BDEB89A43463BB48DED288150CFFB6429EFF82436","maintainer":"Prototik","location":"RU","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Have a nice chatting!","last_ping":1474137098},{"ipv4":"maggie.prok.pw","ipv6":"maggie.prok.pw","port":33445,"tcp_ports":[33445,3389],"public_key":"B75583B6D967DB8AD7C6D3B6F9318194BCC79B2FEF18F69E2DF275B779E7AA30","maintainer":"Prototik","location":"DE","status_udp":true,"status_tcp":true,"version":"2016010100","motd":"Maggie wants a pacifier","last_ping":1474137101},{"ipv4":"108.61.165.198","ipv6":"2001:19f0:5000:8121:5054:ff:fe1c:9ded","port":33445,"tcp_ports":[],"public_key":"8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832","maintainer":"ray65536","location":"NL","status_udp":true,"status_tcp":false,"version":"2016010100","motd":"Ray's Tox Node","last_ping":1474137101},{"ipv4":"92.54.84.70","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"5625A62618CB4FCA70E147A71B29695F38CC65FF0CBD68AD46254585BE564802","maintainer":"t3mp","location":"RU","status_udp":true,"status_tcp":false,"version":"2016010100","motd":"tox-bootstrapd","last_ping":1474137102},{"ipv4":"srv1.ricin.im","ipv6":"-","port":1337,"tcp_ports":[],"public_key":"3651DAB570D7F60381F87B19D6935EE7F5FE01308DCE71C4B69993150C6A903C","maintainer":"Ricin.im","location":"FR","status_udp":true,"status_tcp":false,"version":"2016010100","motd":"Ricin.im Tox node. Enjoy babes \u003c3","last_ping":1474137101},{"ipv4":"46.101.197.175","ipv6":"2a03:b0c0:3:d0::ac:5001","port":443,"tcp_ports":[443,33445,3389],"public_key":"CD133B521159541FB1D326DE9850F5E56A6C724B5B8E5EB5CD8D950408E95707","maintainer":"clearmartin","location":"DE","status_udp":false,"status_tcp":true,"version":"","motd":"","last_ping":1474137105},{"ipv4":"toxnode.nek0.net","ipv6":"toxnode.nek0.net","port":33445,"tcp_ports":[3389,33445],"public_key":"20965721D32CE50C3E837DD75B33908B33037E6225110BFF209277AEAF3F9639","maintainer":"Phsm","location":"UA","status_udp":false,"status_tcp":true,"version":"","motd":"","last_ping":1474137107},{"ipv4":"sorunome.de","ipv6":"sorunome.de","port":33445,"tcp_ports":[33445,3389],"public_key":"02807CF4F8BB8FB390CC3794BDF1E8449E9A8392C5D3F2200019DA9F1E812E46","maintainer":"Sorunome","location":"DE","status_udp":false,"status_tcp":true,"version":"","motd":"","last_ping":1474137105},{"ipv4":"hibiki.eve.moe","ipv6":"hibiki.eve.moe","port":33445,"tcp_ports":[33445],"public_key":"D3EB45181B343C2C222A5BCF72B760638E15ED87904625AAD351C594EEFAE03E","maintainer":"EveNeko","location":"US","status_udp":false,"status_tcp":true,"version":"","motd":"","last_ping":1474137098},{"ipv4":"46.229.52.198","ipv6":"-","port":33445,"tcp_ports":[33445],"public_key":"813C8F4187833EF0655B10F7752141A352248462A567529A38B6BBF73E979307","maintainer":"Stranger","location":"UA","status_udp":false,"status_tcp":true,"version":"","motd":"","last_ping":1474137109},{"ipv4":"144.76.60.215","ipv6":"2a01:4f8:191:64d6::1","port":33445,"tcp_ports":[],"public_key":"04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F","maintainer":"sonOfRa","location":"DE","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"195.154.119.113","ipv6":"2001:bc8:3698:101::1","port":33445,"tcp_ports":[],"public_key":"E398A69646B8CEACA9F0B84F553726C1C49270558C57DF5F3C368F05A7D71354","maintainer":"Munrek","location":"FR","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"46.38.239.179","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"F5A1A38EFB6BD3C2C8AF8B10D85F0F89E931704D349F1D0720C3C4059AF2440A","maintainer":"MartinSchröder","location":"DE","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"104.167.101.29","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"5918AC3C06955962A75AD7DF4F80A5D7C34F7DB9E1498D2E0495DE35B3FE8A57","maintainer":"noisykeyboard","location":"CA","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"80.232.246.79","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"CF6CECA0A14A31717CC8501DA51BE27742B70746956E6676FF423A529F91ED5D","maintainer":"fUNKIAM","location":"LV","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"104.233.104.126","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"EDEE8F2E839A57820DE3DA4156D88350E53D4161447068A3457EE8F59F362414","maintainer":"wildermesser","location":"CA","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"home.vikingmakt.com.br","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"188E072676404ED833A4E947DC1D223DF8EFEBE5F5258573A236573688FB9761","maintainer":"umgeher","location":"BR","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"188.244.38.183","ipv6":"2001:470:de00:2:20c:29ff:fe68:354f","port":33445,"tcp_ports":[],"public_key":"15A0F9684E2423F9F46CFA5A50B562AE42525580D840CC50E518192BF333EE38","maintainer":"gem","location":"RU","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"mrflibble.c4.ee","ipv6":"2a02:16e0:0:12::4","port":33445,"tcp_ports":[],"public_key":"FAAB17014F42F7F20949F61E55F66A73C230876812A9737F5F6D2DCE4D9E4207","maintainer":"mrflibble","location":"GB","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"82.211.31.116","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"AF97B76392A6474AF2FD269220FDCF4127D86A42EF3A242DF53A40A268A2CD7C","maintainer":"Net.Verified","location":"RU","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"tox1.privacydragon.me","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"31910C0497D347FF160D6F3A6C0E317BAFA71E8E03BC4CBB2A185C9D4FB8B31E","maintainer":"PrivacyDragon","location":"US","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"zawertun.net","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"5521952892FBD5C185DF7180DB4DEF69D7844DEEE79B1F75A634ED9DF656756E","maintainer":"ZaWertun","location":"NL","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"87.98.168.93","ipv6":"-","port":33445,"tcp_ports":[],"public_key":"C3F6C06A624FAE086DA94604A7838DB495769807EC055FADA36EBF2D4484FB33","maintainer":"_kinka_","location":"ES","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"185.61.253.189","ipv6":"2a04:ee00:0:9:20c:29ff:fe27:ad96","port":33445,"tcp_ports":[],"public_key":"73EEBCB4CBBE56BF0E0F01881DDD88C6B250BAE92CF487BE3FBE02FD830CE200","maintainer":"MAXL-SPB","location":"RU","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"109.75.40.105","ipv6":"2001:470:70d6::1","port":33445,"tcp_ports":[],"public_key":"2B9CD794424FD579044EC2FC5252B23DF8B4AAF239C25074F70B1090C3F8C83A","maintainer":"nek","location":"AM","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0},{"ipv4":"185.120.34.64","ipv6":"2a06:8ec0:1:bb::3862","port":33445,"tcp_ports":[],"public_key":"728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854","maintainer":"Kostik","location":"GB","status_udp":false,"status_tcp":false,"version":"","motd":"","last_ping":0}]} diff --git a/src/bootstrap.c b/src/bootstrap.c index 0e2e1ed..244ecc1 100644 --- a/src/bootstrap.c +++ b/src/bootstrap.c @@ -23,23 +23,40 @@ #include #include #include +#include +#include #include #include "line_info.h" #include "windows.h" #include "misc_tools.h" +#include "configdir.h" +#include "curl_util.h" extern struct arg_opts arg_opts; +/* URL that we get the JSON encoded nodes list from. */ +#define NODES_LIST_URL "https://nodes.tox.chat/json" + +#define DEFAULT_NODES_FILENAME "DHTnodes" /* Time to wait between bootstrap attempts */ #define TRY_BOOTSTRAP_INTERVAL 5 +/* Number of nodes to bootstrap to per try */ +#define NUM_BOOTSTRAP_NODES 5 + +/* How often we should update the nodeslist file. */ +#define NODELIST_UPDATE_TIMEOUT (60*24*30) + #define IPv4_MAX_SIZE 64 #define PORT_MAX_SIZE 5 +#define LAST_SCAN_JSON_VALUE "\"last_scan\":" +#define LAST_SCAN_JSON_VALUE_LEN (sizeof(LAST_SCAN_JSON_VALUE) - 1) + #define IPV4_JSON_VALUE "\"ipv4\":\"" #define IPV4_JSON_VALUE_LEN (sizeof(IPV4_JSON_VALUE) - 1) @@ -62,24 +79,198 @@ static struct toxNodes { char keys[MAXNODES][TOX_PUBLIC_KEY_SIZE]; } toxNodes; -/* Load the DHT nodelist to memory from json formatted nodes file obtained at https://nodes.tox.chat/json. + +/* Return true if nodeslist pointed to by fp needs to be updated. + * This will be the case if the file is empty, has an invalid format, + * or if the file is older than the given timeout. + */ +static bool nodeslist_needs_update(const char *nodes_path) +{ + FILE *fp = fopen(nodes_path, "r+"); + + if (fp == NULL) { + return false; + } + + /* last_scan value should be at beginning of file */ + char line[LAST_SCAN_JSON_VALUE_LEN + 32]; + + if (fgets(line, sizeof(line), fp) == NULL) { + fclose(fp); + return true; + } + + fclose(fp); + + const char *last_scan_val = strstr(line, LAST_SCAN_JSON_VALUE); + + if (last_scan_val == NULL) { + return true; + } + + last_scan_val += LAST_SCAN_JSON_VALUE_LEN; + long long int last_scan = strtoll(last_scan_val, NULL, 10); + + if (timed_out(last_scan, NODELIST_UPDATE_TIMEOUT)) { + return true; + } + + return false; +} + +/* Fetches the JSON encoded DHT nodeslist from NODES_LIST_URL. * * Return 0 on success. - * Return -1 if nodelist file cannot be opened. - * Return -2 if nodelist file cannot be parsed. - * Return -3 if nodelist file does not contain any valid node entries. + * Return -1 on failure. */ -int load_DHT_nodelist(void) +static int curl_fetch_nodes_JSON(struct Recv_Data *recv_data) { - const char *filename = !arg_opts.nodes_path[0] ? PACKAGE_DATADIR "/DHTnodes" : arg_opts.nodes_path; - FILE *fp = fopen(filename, "r"); + CURL *c_handle = curl_easy_init(); - if (fp == NULL) + if (c_handle == NULL) { return -1; + } + + struct curl_slist *headers = NULL; + headers = curl_slist_append(headers, "Content-Type: application/json"); + headers = curl_slist_append(headers, "charsets: utf-8"); + + curl_easy_setopt(c_handle, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(c_handle, CURLOPT_URL, NODES_LIST_URL); + curl_easy_setopt(c_handle, CURLOPT_WRITEFUNCTION, write_lookup_data); + curl_easy_setopt(c_handle, CURLOPT_WRITEDATA, recv_data); + curl_easy_setopt(c_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + curl_easy_setopt(c_handle, CURLOPT_HTTPGET, 1L); + + int proxy_ret = set_curl_proxy(c_handle, arg_opts.proxy_address, arg_opts.proxy_port, arg_opts.proxy_type); + + if (proxy_ret != 0) { + fprintf(stderr, "set_curl_proxy() failed with error %d\n", proxy_ret); + return -1; + } + + int ret = curl_easy_setopt(c_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + + if (ret != CURLE_OK) { + fprintf(stderr, "TLSv1.2 could not be set (libcurl error %d)", ret); + return -1; + } + + ret = curl_easy_setopt(c_handle, CURLOPT_SSL_CIPHER_LIST, TLS_CIPHER_SUITE_LIST); + + if (ret != CURLE_OK) { + fprintf(stderr, "Failed to set TLS cipher list (libcurl error %d)", ret); + return -1; + } + + ret = curl_easy_perform(c_handle); + + if (ret != CURLE_OK) { + /* If system doesn't support any of the specified ciphers suites, fall back to default */ + if (ret == CURLE_SSL_CIPHER) { + curl_easy_setopt(c_handle, CURLOPT_SSL_CIPHER_LIST, NULL); + ret = curl_easy_perform(c_handle); + } + + if (ret != CURLE_OK) { + fprintf(stderr, "HTTPS lookup error (libcurl error %d)\n", ret); + return -1; + } + } + + return 0; +} + +/* Attempts to update the DHT nodeslist. + * + * Return 1 if list was updated successfully. + * Return 0 if list does not need to be updated. + * Return -1 if file cannot be opened. + * Return -2 if http lookup failed. + * Return -3 if http reponse was empty. + * Return -4 if data could not be written to disk. + */ +static int update_DHT_nodeslist(const char *nodes_path) +{ + if (!nodeslist_needs_update(nodes_path)) { + return 0; + } + + FILE *fp = fopen(nodes_path, "r+"); + + if (fp == NULL) { + return -1; + } + + struct Recv_Data recv_data; + memset(&recv_data, 0, sizeof(struct Recv_Data)); + + if (curl_fetch_nodes_JSON(&recv_data) == -1) { + fclose(fp); + return -2; + } + + if (recv_data.length == 0) { + fclose(fp); + return -3; + } + + if (fwrite(recv_data.data, recv_data.length, 1, fp) != 1) { + fclose(fp); + return -4; + } + + fclose(fp); + return 1; +} + +static void get_nodeslist_path(char *buf, size_t buf_size) +{ + char *config_dir = NULL; + + if (arg_opts.nodes_path[0]) { + snprintf(buf, buf_size, "%s", arg_opts.nodes_path); + } else if ((config_dir = get_user_config_dir()) != NULL) { + snprintf(buf, buf_size, "%s%s%s", config_dir, CONFIGDIR, DEFAULT_NODES_FILENAME); + free(config_dir); + } else { + snprintf(buf, buf_size, "%s", DEFAULT_NODES_FILENAME); + } +} + +/* Load the DHT nodeslist to memory from json encoded nodes file obtained at NODES_LIST_URL. + * TODO: Parse json using a proper library? + * + * Return 0 on success. + * Return -1 if nodeslist file cannot be opened or created. + * Return -2 if nodeslist file cannot be parsed. + * Return -3 if nodeslist file does not contain any valid node entries. + */ +int load_DHT_nodeslist(void) +{ + char nodes_path[PATH_MAX]; + get_nodeslist_path(nodes_path, sizeof(nodes_path)); + + FILE *fp = NULL; + + if (!file_exists(nodes_path)) { + if ((fp = fopen(nodes_path, "w+")) == NULL) { + return -1; + } + } else if ((fp = fopen(nodes_path, "r+")) == NULL) { + return -1; + } + + int update_err = update_DHT_nodeslist(nodes_path); + + if (update_err < 0) { + fprintf(stderr, "update_DHT_nodeslist() failed with error %d\n", update_err); + } char line[MAX_NODELIST_SIZE]; if (fgets(line, sizeof(line), fp) == NULL) { + fclose(fp); return -2; } @@ -124,8 +315,9 @@ int load_DHT_nodelist(void) long int port = strtol(port_string, NULL, 10); - if (port <= 0 || port > MAX_PORT_RANGE) + if (port <= 0 || port > MAX_PORT_RANGE) { continue; + } /* Extract key */ const char *key_start = strstr(port_start, KEY_JSON_VALUE); @@ -145,7 +337,7 @@ int load_DHT_nodelist(void) memcpy(key_string, key_start, TOX_PUBLIC_KEY_SIZE * 2); key_string[TOX_PUBLIC_KEY_SIZE * 2] = 0; - /* Add IP-Port-Key to nodes list */ + /* Add entry to nodes list */ snprintf(toxNodes.nodes[toxNodes.lines], sizeof(toxNodes.nodes[toxNodes.lines]), "%s", ipv4_string); toxNodes.ports[toxNodes.lines] = port; @@ -155,34 +347,45 @@ int load_DHT_nodelist(void) toxNodes.lines++; } - fclose(fp); - - if (toxNodes.lines == 0) + /* If nodeslist does not contain any valid entries we set the last_scan value + * to 0 so that it will fetch a new list the next time this function is called. + */ + if (toxNodes.lines == 0) { + const char *s = "{\"last_scan\":0}"; + rewind(fp); + fwrite(s, strlen(s), 1, fp); // Not much we can do if it fails + fclose(fp); return -3; + } + fclose(fp); return 0; } -/* Connects to a random DHT node listed in the DHTnodes file. */ +/* Connects to NUM_BOOTSTRAP_NODES random DHT nodes listed in the DHTnodes file. */ static void DHT_bootstrap(Tox *m) { if (toxNodes.lines == 0) { return; } - size_t node = rand() % toxNodes.lines; + size_t i; - TOX_ERR_BOOTSTRAP err; - tox_bootstrap(m, toxNodes.nodes[node], toxNodes.ports[node], (uint8_t *) toxNodes.keys[node], &err); + for (i = 0; i < NUM_BOOTSTRAP_NODES; ++i) { + size_t node = rand() % toxNodes.lines; - if (err != TOX_ERR_BOOTSTRAP_OK) { - fprintf(stderr, "Failed to bootstrap %s:%d\n", toxNodes.nodes[node], toxNodes.ports[node]); - } + TOX_ERR_BOOTSTRAP err; + tox_bootstrap(m, toxNodes.nodes[node], toxNodes.ports[node], (uint8_t *) toxNodes.keys[node], &err); - tox_add_tcp_relay(m, toxNodes.nodes[node], toxNodes.ports[node], (uint8_t *) toxNodes.keys[node], &err); + if (err != TOX_ERR_BOOTSTRAP_OK) { + fprintf(stderr, "Failed to bootstrap %s:%d\n", toxNodes.nodes[node], toxNodes.ports[node]); + } - if (err != TOX_ERR_BOOTSTRAP_OK) { - fprintf(stderr, "Failed to add TCP relay %s:%d\n", toxNodes.nodes[node], toxNodes.ports[node]); + tox_add_tcp_relay(m, toxNodes.nodes[node], toxNodes.ports[node], (uint8_t *) toxNodes.keys[node], &err); + + if (err != TOX_ERR_BOOTSTRAP_OK) { + fprintf(stderr, "Failed to add TCP relay %s:%d\n", toxNodes.nodes[node], toxNodes.ports[node]); + } } } diff --git a/src/bootstrap.h b/src/bootstrap.h index e3dfab5..0159d3d 100644 --- a/src/bootstrap.h +++ b/src/bootstrap.h @@ -23,11 +23,12 @@ /* Manages connection to the Tox DHT network. */ void do_tox_connection(Tox *m); -/* Load the DHT nodelist to memory from json formatted nodes file obtained attempts https://nodes.tox.chat/json. +/* Load the DHT nodeslist to memory from json encoded nodes file obtained at NODES_LIST_URL. + * TODO: Parse json using a proper library? * * Return 0 on success. - * Return -1 if nodelist file cannot be opened. - * Return -2 if nodelist file cannot be parsed. - * Return -3 if nodelist file does not contain any valid node entries. + * Return -1 if nodeslist file cannot be opened or created. + * Return -2 if nodeslist file cannot be parsed. + * Return -3 if nodeslist file does not contain any valid node entries. */ -int load_DHT_nodelist(void); +int load_DHT_nodeslist(void); diff --git a/src/configdir.c b/src/configdir.c index d1e5f8d..ee97af3 100644 --- a/src/configdir.c +++ b/src/configdir.c @@ -33,7 +33,7 @@ #include "configdir.h" #include "misc_tools.h" -/* get the user's home directory */ +/* get the user's home directory. */ void get_home_dir(char *home, int size) { struct passwd pwd; @@ -102,8 +102,10 @@ char *get_user_config_dir(void) return user_config_dir; } -/* - * Creates the config and chatlog directories. +/* Creates the config and chatlog directories. + * + * Returns 0 on success. + * Returns -1 on failure. */ int create_user_config_dirs(char *path) { diff --git a/src/configdir.h b/src/configdir.h index 69abffd..a5317c3 100644 --- a/src/configdir.h +++ b/src/configdir.h @@ -34,8 +34,23 @@ #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #endif +/** + * @brief Get the user's config directory. + * + * This is without a trailing slash. Resulting string must be freed. + * + * @return The users config dir or NULL on error. + */ char *get_user_config_dir(void); + +/* get the user's home directory. */ void get_home_dir(char *home, int size); + +/* Creates the config and chatlog directories. + * + * Returns 0 on success. + * Returns -1 on failure. + */ int create_user_config_dirs(char *path); #endif /* #define CONFIGDIR_H */ diff --git a/src/curl_util.c b/src/curl_util.c new file mode 100644 index 0000000..5ab2944 --- /dev/null +++ b/src/curl_util.c @@ -0,0 +1,93 @@ +/* curl_util.c + * + * + * Copyright (C) 2016 Toxic All Rights Reserved. + * + * This file is part of Toxic. + * + * Toxic is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Toxic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Toxic. If not, see . + * + */ + +#include +#include + +#include +#include + +#include "curl_util.h" + +/* Sets proxy info for given CURL handler. + * + * Returns 0 on success or if no proxy is set by the client. + * Returns -1 if proxy info is invalid. + * Returns an int > 0 on curl error (see: https://curl.haxx.se/libcurl/c/libcurl-errors.html) + */ +int set_curl_proxy(CURL *c_handle, const char *proxy_address, uint16_t port, uint8_t proxy_type) +{ + if (proxy_type == TOX_PROXY_TYPE_NONE) + return 0; + + if (proxy_address == NULL || port == 0) { + return -1; + } + + int ret = curl_easy_setopt(c_handle, CURLOPT_PROXYPORT, (long) port); + + if (ret != CURLE_OK) { + return ret; + } + + long int type = proxy_type == TOX_PROXY_TYPE_SOCKS5 ? CURLPROXY_SOCKS5_HOSTNAME : CURLPROXY_HTTP; + + ret = curl_easy_setopt(c_handle, CURLOPT_PROXYTYPE, type); + + if (ret != CURLE_OK) { + return ret; + } + + ret = curl_easy_setopt(c_handle, CURLOPT_PROXY, proxy_address); + + if (ret != CURLE_OK) { + return ret; + } + + return 0; +} + +/* Callback function for CURL to write received data. + * + * This function will append data from an http request to the data buffer + * until the request is complete or the buffer is full. Buffer will be null terminated. + * + * Returns number of bytes received from http request on success (don't change this). + * Returns 0 if data exceeds buffer size. + */ +size_t write_lookup_data(void *data, size_t size, size_t nmemb, void *user_pointer) +{ + struct Recv_Data *recv_data = (struct Recv_Data *) user_pointer; + + size_t length = size * nmemb; + size_t total_size = length + recv_data->length; + + if (total_size > MAX_RECV_CURL_DATA_SIZE) { + return 0; + } + + memcpy(recv_data->data + recv_data->length, data, length); + recv_data->data[total_size] = '\0'; + recv_data->length += length; + + return length; +} diff --git a/src/curl_util.h b/src/curl_util.h new file mode 100644 index 0000000..b6b67f1 --- /dev/null +++ b/src/curl_util.h @@ -0,0 +1,50 @@ +/* curl_util.h + * + * + * Copyright (C) 2016 Toxic All Rights Reserved. + * + * This file is part of Toxic. + * + * Toxic is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Toxic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Toxic. If not, see . + * + */ + +/* List based on Mozilla's recommended configurations for modern browsers */ +#define TLS_CIPHER_SUITE_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK" + +/* Max size of an http response that we can store in Recv_Data */ +#define MAX_RECV_CURL_DATA_SIZE 32767 + +/* Holds data received from curl lookup */ +struct Recv_Data { + char data[MAX_RECV_CURL_DATA_SIZE + 1]; /* Data received from curl write data callback */ + size_t length; /* Total number of bytes written to data buffer (doesn't include null) */ +}; + +/* Sets proxy info for given CURL handler. + * + * Returns 0 on success or if no proxy is set by the client. + * Returns -1 if proxy info is invalid. + * Returns an int > 0 on curl error (see: https://curl.haxx.se/libcurl/c/libcurl-errors.html) + */ +int set_curl_proxy(CURL *c_handle, const char *proxy_address, uint16_t port, uint8_t proxy_type); + +/* Callback function for CURL to write received data. + * + * This function will append data from an http request to the data buffer + * until the request is complete or the buffer is full. Buffer will be null terminated. + * + * Returns size of bytes written to the data buffer. + */ +size_t write_lookup_data(void *data, size_t size, size_t nmemb, void *user_pointer); diff --git a/src/name_lookup.c b/src/name_lookup.c index 3fc7e36..863e9aa 100644 --- a/src/name_lookup.c +++ b/src/name_lookup.c @@ -22,7 +22,6 @@ #include #include -#include /* for u_char */ #include #include "toxic.h" @@ -31,6 +30,7 @@ #include "global_commands.h" #include "misc_tools.h" #include "configdir.h" +#include "curl_util.h" extern struct arg_opts arg_opts; extern struct Winthread Winthread;; @@ -41,9 +41,6 @@ extern struct Winthread Winthread;; #define MAX_DOMAIN_SIZE 32 #define MAX_SERVER_LINE MAX_DOMAIN_SIZE + (SERVER_KEY_SIZE * 2) + 3 -/* List based on Mozilla's recommended configurations for modern browsers */ -#define TLS_CIPHER_SUITE_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK" - struct Nameservers { int lines; char names[MAX_SERVERS][MAX_DOMAIN_SIZE]; @@ -189,29 +186,6 @@ static bool get_domain_match(char *pubkey, char *out_domain, size_t out_domain_s return false; } -#define MAX_RECV_LOOKUP_DATA_SIZE 1024 - -/* Holds raw data received from name server */ -struct Recv_Data { - char data[MAX_RECV_LOOKUP_DATA_SIZE]; - size_t size; -}; - -size_t write_lookup_data(void *data, size_t size, size_t nmemb, void *user_pointer) -{ - struct Recv_Data *recv_data = (struct Recv_Data *) user_pointer; - size_t real_size = size * nmemb; - - if (real_size >= MAX_RECV_LOOKUP_DATA_SIZE) - return 0; - - memcpy(&recv_data->data, data, real_size); - recv_data->size = real_size; - recv_data->data[real_size] = '\0'; - - return real_size; -} - /* Converts Tox ID string contained in recv_data to binary format and puts it in thread's ID buffer. * * Returns 0 on success. @@ -222,7 +196,7 @@ static int process_response(struct Recv_Data *recv_data) { size_t prefix_size = strlen(ID_PREFIX); - if (recv_data->size < TOX_ADDRESS_SIZE * 2 + prefix_size) + if (recv_data->length < TOX_ADDRESS_SIZE * 2 + prefix_size) return -1; const char *IDstart = strstr(recv_data->data, ID_PREFIX); @@ -243,47 +217,6 @@ static int process_response(struct Recv_Data *recv_data) return 0; } -/* Sets proxy info for given CURL handler. - * - * Returns 0 on success or if no proxy is set by the client. - * Returns -1 on failure. - */ -static int set_lookup_proxy(ToxWindow *self, CURL *c_handle, const char *proxy_address, uint16_t port, uint8_t proxy_type) -{ - if (proxy_type == TOX_PROXY_TYPE_NONE) - return 0; - - if (proxy_address == NULL || port == 0) { - lookup_error(self, "Unknown proxy error"); - return -1; - } - - int ret = curl_easy_setopt(c_handle, CURLOPT_PROXYPORT, (long) port); - - if (ret != CURLE_OK) { - lookup_error(self, "Failed to set proxy port (libcurl error %d)", ret); - return -1; - } - - long int type = proxy_type == TOX_PROXY_TYPE_SOCKS5 ? CURLPROXY_SOCKS5_HOSTNAME : CURLPROXY_HTTP; - - ret = curl_easy_setopt(c_handle, CURLOPT_PROXYTYPE, type); - - if (ret != CURLE_OK) { - lookup_error(self, "Failed to set proxy type (libcurl error %d)", ret); - return -1; - } - - ret = curl_easy_setopt(c_handle, CURLOPT_PROXY, proxy_address); - - if (ret != CURLE_OK) { - lookup_error(self, "Failed to set proxy (libcurl error %d)", ret); - return -1; - } - - return 0; -} - void *lookup_thread_func(void *data) { ToxWindow *self = t_data.self; @@ -333,8 +266,12 @@ void *lookup_thread_func(void *data) curl_easy_setopt(c_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); curl_easy_setopt(c_handle, CURLOPT_POSTFIELDS, post_data); - if (set_lookup_proxy(self, c_handle, arg_opts.proxy_address, arg_opts.proxy_port, arg_opts.proxy_type) == -1) + int proxy_ret = set_curl_proxy(c_handle, arg_opts.proxy_address, arg_opts.proxy_port, arg_opts.proxy_type); + + if (proxy_ret != 0) { + lookup_error(self, "Failed to set proxy (error %d)\n"); goto on_exit; + } int ret = curl_easy_setopt(c_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL); @@ -437,9 +374,9 @@ void name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, * Returns -2 if the nameserver list cannot be found. * Returns -3 if the nameserver list does not contain any valid entries. */ -int name_lookup_init(void) +int name_lookup_init(int curl_init_status) { - if (curl_global_init(CURL_GLOBAL_ALL) != 0) { + if (curl_init_status != 0) { t_data.disabled = true; return -1; } @@ -454,8 +391,3 @@ int name_lookup_init(void) return 0; } - -void name_lookup_cleanup(void) -{ - curl_global_cleanup(); -} diff --git a/src/name_lookup.h b/src/name_lookup.h index c1419d8..e9b8ed4 100644 --- a/src/name_lookup.h +++ b/src/name_lookup.h @@ -29,8 +29,7 @@ * Returns 0 on success. * Returns -1 on failure. */ -int name_lookup_init(void); -void name_lookup_cleanup(void); +int name_lookup_init(int curl_init_status); int name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message); diff --git a/src/toxic.c b/src/toxic.c index ab56f5c..2691656 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -164,7 +165,7 @@ void exit_toxic_success(Tox *m) free_global_data(); tox_kill(m); endwin(); - name_lookup_cleanup(); + curl_global_cleanup(); #ifdef X11 /* We have to terminate xtra last coz reasons @@ -455,6 +456,7 @@ int store_data(Tox *m, const char *path) char *data = malloc(data_len * sizeof(char)); if (data == NULL) { + fclose(fp); return -1; } @@ -465,6 +467,7 @@ int store_data(Tox *m, const char *path) char *enc_data = malloc(enc_len * sizeof(char)); if (enc_data == NULL) { + fclose(fp); free(data); return -1; } @@ -580,14 +583,14 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW if (len == 0) { fclose(fp); - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err("failed in load_tox", FATALERR_FILEOP); } char data[len]; if (fread(data, sizeof(data), 1, fp) != 1) { fclose(fp); - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err("failed in load_tox", FATALERR_FILEOP); } bool is_encrypted = tox_is_data_encrypted((uint8_t *) data); @@ -595,7 +598,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW /* attempt to encrypt an already encrypted data file */ if (arg_opts.encrypt_data && is_encrypted) { fclose(fp); - exit_toxic_err("failed in load_toxic", FATALERR_ENCRYPT); + exit_toxic_err("failed in load_tox", FATALERR_ENCRYPT); } if (arg_opts.unencrypt_data && is_encrypted) @@ -681,7 +684,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW fclose(fp); } else { /* Data file does not/should not exist */ if (file_exists(data_path)) - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err("failed in load_tox", FATALERR_FILEOP); tox_opts->savedata_type = TOX_SAVEDATA_TYPE_NONE; @@ -691,7 +694,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW return NULL; if (store_data(m, data_path) == -1) - exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); + exit_toxic_err("failed in load_tox", FATALERR_FILEOP); } return m; @@ -920,10 +923,6 @@ static void parse_args(int argc, char *argv[]) case 'n': snprintf(arg_opts.nodes_path, sizeof(arg_opts.nodes_path), "%s", optarg); - - if (!file_exists(arg_opts.nodes_path)) - queue_init_message("DHTnodes file not found"); - break; case 'o': @@ -1092,6 +1091,7 @@ void DnD_callback(const char* asdv, DropType dt) int main(int argc, char **argv) { + update_unix_time(); parse_args(argc, argv); /* Use the -b flag to enable stderr */ @@ -1125,16 +1125,12 @@ int main(int argc, char **argv) const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL; - if (settings_load(user_settings, p) == -1) + if (settings_load(user_settings, p) == -1) { queue_init_message("Failed to load user settings"); - - int nodelist_ret = load_DHT_nodelist(); - - if (nodelist_ret != 0) { - queue_init_message("DHT nodelist failed to load (error %d). You can still connect manually with the /connect command.", nodelist_ret); } - int nameserver_ret = name_lookup_init(); + int curl_init = curl_global_init(CURL_GLOBAL_ALL); + int nameserver_ret = name_lookup_init(curl_init); if (nameserver_ret == -1) { queue_init_message("curl failed to initialize; name lookup service is disabled."); @@ -1144,6 +1140,12 @@ int main(int argc, char **argv) queue_init_message("Name lookup server list does not contain any valid entries."); } + int nodeslist_ret = load_DHT_nodeslist(); + + if (nodeslist_ret != 0) { + queue_init_message("DHT nodeslist failed to load (error %d)\n", nodeslist_ret); + } + #ifdef X11 if (init_xtra(DnD_callback) == -1) queue_init_message("X failed to initialize"); diff --git a/src/windows.h b/src/windows.h index c2a0760..21f1386 100644 --- a/src/windows.h +++ b/src/windows.h @@ -153,7 +153,7 @@ struct ToxWindow { #ifdef VIDEO int video_device_selection[2]; /* -1 if not set, if set uses these selections instead of primary video device */ - + #endif /* VIDEO */ #endif /* AUDIO */