ii-ssl-20200811-ecf3902.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       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