ii-1.8-ssl-20200810-b10421c.diff (10634B)
1 From b10421c548c3cf3507b8ade1679407a5af6202e6 Mon Sep 17 00:00:00 2001 2 From: Alexandre Hannedouche <hannedouche.alex@gmail.com> 3 Date: Mon, 3 Aug 2020 18:37:01 +0200 4 Subject: [PATCH] Adapting ssl patch 5 6 --- 7 config.mk | 2 +- 8 ii.1 | 5 ++ 9 ii.c | 154 +++++++++++++++++++++++++++++++++++++++++------------- 10 3 files changed, 123 insertions(+), 38 deletions(-) 11 12 diff --git a/config.mk b/config.mk 13 index 957bae0..9becc42 100644 14 --- a/config.mk 15 +++ b/config.mk 16 @@ -10,5 +10,5 @@ DOCPREFIX = ${PREFIX}/share/doc 17 # remove NEED_STRLCPY from CFLAGS and 18 # remove strlcpy.o from LIBS 19 CFLAGS = -DNEED_STRLCPY -Os 20 -LDFLAGS = -s 21 +LDFLAGS = -s -lssl -lcrypto 22 LIBS = strlcpy.o 23 diff --git a/ii.1 b/ii.1 24 index 8e06af7..6d7704c 100644 25 --- a/ii.1 26 +++ b/ii.1 27 @@ -21,6 +21,8 @@ and ii creates a new channel directory with in and out file. 28 .IR servername > 29 .RB [ \-p 30 .IR port ] 31 +.RB [ \-e 32 +.IR ssl ] 33 .RB [ \-k 34 .IR "environment variable" ] 35 .RB [ \-i 36 @@ -42,6 +44,9 @@ connect to a UNIX domain socket instead of directly to a server. 37 .BI \-p " port" 38 lets you override the default port (6667) 39 .TP 40 +.BI \-e " ssl" 41 +lets you connect using ssl encryption. The default ssl port is 6697. 42 +.TP 43 .BI \-k " environment variable" 44 lets you specify an environment variable that contains your IRC password, e.g. IIPASS="foobar" ii -k IIPASS. 45 This is done in order to prevent other users from eavesdropping the server password via the process list. 46 diff --git a/ii.c b/ii.c 47 index 426fcff..712f872 100644 48 --- a/ii.c 49 +++ b/ii.c 50 @@ -20,6 +20,10 @@ 51 #include <time.h> 52 #include <unistd.h> 53 54 +#include <openssl/rand.h> 55 +#include <openssl/ssl.h> 56 +#include <openssl/err.h> 57 + 58 char *argv0; 59 60 #include "arg.h" 61 @@ -43,6 +47,13 @@ struct Channel { 62 Channel *next; 63 }; 64 65 +typedef struct { 66 + int use_ssl; 67 + int irc; 68 + SSL *sslHandle; 69 + SSL_CTX *sslContext; 70 +} conn; 71 + 72 static Channel * channel_add(const char *); 73 static Channel * channel_find(const char *); 74 static Channel * channel_join(const char *); 75 @@ -56,20 +67,23 @@ static int channel_reopen(Channel *); 76 static void channel_rm(Channel *); 77 static void create_dirtree(const char *); 78 static void create_filepath(char *, size_t, const char *, const char *, const char *); 79 -static void ewritestr(int, const char *); 80 -static void handle_channels_input(int, Channel *); 81 -static void handle_server_output(int); 82 +static int swrite(conn *, const char *, size_t); 83 +static void ewritestr(conn *, const char *); 84 +static void handle_channels_input(conn *, Channel *); 85 +static void handle_server_output(conn *); 86 static int isnumeric(const char *); 87 -static void loginkey(int, const char *); 88 -static void loginuser(int, const char *, const char *); 89 -static void proc_channels_input(int, Channel *, char *); 90 -static void proc_channels_privmsg(int, Channel *, char *); 91 -static void proc_server_cmd(int, char *); 92 -static int read_line(int, char *, size_t); 93 -static void run(int, const char *); 94 +static void loginkey(conn *, const char *); 95 +static void loginuser(conn *, const char *, const char *); 96 +static void proc_channels_input(conn *, Channel *, char *); 97 +static void proc_channels_privmsg(conn *, Channel *, char *); 98 +static void proc_server_cmd(conn *, char *); 99 +static int sread(conn *, char *, size_t); 100 +static int read_line(conn *, char *, size_t); 101 +static int read_line_from_channel(int, char *, size_t); 102 +static void run(conn *, const char *); 103 static void setup(void); 104 static void sighandler(int); 105 -static int tcpopen(const char *, const char *); 106 +static void tcpopen(conn *ircfd, const char *, const char *); 107 static size_t tokenize(char **, size_t, char *, int); 108 static int udsopen(const char *); 109 static void usage(void); 110 @@ -87,20 +101,29 @@ static void 111 usage(void) 112 { 113 fprintf(stderr, "usage: %s <-s host> [-i <irc dir>] [-p <port>] " 114 - "[-u <sockname>] [-n <nick>] [-k <password>] " 115 + "[-e <ssl>] [-u <sockname>] [-n <nick>] [-k <password>] " 116 "[-f <fullname>]\n", argv0); 117 exit(1); 118 } 119 120 +static int 121 +swrite(conn *ircfd, const char *msg, size_t len) 122 +{ 123 + if (ircfd->use_ssl) 124 + return SSL_write(ircfd->sslHandle, msg, len); 125 + 126 + return write(ircfd->irc, msg, len); 127 +} 128 + 129 static void 130 -ewritestr(int fd, const char *s) 131 +ewritestr(conn *fd, const char *s) 132 { 133 size_t len, off = 0; 134 int w = -1; 135 136 len = strlen(s); 137 for (off = 0; off < len; off += w) { 138 - if ((w = write(fd, s + off, len - off)) == -1) 139 + if ((w = swrite(fd, s + off, len - off)) == -1) 140 break; 141 } 142 if (w == -1) { 143 @@ -319,14 +342,14 @@ channel_leave(Channel *c) 144 } 145 146 static void 147 -loginkey(int ircfd, const char *key) 148 +loginkey(conn *ircfd, const char *key) 149 { 150 snprintf(msg, sizeof(msg), "PASS %s\r\n", key); 151 ewritestr(ircfd, msg); 152 } 153 154 static void 155 -loginuser(int ircfd, const char *host, const char *fullname) 156 +loginuser(conn *ircfd, const char *host, const char *fullname) 157 { 158 snprintf(msg, sizeof(msg), "NICK %s\r\nUSER %s localhost %s :%s\r\n", 159 nick, nick, host, fullname); 160 @@ -359,12 +382,15 @@ udsopen(const char *uds) 161 return fd; 162 } 163 164 -static int 165 -tcpopen(const char *host, const char *service) 166 +static void 167 +tcpopen(conn *ircfd, const char *host, const char *service) 168 { 169 struct addrinfo hints, *res = NULL, *rp; 170 int fd = -1, e; 171 172 + ircfd->sslHandle = NULL; 173 + ircfd->sslContext = NULL; 174 + 175 memset(&hints, 0, sizeof(hints)); 176 hints.ai_family = AF_UNSPEC; /* allow IPv4 or IPv6 */ 177 hints.ai_flags = AI_NUMERICSERV; /* avoid name lookup for port */ 178 @@ -393,7 +419,19 @@ tcpopen(const char *host, const char *service) 179 } 180 181 freeaddrinfo(res); 182 - return fd; 183 + ircfd->irc = fd; 184 + if (!ircfd->use_ssl) 185 + return; 186 + 187 + //SSL_load_error_strings(); 188 + //SSL_library_init(); 189 + ircfd->sslContext = SSL_CTX_new(SSLv23_client_method()); 190 + if (ircfd->sslContext == NULL) 191 + ERR_print_errors_fp(stderr); 192 + ircfd->sslHandle = SSL_new(ircfd->sslContext); 193 + if (!SSL_set_fd(ircfd->sslHandle, ircfd->irc) || 194 + (SSL_connect(ircfd->sslHandle) != 1)) 195 + ERR_print_errors_fp(stderr); 196 } 197 198 static int 199 @@ -445,7 +483,7 @@ channel_print(Channel *c, const char *buf) 200 } 201 202 static void 203 -proc_channels_privmsg(int ircfd, Channel *c, char *buf) 204 +proc_channels_privmsg(conn *ircfd, Channel *c, char *buf) 205 { 206 snprintf(msg, sizeof(msg), "<%s> %s", nick, buf); 207 channel_print(c, msg); 208 @@ -454,7 +492,7 @@ proc_channels_privmsg(int ircfd, Channel *c, char *buf) 209 } 210 211 static void 212 -proc_channels_input(int ircfd, Channel *c, char *buf) 213 +proc_channels_input(conn *ircfd, Channel *c, char *buf) 214 { 215 char *p = NULL; 216 size_t buflen; 217 @@ -546,7 +584,7 @@ proc_channels_input(int ircfd, Channel *c, char *buf) 218 } 219 220 static void 221 -proc_server_cmd(int fd, char *buf) 222 +proc_server_cmd(conn *fd, char *buf) 223 { 224 Channel *c; 225 const char *channel; 226 @@ -665,8 +703,33 @@ proc_server_cmd(int fd, char *buf) 227 channel_print(c, msg); 228 } 229 230 + 231 +static int 232 +sread(conn *fd, char *buf, size_t bufsize) 233 +{ 234 + if (fd->use_ssl) 235 + return SSL_read(fd->sslHandle, buf, bufsize); 236 + 237 + return read(fd->irc, buf, bufsize); 238 +} 239 + 240 +static int 241 +read_line(conn *fd, char *buf, size_t bufsiz) 242 +{ 243 + size_t i = 0; 244 + char c = '\0'; 245 + 246 + do { 247 + if (sread(fd, &c, sizeof(char)) != sizeof(char)) 248 + return -1; 249 + buf[i++] = c; 250 + } while (c != '\n' && i < bufsiz); 251 + buf[i - 1] = '\0'; /* eliminates '\n' */ 252 + return 0; 253 +} 254 + 255 static int 256 -read_line(int fd, char *buf, size_t bufsiz) 257 +read_line_from_channel(int fd, char *buf, size_t bufsiz) 258 { 259 size_t i = 0; 260 char c = '\0'; 261 @@ -681,11 +744,11 @@ read_line(int fd, char *buf, size_t bufsiz) 262 } 263 264 static void 265 -handle_channels_input(int ircfd, Channel *c) 266 +handle_channels_input(conn *ircfd, Channel *c) 267 { 268 char buf[IRC_MSG_MAX]; 269 270 - if (read_line(c->fdin, buf, sizeof(buf)) == -1) { 271 + if (read_line_from_channel(c->fdin, buf, sizeof(buf)) == -1) { 272 if (channel_reopen(c) == -1) 273 channel_rm(c); 274 return; 275 @@ -694,7 +757,7 @@ handle_channels_input(int ircfd, Channel *c) 276 } 277 278 static void 279 -handle_server_output(int ircfd) 280 +handle_server_output(conn *ircfd) 281 { 282 char buf[IRC_MSG_MAX]; 283 284 @@ -727,7 +790,7 @@ setup(void) 285 } 286 287 static void 288 -run(int ircfd, const char *host) 289 +run(conn *ircfd, const char *host) 290 { 291 Channel *c, *tmp; 292 fd_set rdset; 293 @@ -737,9 +800,9 @@ run(int ircfd, const char *host) 294 295 snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host); 296 while (isrunning) { 297 - maxfd = ircfd; 298 + maxfd = ircfd->irc; 299 FD_ZERO(&rdset); 300 - FD_SET(ircfd, &rdset); 301 + FD_SET(ircfd->irc, &rdset); 302 for (c = channels; c; c = c->next) { 303 if (c->fdin > maxfd) 304 maxfd = c->fdin; 305 @@ -761,7 +824,7 @@ run(int ircfd, const char *host) 306 ewritestr(ircfd, ping_msg); 307 continue; 308 } 309 - if (FD_ISSET(ircfd, &rdset)) { 310 + if (FD_ISSET(ircfd->irc, &rdset)) { 311 handle_server_output(ircfd); 312 last_response = time(NULL); 313 } 314 @@ -779,9 +842,12 @@ main(int argc, char *argv[]) 315 Channel *c, *tmp; 316 struct passwd *spw; 317 const char *key = NULL, *fullname = NULL, *host = ""; 318 - const char *uds = NULL, *service = "6667"; 319 + const char *uds = NULL; 320 + const char *service = "6667"; 321 + const char *sservice = "6697"; 322 char prefix[PATH_MAX]; 323 - int ircfd, r; 324 + int r, defaultPort = 1; 325 + conn ircfd; 326 327 /* use nickname and home dir of user by default */ 328 if (!(spw = getpwuid(getuid()))) { 329 @@ -806,6 +872,7 @@ main(int argc, char *argv[]) 330 break; 331 case 'p': 332 service = EARGF(usage()); 333 + defaultPort = 0; 334 break; 335 case 's': 336 host = EARGF(usage()); 337 @@ -813,6 +880,11 @@ main(int argc, char *argv[]) 338 case 'u': 339 uds = EARGF(usage()); 340 break; 341 + case 'e': 342 + if (defaultPort) 343 + service = sservice; 344 + ircfd.use_ssl = 1; 345 + break; 346 default: 347 usage(); 348 break; 349 @@ -822,9 +894,9 @@ main(int argc, char *argv[]) 350 usage(); 351 352 if (uds) 353 - ircfd = udsopen(uds); 354 + ircfd.irc = udsopen(uds); 355 else 356 - ircfd = tcpopen(host, service); 357 + tcpopen(&ircfd, host, service); 358 359 #ifdef __OpenBSD__ 360 /* OpenBSD pledge(2) support */ 361 @@ -843,10 +915,10 @@ main(int argc, char *argv[]) 362 363 channelmaster = channel_add(""); /* master channel */ 364 if (key) 365 - loginkey(ircfd, key); 366 - loginuser(ircfd, host, fullname && *fullname ? fullname : nick); 367 + loginkey(&ircfd, key); 368 + loginuser(&ircfd, host, fullname && *fullname ? fullname : nick); 369 setup(); 370 - run(ircfd, host); 371 + run(&ircfd, host); 372 if (channelmaster) 373 channel_leave(channelmaster); 374 375 @@ -855,5 +927,13 @@ main(int argc, char *argv[]) 376 channel_leave(c); 377 } 378 379 + if (ircfd.use_ssl) { 380 + SSL_shutdown(ircfd.sslHandle); 381 + SSL_free(ircfd.sslHandle); 382 + SSL_CTX_free(ircfd.sslContext); 383 + } 384 + 385 + close(ircfd.irc); 386 + 387 return 0; 388 } 389 -- 390 2.28.0 391