| ii-2.0-ssl.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| ii-2.0-ssl.diff (10577B) | |
| --- | |
| 1 From 20b47a9dbf4c8299f01d0d73f112ece58da8cabb Mon Sep 17 00:00:00 2001 | |
| 2 From: Jon Eskin <[email protected]> | |
| 3 Date: Wed, 4 Jan 2023 06:20:19 -0500 | |
| 4 Subject: [PATCH] porting ssl patch to 2.0 | |
| 5 | |
| 6 --- | |
| 7 Makefile | 2 +- | |
| 8 ii.1 | 5 ++ | |
| 9 ii.c | 156 ++++++++++++++++++++++++++++++++++++++++++------------- | |
| 10 3 files changed, 125 insertions(+), 38 deletions(-) | |
| 11 | |
| 12 diff --git a/Makefile b/Makefile | |
| 13 index 28c7781..23db7c1 100644 | |
| 14 --- a/Makefile | |
| 15 +++ b/Makefile | |
| 16 @@ -12,7 +12,7 @@ OBJ = $(SRC:.c=.o) | |
| 17 | |
| 18 # use system flags. | |
| 19 II_CFLAGS = $(CFLAGS) | |
| 20 -II_LDFLAGS = $(LDFLAGS) | |
| 21 +II_LDFLAGS = $(LDFLAGS) -lssl -lcrypto | |
| 22 | |
| 23 # on systems which provide strlcpy(3), | |
| 24 # remove NEED_STRLCPY from CPPFLAGS and | |
| 25 diff --git a/ii.1 b/ii.1 | |
| 26 index 59fd798..3ddc376 100644 | |
| 27 --- a/ii.1 | |
| 28 +++ b/ii.1 | |
| 29 @@ -7,6 +7,8 @@ ii - irc it or irc improved | |
| 30 .I host | |
| 31 .RB [ -p | |
| 32 .I port | |
| 33 +.RB [ \-e | |
| 34 +.IR ssl ] | |
| 35 | | |
| 36 .B -u | |
| 37 .IR sockname ] | |
| 38 @@ -40,6 +42,9 @@ server/host to connect to, for example: irc.freenode.n… | |
| 39 .BI -p " port" | |
| 40 lets you override the default port (6667) | |
| 41 .TP | |
| 42 +.BI \-e " ssl" | |
| 43 +lets you connect using ssl encryption. The default ssl port is 6697. | |
| 44 +.TP | |
| 45 .BI -u " sockname" | |
| 46 connect to a UNIX domain socket instead of directly to a server. | |
| 47 If set, the | |
| 48 diff --git a/ii.c b/ii.c | |
| 49 index c402a87..6de4157 100644 | |
| 50 --- a/ii.c | |
| 51 +++ b/ii.c | |
| 52 @@ -20,6 +20,10 @@ | |
| 53 #include <time.h> | |
| 54 #include <unistd.h> | |
| 55 | |
| 56 +#include <openssl/rand.h> | |
| 57 +#include <openssl/ssl.h> | |
| 58 +#include <openssl/err.h> | |
| 59 + | |
| 60 char *argv0; | |
| 61 | |
| 62 #include "arg.h" | |
| 63 @@ -43,6 +47,14 @@ struct Channel { | |
| 64 Channel *next; | |
| 65 }; | |
| 66 | |
| 67 +typedef struct { | |
| 68 + int use_ssl; | |
| 69 + int irc; | |
| 70 + SSL *sslHandle; | |
| 71 + SSL_CTX *sslContext; | |
| 72 +} conn; | |
| 73 + | |
| 74 + | |
| 75 static Channel * channel_add(const char *); | |
| 76 static Channel * channel_find(const char *); | |
| 77 static Channel * channel_join(const char *); | |
| 78 @@ -57,21 +69,24 @@ static void channel_rm(Channel *); | |
| 79 static void cleanup(void); | |
| 80 static void create_dirtree(const char *); | |
| 81 static void create_filepath(char *, size_t, const char *, const ch… | |
| 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 void die(const char *, ...); | |
| 87 -static void ewritestr(int, const char *); | |
| 88 -static void handle_channels_input(int, Channel *); | |
| 89 -static void handle_server_output(int); | |
| 90 static int isnumeric(const char *); | |
| 91 -static void loginkey(int, const char *); | |
| 92 -static void loginuser(int, const char *, const char *); | |
| 93 -static void proc_channels_input(int, Channel *, char *); | |
| 94 -static void proc_channels_privmsg(int, Channel *, char *); | |
| 95 -static void proc_server_cmd(int, char *); | |
| 96 -static int read_line(int, char *, size_t); | |
| 97 -static void run(int, const char *); | |
| 98 +static void loginkey(conn *, const char *); | |
| 99 +static void loginuser(conn *, const char *, const char *); | |
| 100 +static void proc_channels_input(conn *, Channel *, char *); | |
| 101 +static void proc_channels_privmsg(conn *, Channel *, char *); | |
| 102 +static void proc_server_cmd(conn *, char *); | |
| 103 +static int sread(conn *, char *, size_t); | |
| 104 +static int read_line(conn *, char *, size_t); | |
| 105 +static int read_line_from_channel(int, char *, size_t); | |
| 106 +static void run(conn *, const char *); | |
| 107 static void setup(void); | |
| 108 static void sighandler(int); | |
| 109 -static int tcpopen(const char *, const char *); | |
| 110 +static void tcpopen(conn *ircfd, const char *, const char *); | |
| 111 static size_t tokenize(char **, size_t, char *, int); | |
| 112 static int udsopen(const char *); | |
| 113 static void usage(void); | |
| 114 @@ -102,18 +117,27 @@ static void | |
| 115 usage(void) | |
| 116 { | |
| 117 die("usage: %s -s host [-p port | -u sockname] [-i ircdir]\n" | |
| 118 - " [-n nickname] [-f fullname] [-k env_pass]\n", argv… | |
| 119 + " [-e <ssl>] [-n nickname] [-f fullname] [-k env_pas… | |
| 120 +} | |
| 121 + | |
| 122 +static int | |
| 123 +swrite(conn *ircfd, const char *msg, size_t len) | |
| 124 +{ | |
| 125 + if (ircfd->use_ssl) | |
| 126 + return SSL_write(ircfd->sslHandle, msg, len); | |
| 127 + | |
| 128 + return write(ircfd->irc, msg, len); | |
| 129 } | |
| 130 | |
| 131 static void | |
| 132 -ewritestr(int fd, const char *s) | |
| 133 +ewritestr(conn *fd, const char *s) | |
| 134 { | |
| 135 size_t len, off = 0; | |
| 136 int w = -1; | |
| 137 | |
| 138 len = strlen(s); | |
| 139 for (off = 0; off < len; off += w) { | |
| 140 - if ((w = write(fd, s + off, len - off)) == -1) | |
| 141 + if ((w = swrite(fd, s + off, len - off)) == -1) | |
| 142 break; | |
| 143 } | |
| 144 if (w == -1) | |
| 145 @@ -185,6 +209,7 @@ cleanup(void) | |
| 146 tmp = c->next; | |
| 147 channel_leave(c); | |
| 148 } | |
| 149 + | |
| 150 } | |
| 151 | |
| 152 static void | |
| 153 @@ -341,14 +366,14 @@ channel_leave(Channel *c) | |
| 154 } | |
| 155 | |
| 156 static void | |
| 157 -loginkey(int ircfd, const char *key) | |
| 158 +loginkey(conn *ircfd, const char *key) | |
| 159 { | |
| 160 snprintf(msg, sizeof(msg), "PASS %s\r\n", key); | |
| 161 ewritestr(ircfd, msg); | |
| 162 } | |
| 163 | |
| 164 static void | |
| 165 -loginuser(int ircfd, const char *host, const char *fullname) | |
| 166 +loginuser(conn *ircfd, const char *host, const char *fullname) | |
| 167 { | |
| 168 snprintf(msg, sizeof(msg), "NICK %s\r\nUSER %s localhost %s :%s… | |
| 169 nick, nick, host, fullname); | |
| 170 @@ -377,12 +402,15 @@ udsopen(const char *uds) | |
| 171 return fd; | |
| 172 } | |
| 173 | |
| 174 -static int | |
| 175 -tcpopen(const char *host, const char *service) | |
| 176 +static void | |
| 177 +tcpopen(conn *ircfd, const char *host, const char *service) | |
| 178 { | |
| 179 struct addrinfo hints, *res = NULL, *rp; | |
| 180 int fd = -1, e; | |
| 181 | |
| 182 + ircfd->sslHandle = NULL; | |
| 183 + ircfd->sslContext = NULL; | |
| 184 + | |
| 185 memset(&hints, 0, sizeof(hints)); | |
| 186 hints.ai_family = AF_UNSPEC; /* allow IPv4 or IPv6 */ | |
| 187 hints.ai_flags = AI_NUMERICSERV; /* avoid name lookup for port … | |
| 188 @@ -407,7 +435,19 @@ tcpopen(const char *host, const char *service) | |
| 189 argv0, host, service, strerror(errno)); | |
| 190 | |
| 191 freeaddrinfo(res); | |
| 192 - return fd; | |
| 193 + ircfd->irc = fd; | |
| 194 + if (!ircfd->use_ssl) | |
| 195 + return; | |
| 196 + | |
| 197 + //SSL_load_error_strings(); | |
| 198 + //SSL_library_init(); | |
| 199 + ircfd->sslContext = SSL_CTX_new(SSLv23_client_method()); | |
| 200 + if (ircfd->sslContext == NULL) | |
| 201 + ERR_print_errors_fp(stderr); | |
| 202 + ircfd->sslHandle = SSL_new(ircfd->sslContext); | |
| 203 + if (!SSL_set_fd(ircfd->sslHandle, ircfd->irc) || | |
| 204 + (SSL_connect(ircfd->sslHandle) != 1)) | |
| 205 + ERR_print_errors_fp(stderr); | |
| 206 } | |
| 207 | |
| 208 static int | |
| 209 @@ -459,7 +499,7 @@ channel_print(Channel *c, const char *buf) | |
| 210 } | |
| 211 | |
| 212 static void | |
| 213 -proc_channels_privmsg(int ircfd, Channel *c, char *buf) | |
| 214 +proc_channels_privmsg(conn *ircfd, Channel *c, char *buf) | |
| 215 { | |
| 216 snprintf(msg, sizeof(msg), "<%s> %s", nick, buf); | |
| 217 channel_print(c, msg); | |
| 218 @@ -468,7 +508,7 @@ proc_channels_privmsg(int ircfd, Channel *c, char *b… | |
| 219 } | |
| 220 | |
| 221 static void | |
| 222 -proc_channels_input(int ircfd, Channel *c, char *buf) | |
| 223 +proc_channels_input(conn *ircfd, Channel *c, char *buf) | |
| 224 { | |
| 225 char *p = NULL; | |
| 226 size_t buflen; | |
| 227 @@ -560,7 +600,7 @@ proc_channels_input(int ircfd, Channel *c, char *buf) | |
| 228 } | |
| 229 | |
| 230 static void | |
| 231 -proc_server_cmd(int fd, char *buf) | |
| 232 +proc_server_cmd(conn *fd, char *buf) | |
| 233 { | |
| 234 Channel *c; | |
| 235 const char *channel; | |
| 236 @@ -679,8 +719,33 @@ proc_server_cmd(int fd, char *buf) | |
| 237 channel_print(c, msg); | |
| 238 } | |
| 239 | |
| 240 + | |
| 241 +static int | |
| 242 +sread(conn *fd, char *buf, size_t bufsize) | |
| 243 +{ | |
| 244 + if (fd->use_ssl) | |
| 245 + return SSL_read(fd->sslHandle, buf, bufsize); | |
| 246 + | |
| 247 + return read(fd->irc, buf, bufsize); | |
| 248 +} | |
| 249 + | |
| 250 static int | |
| 251 -read_line(int fd, char *buf, size_t bufsiz) | |
| 252 +read_line(conn *fd, char *buf, size_t bufsiz) | |
| 253 +{ | |
| 254 + size_t i = 0; | |
| 255 + char c = '\0'; | |
| 256 + | |
| 257 + do { | |
| 258 + if (sread(fd, &c, sizeof(char)) != sizeof(char)) | |
| 259 + return -1; | |
| 260 + buf[i++] = c; | |
| 261 + } while (c != '\n' && i < bufsiz); | |
| 262 + buf[i - 1] = '\0'; /* eliminates '\n' */ | |
| 263 + return 0; | |
| 264 +} | |
| 265 + | |
| 266 +static int | |
| 267 +read_line_from_channel(int fd, char *buf, size_t bufsiz) | |
| 268 { | |
| 269 size_t i = 0; | |
| 270 char c = '\0'; | |
| 271 @@ -695,7 +760,7 @@ read_line(int fd, char *buf, size_t bufsiz) | |
| 272 } | |
| 273 | |
| 274 static void | |
| 275 -handle_channels_input(int ircfd, Channel *c) | |
| 276 +handle_channels_input(conn *ircfd, Channel *c) | |
| 277 { | |
| 278 /* | |
| 279 * Do not allow to read this fully, since commands will be | |
| 280 @@ -706,7 +771,7 @@ handle_channels_input(int ircfd, Channel *c) | |
| 281 */ | |
| 282 char buf[IRC_MSG_MAX-64]; | |
| 283 | |
| 284 - if (read_line(c->fdin, buf, sizeof(buf)) == -1) { | |
| 285 + if (read_line_from_channel(c->fdin, buf, sizeof(buf)) == -1) { | |
| 286 if (channel_reopen(c) == -1) | |
| 287 channel_rm(c); | |
| 288 return; | |
| 289 @@ -715,7 +780,7 @@ handle_channels_input(int ircfd, Channel *c) | |
| 290 } | |
| 291 | |
| 292 static void | |
| 293 -handle_server_output(int ircfd) | |
| 294 +handle_server_output(conn *ircfd) | |
| 295 { | |
| 296 char buf[IRC_MSG_MAX]; | |
| 297 | |
| 298 @@ -746,7 +811,7 @@ setup(void) | |
| 299 } | |
| 300 | |
| 301 static void | |
| 302 -run(int ircfd, const char *host) | |
| 303 +run(conn *ircfd, const char *host) | |
| 304 { | |
| 305 Channel *c, *tmp; | |
| 306 fd_set rdset; | |
| 307 @@ -756,9 +821,9 @@ run(int ircfd, const char *host) | |
| 308 | |
| 309 snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host); | |
| 310 while (isrunning) { | |
| 311 - maxfd = ircfd; | |
| 312 + maxfd = ircfd->irc; | |
| 313 FD_ZERO(&rdset); | |
| 314 - FD_SET(ircfd, &rdset); | |
| 315 + FD_SET(ircfd->irc, &rdset); | |
| 316 for (c = channels; c; c = c->next) { | |
| 317 if (c->fdin > maxfd) | |
| 318 maxfd = c->fdin; | |
| 319 @@ -780,7 +845,7 @@ run(int ircfd, const char *host) | |
| 320 ewritestr(ircfd, ping_msg); | |
| 321 continue; | |
| 322 } | |
| 323 - if (FD_ISSET(ircfd, &rdset)) { | |
| 324 + if (FD_ISSET(ircfd->irc, &rdset)) { | |
| 325 handle_server_output(ircfd); | |
| 326 last_response = time(NULL); | |
| 327 } | |
| 328 @@ -797,9 +862,12 @@ main(int argc, char *argv[]) | |
| 329 { | |
| 330 struct passwd *spw; | |
| 331 const char *key = NULL, *fullname = NULL, *host = ""; | |
| 332 - const char *uds = NULL, *service = "6667"; | |
| 333 + const char *uds = NULL; | |
| 334 + const char *service = "6667"; | |
| 335 + const char *sservice = "6697"; | |
| 336 char prefix[PATH_MAX]; | |
| 337 - int ircfd, r; | |
| 338 + int r, defaultPort = 1; | |
| 339 + conn ircfd; | |
| 340 | |
| 341 /* use nickname and home dir of user by default */ | |
| 342 if (!(spw = getpwuid(getuid()))) | |
| 343 @@ -823,6 +891,7 @@ main(int argc, char *argv[]) | |
| 344 break; | |
| 345 case 'p': | |
| 346 service = EARGF(usage()); | |
| 347 + defaultPort = 0; | |
| 348 break; | |
| 349 case 's': | |
| 350 host = EARGF(usage()); | |
| 351 @@ -830,6 +899,11 @@ main(int argc, char *argv[]) | |
| 352 case 'u': | |
| 353 uds = EARGF(usage()); | |
| 354 break; | |
| 355 + case 'e': | |
| 356 + if (defaultPort) | |
| 357 + service = sservice; | |
| 358 + ircfd.use_ssl = 1; | |
| 359 + break; | |
| 360 default: | |
| 361 usage(); | |
| 362 break; | |
| 363 @@ -839,9 +913,9 @@ main(int argc, char *argv[]) | |
| 364 usage(); | |
| 365 | |
| 366 if (uds) | |
| 367 - ircfd = udsopen(uds); | |
| 368 + ircfd.irc = udsopen(uds); | |
| 369 else | |
| 370 - ircfd = tcpopen(host, service); | |
| 371 + tcpopen(&ircfd, host, service); | |
| 372 | |
| 373 #ifdef __OpenBSD__ | |
| 374 /* OpenBSD pledge(2) support */ | |
| 375 @@ -856,11 +930,19 @@ main(int argc, char *argv[]) | |
| 376 | |
| 377 channelmaster = channel_add(""); /* master channel */ | |
| 378 if (key) | |
| 379 - loginkey(ircfd, key); | |
| 380 - loginuser(ircfd, host, fullname && *fullname ? fullname : nick); | |
| 381 + loginkey(&ircfd, key); | |
| 382 + loginuser(&ircfd, host, fullname && *fullname ? fullname : nick… | |
| 383 setup(); | |
| 384 - run(ircfd, host); | |
| 385 + run(&ircfd, host); | |
| 386 cleanup(); | |
| 387 | |
| 388 + if (ircfd.use_ssl) { | |
| 389 + SSL_shutdown(ircfd.sslHandle); | |
| 390 + SSL_free(ircfd.sslHandle); | |
| 391 + SSL_CTX_free(ircfd.sslContext); | |
| 392 + } | |
| 393 + | |
| 394 + close(ircfd.irc); | |
| 395 + | |
| 396 return 0; | |
| 397 } | |
| 398 -- | |
| 399 2.39.0 | |
| 400 |