From 7ae6847839226aac8724f93b45ebcf3563b16dd4 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Mon, 24 Nov 2003 16:04:37 +0000 Subject: [PATCH] Brute-force decryption of the tetrisstart message, now it works even for clients behind NATs. --- Makefile | 3 +++ server.c | 83 +++++++++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 8230179..62c8f08 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,9 @@ OBJS = sockets.o tetrinet.o tetris.o tty.o # CFLAGS = -O2 -I/usr/include/ncurses -DHAVE_IPV6 -g -DBUILTIN_SERVER -Wall # OBJS = server.o sockets.o tetrinet.o tetris.o tty.o xwin.o +### If you experience random delays and server freezes when accepting new +### clients, add -DNO_BRUTE_FORCE_DECRYPTION to the CFLAGS line. + ######## all: tetrinet tetrinet-server diff --git a/server.c b/server.c index 7b3cdc9..96ce68d 100644 --- a/server.c +++ b/server.c @@ -886,37 +886,60 @@ static void check_sockets() continue; sgets(buf, sizeof(buf), fd); if (player_socks[i] < 0) { - /* Messy decoding stuff */ - char iphashbuf[16], newbuf[1024]; - unsigned char *ip; - int j, c, d; + /* Our extension: the client can give up on the meaningless + * encryption completely. */ + if (strncmp(buf,"tetrisstart ",12) != 0) { + /* Messy decoding stuff */ + char iphashbuf[16], newbuf[1024]; +#ifdef NO_BRUTE_FORCE_DECRYPTION + unsigned char *ip; +#else + int hashval; +#endif + int j, c, d; - if (strlen(buf) < 2*13) { /* "tetrisstart " + initial byte */ - close(fd); - player_socks[i] = -1; - continue; - } - ip = player_ips[i]; - sprintf(iphashbuf, "%d", ip[0]*54 + ip[1]*41 + ip[2]*29 + ip[3]*17); - c = xtoi(buf); - for (j = 2; buf[j] && buf[j+1]; j += 2) { - int temp; - temp = d = xtoi(buf+j); - d ^= iphashbuf[((j/2)-1) % strlen(iphashbuf)]; - d += 255 - c; - d %= 255; - newbuf[j/2-1] = d; - c = temp; - } - newbuf[j/2-1] = 0; - if (strncmp(newbuf, "tetrisstart ", 12) != 0) { - close(fd); - player_socks[i] = -1; - continue; - } - /* Buffers should be the same size, but let's be paranoid */ - strncpy(buf, newbuf, sizeof(buf)); - buf[sizeof(buf)-1] = 0; + if (strlen(buf) < 2*13) { /* "tetrisstart " + initial byte */ + close(fd); + player_socks[i] = -1; + continue; + } +#ifdef NO_BRUTE_FORCE_DECRYPTION + ip = player_ips[i]; + sprintf(iphashbuf, "%d", + ip[0]*54 + ip[1]*41 + ip[2]*29 + ip[3]*17); +#else + /* The IP-based crypt does not work for clients behind NAT. So + * help them by brute-forcing the crypt. This should not be + * even noticeable unless you are running this under ucLinux on + * some XT machine. */ + for (hashval = 0; hashval < 35956; hashval++) { + sprintf(iphashbuf, "%d", hashval); +#endif + c = xtoi(buf); + for (j = 2; buf[j] && buf[j+1]; j += 2) { + int temp; + temp = d = xtoi(buf+j); + d ^= iphashbuf[((j/2)-1) % strlen(iphashbuf)]; + d += 255 - c; + d %= 255; + newbuf[j/2-1] = d; + c = temp; + } + newbuf[j/2-1] = 0; +#ifndef NO_BRUTE_FORCE_DECRYPTION + if(strncmp(newbuf,"tetrisstart ",12) == 0) + break; + } /* for (hashval) */ +#endif + if (strncmp(newbuf, "tetrisstart ", 12) != 0) { + close(fd); + player_socks[i] = -1; + continue; + } + /* Buffers should be the same size, but let's be paranoid */ + strncpy(buf, newbuf, sizeof(buf)); + buf[sizeof(buf)-1] = 0; + } /* if encrypted */ player_socks[i] = fd; /* Has now registered */ } /* if client not registered */ if (!server_parse(i+1, buf)) { -- 2.11.4.GIT