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