ii-ssl-20200811-ecf3902.diff (21310B)
1 From 68d3498bb0ce639875c5927a618567231b500d61 Mon Sep 17 00:00:00 2001 2 From: Alexandre Hannedouche <hannedouche.alex@gmail.com> 3 Date: Tue, 11 Aug 2020 22:51:08 +0200 4 Subject: [PATCH] porting ssh patch to 1.8 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..9a09135 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 392 From 6c237478845fa047a5f414f9c032b2674da8f30b Mon Sep 17 00:00:00 2001 393 From: Alexandre Hannedouche <hannedouche.alex@gmail.com> 394 Date: Tue, 11 Aug 2020 22:51:08 +0200 395 Subject: [PATCH] porting ssl patch to 1.8 396 397 --- 398 config.mk | 2 +- 399 ii.1 | 5 ++ 400 ii.c | 154 +++++++++++++++++++++++++++++++++++++++++------------- 401 3 files changed, 123 insertions(+), 38 deletions(-) 402 403 diff --git a/config.mk b/config.mk 404 index 957bae0..9becc42 100644 405 --- a/config.mk 406 +++ b/config.mk 407 @@ -10,5 +10,5 @@ DOCPREFIX = ${PREFIX}/share/doc 408 # remove NEED_STRLCPY from CFLAGS and 409 # remove strlcpy.o from LIBS 410 CFLAGS = -DNEED_STRLCPY -Os 411 -LDFLAGS = -s 412 +LDFLAGS = -s -lssl -lcrypto 413 LIBS = strlcpy.o 414 diff --git a/ii.1 b/ii.1 415 index 8e06af7..6d7704c 100644 416 --- a/ii.1 417 +++ b/ii.1 418 @@ -21,6 +21,8 @@ and ii creates a new channel directory with in and out file. 419 .IR servername > 420 .RB [ \-p 421 .IR port ] 422 +.RB [ \-e 423 +.IR ssl ] 424 .RB [ \-k 425 .IR "environment variable" ] 426 .RB [ \-i 427 @@ -42,6 +44,9 @@ connect to a UNIX domain socket instead of directly to a server. 428 .BI \-p " port" 429 lets you override the default port (6667) 430 .TP 431 +.BI \-e " ssl" 432 +lets you connect using ssl encryption. The default ssl port is 6697. 433 +.TP 434 .BI \-k " environment variable" 435 lets you specify an environment variable that contains your IRC password, e.g. IIPASS="foobar" ii -k IIPASS. 436 This is done in order to prevent other users from eavesdropping the server password via the process list. 437 diff --git a/ii.c b/ii.c 438 index 426fcff..9a09135 100644 439 --- a/ii.c 440 +++ b/ii.c 441 @@ -20,6 +20,10 @@ 442 #include <time.h> 443 #include <unistd.h> 444 445 +#include <openssl/rand.h> 446 +#include <openssl/ssl.h> 447 +#include <openssl/err.h> 448 + 449 char *argv0; 450 451 #include "arg.h" 452 @@ -43,6 +47,13 @@ struct Channel { 453 Channel *next; 454 }; 455 456 +typedef struct { 457 + int use_ssl; 458 + int irc; 459 + SSL *sslHandle; 460 + SSL_CTX *sslContext; 461 +} conn; 462 + 463 static Channel * channel_add(const char *); 464 static Channel * channel_find(const char *); 465 static Channel * channel_join(const char *); 466 @@ -56,20 +67,23 @@ static int channel_reopen(Channel *); 467 static void channel_rm(Channel *); 468 static void create_dirtree(const char *); 469 static void create_filepath(char *, size_t, const char *, const char *, const char *); 470 -static void ewritestr(int, const char *); 471 -static void handle_channels_input(int, Channel *); 472 -static void handle_server_output(int); 473 +static int swrite(conn *, const char *, size_t); 474 +static void ewritestr(conn *, const char *); 475 +static void handle_channels_input(conn *, Channel *); 476 +static void handle_server_output(conn *); 477 static int isnumeric(const char *); 478 -static void loginkey(int, const char *); 479 -static void loginuser(int, const char *, const char *); 480 -static void proc_channels_input(int, Channel *, char *); 481 -static void proc_channels_privmsg(int, Channel *, char *); 482 -static void proc_server_cmd(int, char *); 483 -static int read_line(int, char *, size_t); 484 -static void run(int, const char *); 485 +static void loginkey(conn *, const char *); 486 +static void loginuser(conn *, const char *, const char *); 487 +static void proc_channels_input(conn *, Channel *, char *); 488 +static void proc_channels_privmsg(conn *, Channel *, char *); 489 +static void proc_server_cmd(conn *, char *); 490 +static int sread(conn *, char *, size_t); 491 +static int read_line(conn *, char *, size_t); 492 +static int read_line_from_channel(int, char *, size_t); 493 +static void run(conn *, const char *); 494 static void setup(void); 495 static void sighandler(int); 496 -static int tcpopen(const char *, const char *); 497 +static void tcpopen(conn *ircfd, const char *, const char *); 498 static size_t tokenize(char **, size_t, char *, int); 499 static int udsopen(const char *); 500 static void usage(void); 501 @@ -87,20 +101,29 @@ static void 502 usage(void) 503 { 504 fprintf(stderr, "usage: %s <-s host> [-i <irc dir>] [-p <port>] " 505 - "[-u <sockname>] [-n <nick>] [-k <password>] " 506 + "[-e <ssl>] [-u <sockname>] [-n <nick>] [-k <password>] " 507 "[-f <fullname>]\n", argv0); 508 exit(1); 509 } 510 511 +static int 512 +swrite(conn *ircfd, const char *msg, size_t len) 513 +{ 514 + if (ircfd->use_ssl) 515 + return SSL_write(ircfd->sslHandle, msg, len); 516 + 517 + return write(ircfd->irc, msg, len); 518 +} 519 + 520 static void 521 -ewritestr(int fd, const char *s) 522 +ewritestr(conn *fd, const char *s) 523 { 524 size_t len, off = 0; 525 int w = -1; 526 527 len = strlen(s); 528 for (off = 0; off < len; off += w) { 529 - if ((w = write(fd, s + off, len - off)) == -1) 530 + if ((w = swrite(fd, s + off, len - off)) == -1) 531 break; 532 } 533 if (w == -1) { 534 @@ -319,14 +342,14 @@ channel_leave(Channel *c) 535 } 536 537 static void 538 -loginkey(int ircfd, const char *key) 539 +loginkey(conn *ircfd, const char *key) 540 { 541 snprintf(msg, sizeof(msg), "PASS %s\r\n", key); 542 ewritestr(ircfd, msg); 543 } 544 545 static void 546 -loginuser(int ircfd, const char *host, const char *fullname) 547 +loginuser(conn *ircfd, const char *host, const char *fullname) 548 { 549 snprintf(msg, sizeof(msg), "NICK %s\r\nUSER %s localhost %s :%s\r\n", 550 nick, nick, host, fullname); 551 @@ -359,12 +382,15 @@ udsopen(const char *uds) 552 return fd; 553 } 554 555 -static int 556 -tcpopen(const char *host, const char *service) 557 +static void 558 +tcpopen(conn *ircfd, const char *host, const char *service) 559 { 560 struct addrinfo hints, *res = NULL, *rp; 561 int fd = -1, e; 562 563 + ircfd->sslHandle = NULL; 564 + ircfd->sslContext = NULL; 565 + 566 memset(&hints, 0, sizeof(hints)); 567 hints.ai_family = AF_UNSPEC; /* allow IPv4 or IPv6 */ 568 hints.ai_flags = AI_NUMERICSERV; /* avoid name lookup for port */ 569 @@ -393,7 +419,19 @@ tcpopen(const char *host, const char *service) 570 } 571 572 freeaddrinfo(res); 573 - return fd; 574 + ircfd->irc = fd; 575 + if (!ircfd->use_ssl) 576 + return; 577 + 578 + //SSL_load_error_strings(); 579 + //SSL_library_init(); 580 + ircfd->sslContext = SSL_CTX_new(SSLv23_client_method()); 581 + if (ircfd->sslContext == NULL) 582 + ERR_print_errors_fp(stderr); 583 + ircfd->sslHandle = SSL_new(ircfd->sslContext); 584 + if (!SSL_set_fd(ircfd->sslHandle, ircfd->irc) || 585 + (SSL_connect(ircfd->sslHandle) != 1)) 586 + ERR_print_errors_fp(stderr); 587 } 588 589 static int 590 @@ -445,7 +483,7 @@ channel_print(Channel *c, const char *buf) 591 } 592 593 static void 594 -proc_channels_privmsg(int ircfd, Channel *c, char *buf) 595 +proc_channels_privmsg(conn *ircfd, Channel *c, char *buf) 596 { 597 snprintf(msg, sizeof(msg), "<%s> %s", nick, buf); 598 channel_print(c, msg); 599 @@ -454,7 +492,7 @@ proc_channels_privmsg(int ircfd, Channel *c, char *buf) 600 } 601 602 static void 603 -proc_channels_input(int ircfd, Channel *c, char *buf) 604 +proc_channels_input(conn *ircfd, Channel *c, char *buf) 605 { 606 char *p = NULL; 607 size_t buflen; 608 @@ -546,7 +584,7 @@ proc_channels_input(int ircfd, Channel *c, char *buf) 609 } 610 611 static void 612 -proc_server_cmd(int fd, char *buf) 613 +proc_server_cmd(conn *fd, char *buf) 614 { 615 Channel *c; 616 const char *channel; 617 @@ -665,8 +703,33 @@ proc_server_cmd(int fd, char *buf) 618 channel_print(c, msg); 619 } 620 621 + 622 +static int 623 +sread(conn *fd, char *buf, size_t bufsize) 624 +{ 625 + if (fd->use_ssl) 626 + return SSL_read(fd->sslHandle, buf, bufsize); 627 + 628 + return read(fd->irc, buf, bufsize); 629 +} 630 + 631 +static int 632 +read_line(conn *fd, char *buf, size_t bufsiz) 633 +{ 634 + size_t i = 0; 635 + char c = '\0'; 636 + 637 + do { 638 + if (sread(fd, &c, sizeof(char)) != sizeof(char)) 639 + return -1; 640 + buf[i++] = c; 641 + } while (c != '\n' && i < bufsiz); 642 + buf[i - 1] = '\0'; /* eliminates '\n' */ 643 + return 0; 644 +} 645 + 646 static int 647 -read_line(int fd, char *buf, size_t bufsiz) 648 +read_line_from_channel(int fd, char *buf, size_t bufsiz) 649 { 650 size_t i = 0; 651 char c = '\0'; 652 @@ -681,11 +744,11 @@ read_line(int fd, char *buf, size_t bufsiz) 653 } 654 655 static void 656 -handle_channels_input(int ircfd, Channel *c) 657 +handle_channels_input(conn *ircfd, Channel *c) 658 { 659 char buf[IRC_MSG_MAX]; 660 661 - if (read_line(c->fdin, buf, sizeof(buf)) == -1) { 662 + if (read_line_from_channel(c->fdin, buf, sizeof(buf)) == -1) { 663 if (channel_reopen(c) == -1) 664 channel_rm(c); 665 return; 666 @@ -694,7 +757,7 @@ handle_channels_input(int ircfd, Channel *c) 667 } 668 669 static void 670 -handle_server_output(int ircfd) 671 +handle_server_output(conn *ircfd) 672 { 673 char buf[IRC_MSG_MAX]; 674 675 @@ -727,7 +790,7 @@ setup(void) 676 } 677 678 static void 679 -run(int ircfd, const char *host) 680 +run(conn *ircfd, const char *host) 681 { 682 Channel *c, *tmp; 683 fd_set rdset; 684 @@ -737,9 +800,9 @@ run(int ircfd, const char *host) 685 686 snprintf(ping_msg, sizeof(ping_msg), "PING %s\r\n", host); 687 while (isrunning) { 688 - maxfd = ircfd; 689 + maxfd = ircfd->irc; 690 FD_ZERO(&rdset); 691 - FD_SET(ircfd, &rdset); 692 + FD_SET(ircfd->irc, &rdset); 693 for (c = channels; c; c = c->next) { 694 if (c->fdin > maxfd) 695 maxfd = c->fdin; 696 @@ -761,7 +824,7 @@ run(int ircfd, const char *host) 697 ewritestr(ircfd, ping_msg); 698 continue; 699 } 700 - if (FD_ISSET(ircfd, &rdset)) { 701 + if (FD_ISSET(ircfd->irc, &rdset)) { 702 handle_server_output(ircfd); 703 last_response = time(NULL); 704 } 705 @@ -779,9 +842,12 @@ main(int argc, char *argv[]) 706 Channel *c, *tmp; 707 struct passwd *spw; 708 const char *key = NULL, *fullname = NULL, *host = ""; 709 - const char *uds = NULL, *service = "6667"; 710 + const char *uds = NULL; 711 + const char *service = "6667"; 712 + const char *sservice = "6697"; 713 char prefix[PATH_MAX]; 714 - int ircfd, r; 715 + int r, defaultPort = 1; 716 + conn ircfd; 717 718 /* use nickname and home dir of user by default */ 719 if (!(spw = getpwuid(getuid()))) { 720 @@ -806,6 +872,7 @@ main(int argc, char *argv[]) 721 break; 722 case 'p': 723 service = EARGF(usage()); 724 + defaultPort = 0; 725 break; 726 case 's': 727 host = EARGF(usage()); 728 @@ -813,6 +880,11 @@ main(int argc, char *argv[]) 729 case 'u': 730 uds = EARGF(usage()); 731 break; 732 + case 'e': 733 + if (defaultPort) 734 + service = sservice; 735 + ircfd.use_ssl = 1; 736 + break; 737 default: 738 usage(); 739 break; 740 @@ -822,9 +894,9 @@ main(int argc, char *argv[]) 741 usage(); 742 743 if (uds) 744 - ircfd = udsopen(uds); 745 + ircfd.irc = udsopen(uds); 746 else 747 - ircfd = tcpopen(host, service); 748 + tcpopen(&ircfd, host, service); 749 750 #ifdef __OpenBSD__ 751 /* OpenBSD pledge(2) support */ 752 @@ -843,10 +915,10 @@ main(int argc, char *argv[]) 753 754 channelmaster = channel_add(""); /* master channel */ 755 if (key) 756 - loginkey(ircfd, key); 757 - loginuser(ircfd, host, fullname && *fullname ? fullname : nick); 758 + loginkey(&ircfd, key); 759 + loginuser(&ircfd, host, fullname && *fullname ? fullname : nick); 760 setup(); 761 - run(ircfd, host); 762 + run(&ircfd, host); 763 if (channelmaster) 764 channel_leave(channelmaster); 765 766 @@ -855,5 +927,13 @@ main(int argc, char *argv[]) 767 channel_leave(c); 768 } 769 770 + if (ircfd.use_ssl) { 771 + SSL_shutdown(ircfd.sslHandle); 772 + SSL_free(ircfd.sslHandle); 773 + SSL_CTX_free(ircfd.sslContext); 774 + } 775 + 776 + close(ircfd.irc); 777 + 778 return 0; 779 } 780 -- 781 2.28.0 782