ii-2.0-tls.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-tls.diff (4917B)
       ---
            1 commit 6e349ab328266ab6a6beee31db2c7f97921d480f
            2 Author: Jan Klemkow <j.klemkow@wemelug.de>
            3 Date:   Sun Oct 30 22:25:31 2022 +0100
            4 
            5     add tls support
            6 
            7 diff --git a/Makefile b/Makefile
            8 index 28c7781..8c19387 100644
            9 --- a/Makefile
           10 +++ b/Makefile
           11 @@ -12,7 +12,7 @@ OBJ = $(SRC:.c=.o)
           12  
           13  # use system flags.
           14  II_CFLAGS = $(CFLAGS)
           15 -II_LDFLAGS = $(LDFLAGS)
           16 +II_LDFLAGS = $(LDFLAGS) -ltls
           17  
           18  # on systems which provide strlcpy(3),
           19  # remove NEED_STRLCPY from CPPFLAGS and
           20 diff --git a/ii.1 b/ii.1
           21 index 59fd798..a51944e 100644
           22 --- a/ii.1
           23 +++ b/ii.1
           24 @@ -3,6 +3,7 @@
           25  ii - irc it or irc improved
           26  .SH SYNOPSIS
           27  .B ii
           28 +.RB [ -t ]
           29  .B -s
           30  .I host
           31  .RB [ -p
           32 @@ -18,6 +19,8 @@ ii - irc it or irc improved
           33  .IR realname ]
           34  .RB [ -k
           35  .IR env_pass ]
           36 +.RB [ -F
           37 +.IR fingerprint ]
           38  .SH DESCRIPTION
           39  .B ii
           40  is a minimalistic FIFO and filesystem based IRC client.
           41 @@ -34,6 +37,9 @@ For example if you will join a channel just do echo "/j #channel" > in
           42  and ii creates a new channel directory with in and out file.
           43  .SH OPTIONS
           44  .TP
           45 +.BI -t
           46 +TLS encrypted connection
           47 +.TP
           48  .BI -s " host"
           49  server/host to connect to, for example: irc.freenode.net
           50  .TP
           51 @@ -60,6 +66,11 @@ lets you specify an environment variable that contains your IRC password,
           52  e.g. IIPASS="foobar" ii -k IIPASS.
           53  This is done in order to prevent other users from eavesdropping the server
           54  password via the process list.
           55 +.TP
           56 +.BI -F " fingerprint"
           57 +disables certificate and hostname verification.
           58 +Just check the server's certificate fingerprint.
           59 +This is recommended to connection to servers with self signed certificates.
           60  .SH DIRECTORIES
           61  .TP
           62  .B ~/irc
           63 diff --git a/ii.c b/ii.c
           64 index c402a87..95819c5 100644
           65 --- a/ii.c
           66 +++ b/ii.c
           67 @@ -20,6 +20,9 @@
           68  #include <time.h>
           69  #include <unistd.h>
           70  
           71 +#include <tls.h>
           72 +struct tls *tls = NULL;
           73 +int ircfd;
           74  char *argv0;
           75  
           76  #include "arg.h"
           77 @@ -101,8 +104,9 @@ die(const char *fmt, ...)
           78  static void
           79  usage(void)
           80  {
           81 -        die("usage: %s -s host [-p port | -u sockname] [-i ircdir]\n"
           82 -            "        [-n nickname] [-f fullname] [-k env_pass]\n", argv0);
           83 +        die("usage: %s [-t] -s host [-p port | -u sockname] [-i ircdir]\n"
           84 +            "        [-n nickname] [-f fullname] [-k env_pass] [-F fingerprint]\n",
           85 +            argv0);
           86  }
           87  
           88  static void
           89 @@ -113,11 +117,17 @@ ewritestr(int fd, const char *s)
           90  
           91          len = strlen(s);
           92          for (off = 0; off < len; off += w) {
           93 -                if ((w = write(fd, s + off, len - off)) == -1)
           94 +                if (tls && (w = tls_write(tls, s + off, len - off)) == -1)
           95                          break;
           96 +                if (!tls && (w = write(fd, s + off, len - off)) == -1)
           97 +                        break;
           98 +        }
           99 +        if (w == -1) {
          100 +                if (tls)
          101 +                        die("%s: tls_write: %s\n", argv0, tls_error(tls));
          102 +                else
          103 +                        die("%s: write: %s\n", argv0, strerror(errno));
          104          }
          105 -        if (w == -1)
          106 -                die("%s: write: %s\n", argv0, strerror(errno));
          107  }
          108  
          109  /* creates directories bottom-up, if necessary */
          110 @@ -686,8 +696,15 @@ read_line(int fd, char *buf, size_t bufsiz)
          111          char c = '\0';
          112  
          113          do {
          114 -                if (read(fd, &c, sizeof(char)) != sizeof(char))
          115 -                        return -1;
          116 +                if (tls && fd == ircfd) {
          117 +                        if (tls_read(tls, &c, sizeof(c)) == -1) {
          118 +                                die("");
          119 +                                return -1;
          120 +                        }
          121 +                } else {
          122 +                        if (read(fd, &c, sizeof(char)) != sizeof(char))
          123 +                                return -1;
          124 +                }
          125                  buf[i++] = c;
          126          } while (c != '\n' && i < bufsiz);
          127          buf[i - 1] = '\0'; /* eliminates '\n' */
          128 @@ -798,8 +815,9 @@ main(int argc, char *argv[])
          129          struct passwd *spw;
          130          const char *key = NULL, *fullname = NULL, *host = "";
          131          const char *uds = NULL, *service = "6667";
          132 -        char prefix[PATH_MAX];
          133 -        int ircfd, r;
          134 +        char prefix[PATH_MAX], *fingerprint = NULL;
          135 +        int r;
          136 +        struct tls_config *tls_config = NULL;
          137  
          138          /* use nickname and home dir of user by default */
          139          if (!(spw = getpwuid(getuid())))
          140 @@ -827,6 +845,16 @@ main(int argc, char *argv[])
          141          case 's':
          142                  host = EARGF(usage());
          143                  break;
          144 +        case 't':
          145 +                if (tls != NULL)
          146 +                        break;
          147 +
          148 +                if ((tls = tls_client()) == NULL)
          149 +                        die("%s: tls_client\n", argv0);
          150 +                break;
          151 +        case 'F':
          152 +                fingerprint = EARGF(usage());
          153 +                break;
          154          case 'u':
          155                  uds = EARGF(usage());
          156                  break;
          157 @@ -843,6 +871,22 @@ main(int argc, char *argv[])
          158          else
          159                  ircfd = tcpopen(host, service);
          160  
          161 +        if (tls && (tls_config = tls_config_new()) == NULL)
          162 +                die("%s: tls_config_new\n", argv0);
          163 +        if (tls && fingerprint) {
          164 +                /* Just check cert fingerprint and no CA chain or cert name. */
          165 +                tls_config_insecure_noverifycert(tls_config);
          166 +                tls_config_insecure_noverifyname(tls_config);
          167 +        }
          168 +        if (tls && tls_configure(tls, tls_config) == -1)
          169 +                die("%s: tls_configure\n", argv0);
          170 +        if (tls && tls_connect_socket(tls, ircfd, host) == -1)
          171 +                die("%s: tls_connect_socket: %s\n", argv0, tls_error(tls));
          172 +        if (tls && tls_handshake(tls) == -1)
          173 +                die("%s: tls_handshake: %s\n", argv0, tls_error(tls));
          174 +        if (tls && fingerprint && strcmp(fingerprint, tls_peer_cert_hash(tls)) != 0)
          175 +                die("%s: wrong fingerprint: %s\n", argv0, tls_peer_cert_hash(tls));
          176 +
          177  #ifdef __OpenBSD__
          178          /* OpenBSD pledge(2) support */
          179          if (pledge("stdio rpath wpath cpath dpath", NULL) == -1)