ii-2.0-ssl.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       ii-2.0-ssl.diff (10577B)
       ---
            1 From 20b47a9dbf4c8299f01d0d73f112ece58da8cabb Mon Sep 17 00:00:00 2001
            2 From: Jon Eskin <eskinjp@gmail.com>
            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.net
           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 char *, const char *);
           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", argv0);
          119 +            "        [-e <ssl>] [-n nickname] [-f fullname] [-k env_pass]\n", argv0);
          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\r\n",
          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 *buf)
          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