* [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects
@ 2025-10-14 7:27 noodle via 9fans
2025-10-15 11:49 ` hiro
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: noodle via 9fans @ 2025-10-14 7:27 UTC (permalink / raw)
To: 9fans
i got ircsrv to automatically authenticate via PASS and/or NickServ
through factotum and added a joinlist option. i haven't written much
C in years so comments/criticism welcome :)
apologies for the sloppy patch + the 60 second sleep (might lower it i
guess). i also should've split it into multiple commits but thought
yall would like to see it. it connects well and i can chat so far.
haven't used it for a while to uncover any hidden bugs
thank u
--
noodle
---
diff ef4697c47cda464feb2fb57fcedf9453eb0bfddc 37e5da47095c2e3d7ab843988decc0c6cd32fc83
--- a/irc.man
+++ b/irc.man
@@ -4,7 +4,7 @@
.SH SYNOPSIS
.B ircsrv
[
-.I -e
+.I -eip
]
[
.I -s service
@@ -13,7 +13,7 @@
.I -f file
]
[
-.I -p pass
+.I -j joinlist
]
.I nickname
.I [net!]irc.server.org[!port]
@@ -79,6 +79,18 @@
The
.I -e
flag enables SSL, the
+.I -f
+flag sets the pathname of the log file, the
+.I -j
+flag sets a list of channels to join (ex: -j '#aaa,#bbb,#ccc'), the
+.I -s
+flag sets the filename of the service file under /srv,
+.I -i
+flag sends a password to NickServ (from factotum service=ircsrv) after connecting to server and enables SSL, the
+.I -p
+flag is like the
+.I -i
+flag but sends the password to the server on connection instead (both can be combined), the
.I -c
flag sets character set conversion using
.IR tcs (1),
--- a/ircsrv.c
+++ b/ircsrv.c
@@ -3,6 +3,8 @@
#include <auth.h>
#include <libsec.h>
+enum { ReconDelay = 60 }; /* time in seconds to sleep before reconnecting to server */
+
char *post;
char *file;
int ircfd = -1; // the irc server
@@ -10,23 +12,27 @@
int enctls = 0; // ssl/tls
QLock lck;
+UserPasswd *pass = nil;
+UserPasswd *nickpass = nil;
+char *chans = nil;
+char *host;
char *server;
-char *passwd;
char *nickname;
-char *realname;
-char *username;
-char *mode = "foo";
-char *unused = "bar";
+char *realname = nil;
+char *username = nil;
+char *port = "6667";
void ircsrv(void);
void logger(void);
void die(void*, char*);
void reconnect(void);
+void authnick(void);
+void joinchans(void);
void
usage(void)
{
- fprint(2, "usage: %s [-e] [-s service] [-f file] [-p pass] nickname [net!]ircserver[!port]\n", argv0);
+ fprint(2, "usage: %s [-eip] [-f file] [-j join] [-s service] [ -r realname ] [ -u username ] nickname [net!]ircserver[!port]\n", argv0);
exits("usage");
}
@@ -50,13 +56,17 @@
void
main(int argc, char *argv[])
{
- char *tmp;
- int p[2], fd;
+ char *netaddr[3];
+ int getpass = 0, getnickpass = 0;
+ int nf, p[2], fd;
ARGBEGIN{
case 'f':
file = EARGF(usage());
break;
+ case 'j':
+ chans = EARGF(usage());
+ break;
case 's':
post = EARGF(usage());
break;
@@ -63,19 +73,20 @@
case 'r':
realname = EARGF(usage());
break;
+ case 'u':
+ username = EARGF(usage());
+ break;
case 'e':
enctls = 1;
break;
case 'p':
- passwd = EARGF(usage());
- /* try to obfuscate the password so ps -a won't see it */
- tmp = passwd;
- passwd = smprint("%s", tmp);
- if(passwd)
- memset(tmp, '\0', strlen(tmp));
- else
- passwd = tmp;
+ getpass = 1;
+ enctls = 1;
break;
+ case 'i':
+ getnickpass = 1;
+ enctls = 1;
+ break;
default:
usage();
}ARGEND;
@@ -82,16 +93,34 @@
if(argc < 2)
usage();
+ if(enctls)
+ port = "6697";
-
nickname = argv[0];
server = argv[1];
- username = getuser();
+ nf = getfields(server, netaddr, 3, 0, "!");
+ host = nf == 3 ? netaddr[1] : server;
+ if(getpass){
+ pass = auth_getuserpasswd(auth_getkey,
+ "proto=pass service=irc server=%q user=%q", host, nickname);
+ if(pass == nil)
+ sysfatal("auth_getuserpasswd");
+ }
+ if(getnickpass){
+ nickpass = auth_getuserpasswd(auth_getkey,
+ "proto=pass service=ircsrv server=%q user=%q", host, nickname);
+ if(nickpass == nil)
+ sysfatal("auth_getuserpasswd");
+ }
+ if(!username)
+ username = getuser();
if(strlen(username) > 4)
username[4] = '\0';
+ if (!realname)
+ realname = "<nil>";
if(post == nil)
post = smprint("/srv/%sirc", username);
@@ -188,22 +217,51 @@
TLSconn *conn;
if(ircfd >= 0)
close(ircfd);
- if((ircfd = dial(netmkaddr(server, "tcp", "6667"), nil, nil, nil)) < 0)
+ if((ircfd = dial(netmkaddr(server, "tcp", port), nil, nil, nil)) < 0)
sysfatal("dial %r");
- if(enctls > 0) {
+ if(enctls > 0){
conn = (TLSconn *)mallocz(sizeof *conn, 1);
- ircfd = tlsClient(ircfd, conn);
+ ircfd = tlsClient(ircfd, conn);
if (ircfd < 0) { sysfatal ("tls: %r"); }
}
- if(passwd && strcmp(passwd, ""))
- fprint(ircfd, "PASS %s\r\n", passwd);
- fprint(ircfd, "USER %s %s %s :%s\r\n",
- nickname, mode, unused, realname);
+ if(pass && pass->passwd && strcmp(pass->passwd, ""))
+ fprint(ircfd, "PASS %s\r\n", pass->passwd);
+ fprint(ircfd, "USER %s * * :%s\r\n", username, realname);
fprint(ircfd, "NICK %s\r\n", nickname);
+ authnick();
+ joinchans();
}
+void
+joinchans(void)
+{
+ char *s, *e;
+ if(!chans)
+ return;
+ for(s = e = chans; *e; e++)
+ if (*e == ',' && e - s > 0) {
+ fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
+ s = e + 1;
+ }
+ if(e - s > 0)
+ fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
+}
void
+authnick(void){
+ char *labels[3];
+ int nf;
+
+ if(!nickpass || !nickpass->passwd || !strcmp(nickpass->passwd, ""))
+ return;
+ nf = getfields(host, labels, 3, 0, ".");
+ if(nf == 3 && !strcmp(labels[1], "oftc") && !strcmp(labels[2], "net"))
+ fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", nickpass->passwd, nickname);
+ else
+ fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", nickname, nickpass->passwd);
+}
+
+void
logger(void)
{
char buf[513];
@@ -211,6 +269,7 @@
long n;
for(;;){
+ int doreauth = 0;
while((n = readln(ircfd, buf, sizeof(buf)-1)) > 0){
fprint(logfd, "%ld ", time(0));
write(logfd, buf, n);
@@ -221,15 +280,21 @@
fprint(ircfd, "PONG %s\r\n", f[2]);
fprint(logfd, "%ld PONG %s\r\n", time(0), f[2]);
qunlock(&lck);
- } else if(n == 2 && !cistrcmp(f[0], "PING")){
+ }else if(n == 2 && !cistrcmp(f[0], "PING")){
qlock(&lck);
fprint(ircfd, "PONG %s\r\n", f[1]);
fprint(logfd, "%ld PONG %s\r\n", time(0), f[1]);
qunlock(&lck);
- } else if(n == 3 && atoi(f[1]) == 433) {
+ }else if(n == 3 && (atoi(f[1]) == 433 || atoi(f[1]) == 437)){
reregister();
+ doreauth = 1;
+ }else if (doreauth && n == 3 && atoi(f[1]) == 001){
+ authnick();
+ fprint(ircfd, "PRIVMSG NickServ :REGAIN %s\r\n", nickname);
+ joinchans();
}
}
+ sleep(ReconDelay * 1000);
reconnect();
}
}
@@ -251,5 +316,3 @@
}
killall();
}
-
-
--
⑨
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tda2484b041420163-M4bd75d514a2b0a715a99c9de
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects
2025-10-14 7:27 [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects noodle via 9fans
@ 2025-10-15 11:49 ` hiro
2025-10-15 15:30 ` noodle via 9fans
2025-10-15 13:08 ` noodle via 9fans
2025-11-03 1:06 ` noodle via 9fans
2 siblings, 1 reply; 5+ messages in thread
From: hiro @ 2025-10-15 11:49 UTC (permalink / raw)
To: 9fans
pls also consider tls client-certs that oftc and freenode support
this way authentication doesn't happen on irc layer any more.
On Wed, Oct 15, 2025 at 5:31 AM noodle via 9fans <9fans@9fans.net> wrote:
>
> i got ircsrv to automatically authenticate via PASS and/or NickServ
> through factotum and added a joinlist option. i haven't written much
> C in years so comments/criticism welcome :)
>
> apologies for the sloppy patch + the 60 second sleep (might lower it i
> guess). i also should've split it into multiple commits but thought
> yall would like to see it. it connects well and i can chat so far.
> haven't used it for a while to uncover any hidden bugs
>
> thank u
>
> --
> noodle
>
> ---
> diff ef4697c47cda464feb2fb57fcedf9453eb0bfddc 37e5da47095c2e3d7ab843988decc0c6cd32fc83
> --- a/irc.man
> +++ b/irc.man
> @@ -4,7 +4,7 @@
> .SH SYNOPSIS
> .B ircsrv
> [
> -.I -e
> +.I -eip
> ]
> [
> .I -s service
> @@ -13,7 +13,7 @@
> .I -f file
> ]
> [
> -.I -p pass
> +.I -j joinlist
> ]
> .I nickname
> .I [net!]irc.server.org[!port]
> @@ -79,6 +79,18 @@
> The
> .I -e
> flag enables SSL, the
> +.I -f
> +flag sets the pathname of the log file, the
> +.I -j
> +flag sets a list of channels to join (ex: -j '#aaa,#bbb,#ccc'), the
> +.I -s
> +flag sets the filename of the service file under /srv,
> +.I -i
> +flag sends a password to NickServ (from factotum service=ircsrv) after connecting to server and enables SSL, the
> +.I -p
> +flag is like the
> +.I -i
> +flag but sends the password to the server on connection instead (both can be combined), the
> .I -c
> flag sets character set conversion using
> .IR tcs (1),
> --- a/ircsrv.c
> +++ b/ircsrv.c
> @@ -3,6 +3,8 @@
> #include <auth.h>
> #include <libsec.h>
>
> +enum { ReconDelay = 60 }; /* time in seconds to sleep before reconnecting to server */
> +
> char *post;
> char *file;
> int ircfd = -1; // the irc server
> @@ -10,23 +12,27 @@
> int enctls = 0; // ssl/tls
> QLock lck;
>
> +UserPasswd *pass = nil;
> +UserPasswd *nickpass = nil;
> +char *chans = nil;
> +char *host;
> char *server;
> -char *passwd;
> char *nickname;
> -char *realname;
> -char *username;
> -char *mode = "foo";
> -char *unused = "bar";
> +char *realname = nil;
> +char *username = nil;
> +char *port = "6667";
>
> void ircsrv(void);
> void logger(void);
> void die(void*, char*);
> void reconnect(void);
> +void authnick(void);
> +void joinchans(void);
>
> void
> usage(void)
> {
> - fprint(2, "usage: %s [-e] [-s service] [-f file] [-p pass] nickname [net!]ircserver[!port]\n", argv0);
> + fprint(2, "usage: %s [-eip] [-f file] [-j join] [-s service] [ -r realname ] [ -u username ] nickname [net!]ircserver[!port]\n", argv0);
> exits("usage");
> }
>
> @@ -50,13 +56,17 @@
> void
> main(int argc, char *argv[])
> {
> - char *tmp;
> - int p[2], fd;
> + char *netaddr[3];
> + int getpass = 0, getnickpass = 0;
> + int nf, p[2], fd;
>
> ARGBEGIN{
> case 'f':
> file = EARGF(usage());
> break;
> + case 'j':
> + chans = EARGF(usage());
> + break;
> case 's':
> post = EARGF(usage());
> break;
> @@ -63,19 +73,20 @@
> case 'r':
> realname = EARGF(usage());
> break;
> + case 'u':
> + username = EARGF(usage());
> + break;
> case 'e':
> enctls = 1;
> break;
> case 'p':
> - passwd = EARGF(usage());
> - /* try to obfuscate the password so ps -a won't see it */
> - tmp = passwd;
> - passwd = smprint("%s", tmp);
> - if(passwd)
> - memset(tmp, '\0', strlen(tmp));
> - else
> - passwd = tmp;
> + getpass = 1;
> + enctls = 1;
> break;
> + case 'i':
> + getnickpass = 1;
> + enctls = 1;
> + break;
> default:
> usage();
> }ARGEND;
> @@ -82,16 +93,34 @@
>
> if(argc < 2)
> usage();
> + if(enctls)
> + port = "6697";
>
> -
> nickname = argv[0];
> server = argv[1];
>
> - username = getuser();
> + nf = getfields(server, netaddr, 3, 0, "!");
> + host = nf == 3 ? netaddr[1] : server;
> + if(getpass){
> + pass = auth_getuserpasswd(auth_getkey,
> + "proto=pass service=irc server=%q user=%q", host, nickname);
> + if(pass == nil)
> + sysfatal("auth_getuserpasswd");
> + }
> + if(getnickpass){
> + nickpass = auth_getuserpasswd(auth_getkey,
> + "proto=pass service=ircsrv server=%q user=%q", host, nickname);
> + if(nickpass == nil)
> + sysfatal("auth_getuserpasswd");
> + }
>
> + if(!username)
> + username = getuser();
> if(strlen(username) > 4)
> username[4] = '\0';
>
> + if (!realname)
> + realname = "<nil>";
>
> if(post == nil)
> post = smprint("/srv/%sirc", username);
> @@ -188,22 +217,51 @@
> TLSconn *conn;
> if(ircfd >= 0)
> close(ircfd);
> - if((ircfd = dial(netmkaddr(server, "tcp", "6667"), nil, nil, nil)) < 0)
> + if((ircfd = dial(netmkaddr(server, "tcp", port), nil, nil, nil)) < 0)
> sysfatal("dial %r");
> - if(enctls > 0) {
> + if(enctls > 0){
> conn = (TLSconn *)mallocz(sizeof *conn, 1);
> - ircfd = tlsClient(ircfd, conn);
> + ircfd = tlsClient(ircfd, conn);
> if (ircfd < 0) { sysfatal ("tls: %r"); }
> }
> - if(passwd && strcmp(passwd, ""))
> - fprint(ircfd, "PASS %s\r\n", passwd);
> - fprint(ircfd, "USER %s %s %s :%s\r\n",
> - nickname, mode, unused, realname);
> + if(pass && pass->passwd && strcmp(pass->passwd, ""))
> + fprint(ircfd, "PASS %s\r\n", pass->passwd);
> + fprint(ircfd, "USER %s * * :%s\r\n", username, realname);
> fprint(ircfd, "NICK %s\r\n", nickname);
> + authnick();
> + joinchans();
> }
>
> +void
> +joinchans(void)
> +{
> + char *s, *e;
> + if(!chans)
> + return;
> + for(s = e = chans; *e; e++)
> + if (*e == ',' && e - s > 0) {
> + fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
> + s = e + 1;
> + }
> + if(e - s > 0)
> + fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
> +}
>
> void
> +authnick(void){
> + char *labels[3];
> + int nf;
> +
> + if(!nickpass || !nickpass->passwd || !strcmp(nickpass->passwd, ""))
> + return;
> + nf = getfields(host, labels, 3, 0, ".");
> + if(nf == 3 && !strcmp(labels[1], "oftc") && !strcmp(labels[2], "net"))
> + fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", nickpass->passwd, nickname);
> + else
> + fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", nickname, nickpass->passwd);
> +}
> +
> +void
> logger(void)
> {
> char buf[513];
> @@ -211,6 +269,7 @@
> long n;
>
> for(;;){
> + int doreauth = 0;
> while((n = readln(ircfd, buf, sizeof(buf)-1)) > 0){
> fprint(logfd, "%ld ", time(0));
> write(logfd, buf, n);
> @@ -221,15 +280,21 @@
> fprint(ircfd, "PONG %s\r\n", f[2]);
> fprint(logfd, "%ld PONG %s\r\n", time(0), f[2]);
> qunlock(&lck);
> - } else if(n == 2 && !cistrcmp(f[0], "PING")){
> + }else if(n == 2 && !cistrcmp(f[0], "PING")){
> qlock(&lck);
> fprint(ircfd, "PONG %s\r\n", f[1]);
> fprint(logfd, "%ld PONG %s\r\n", time(0), f[1]);
> qunlock(&lck);
> - } else if(n == 3 && atoi(f[1]) == 433) {
> + }else if(n == 3 && (atoi(f[1]) == 433 || atoi(f[1]) == 437)){
> reregister();
> + doreauth = 1;
> + }else if (doreauth && n == 3 && atoi(f[1]) == 001){
> + authnick();
> + fprint(ircfd, "PRIVMSG NickServ :REGAIN %s\r\n", nickname);
> + joinchans();
> }
> }
> + sleep(ReconDelay * 1000);
> reconnect();
> }
> }
> @@ -251,5 +316,3 @@
> }
> killall();
> }
> -
> -
> --
> ⑨
>
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tda2484b041420163-Mb4b0969075a840df49196b2e
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects
2025-10-14 7:27 [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects noodle via 9fans
2025-10-15 11:49 ` hiro
@ 2025-10-15 13:08 ` noodle via 9fans
2025-11-03 1:06 ` noodle via 9fans
2 siblings, 0 replies; 5+ messages in thread
From: noodle via 9fans @ 2025-10-15 13:08 UTC (permalink / raw)
To: 9fans
sorry i forgot to specify that i'm patching on top of
https://github.com/pete/irc7 so the patch won't apply on the 9p.io or
https://code.9front.org/hg/irc7 versions. i sent another diff below
that applies on top of https://code.9front.org/hg/irc7 commit
6c4572b47d06d30b86d2aab66c8ef5d666608929 without trouble.
(code.9front.org looks offline right now; bad timing :b). the 9p.io
version seems to not have TLS support so adding authentication to it
is counterintuitive
after some use, i can confirm it automatically authenticates to
liberachat and oftc without trouble. (a friend says it has trouble
connecting to ircnow but we haven't figured it out yet. seems their
nickserv has a quirk). the joinlist works well too.
it's still rough around the edges with it forgetting to reconnect from
time to time and having to monitor all dms to not miss messages (the
latter problem seems to be solved by the pete version but i haven't
tested their patches much. i posted the last patch then after i
realized i sent an unapply-able patch i reverted pete's diffs on my
version for tha time. i should test the more).
ircs seems to handle dms and reconnection well (except when
reconnecting to oftc for some reason) but it's code is complex to hack
on.
--
noodle
---
diff 4e3135c90cc6de1bb782fce03d17d1d1a9dd5876 7106744269a9b3af0fba432ae8de47cbcd9f8ead
--- a/irc.man
+++ b/irc.man
@@ -4,7 +4,7 @@
.SH SYNOPSIS
.B ircsrv
[
-.I -e
+.I -eip
]
[
.I -s service
@@ -13,7 +13,7 @@
.I -f file
]
[
-.I -p pass
+.I -j joinlist
]
.I nickname
.I [net!]irc.server.org[!port]
@@ -75,6 +75,18 @@
The
.I -e
flag enables SSL, the
+.I -f
+flag sets the pathname of the log file, the
+.I -j
+flag sets a list of channels to join (ex: -j '#aaa,#bbb,#ccc'), the
+.I -s
+flag sets the filename of the service file under /srv,
+.I -i
+flag sends a password to NickServ (from factotum service=ircsrv) after connecting to server and enables SSL, the
+.I -p
+flag is like the
+.I -i
+flag but sends the password to the server on connection instead (both can be combined), the
.I -c
flag sets character set conversion using
.IR tcs (1),
--- a/ircsrv.c
+++ b/ircsrv.c
@@ -3,6 +3,8 @@
#include <auth.h>
#include <libsec.h>
+enum { ReconDelay = 60 }; /* time in seconds to sleep before reconnecting to server */
+
char *post;
char *file;
int ircfd = -1; // the irc server
@@ -10,23 +12,27 @@
int enctls = 0; // ssl/tls
QLock lck;
+UserPasswd *pass = nil;
+UserPasswd *nickpass = nil;
+char *chans = nil;
+char *host;
char *server;
-char *passwd;
char *nickname;
-char *realname;
-char *username;
-char *mode = "foo";
-char *unused = "bar";
+char *realname = nil;
+char *username = nil;
+char *port = "6667";
void ircsrv(void);
void logger(void);
void die(void*, char*);
void reconnect(void);
+void authnick(void);
+void joinchans(void);
void
usage(void)
{
- fprint(2, "usage: %s [-e] [-s service] [-f file] [-p pass] nickname [net!]ircserver[!port]\n", argv0);
+ fprint(2, "usage: %s [-eip] [-f file] [-j join] [-s service] [ -r realname ] [ -u username ] nickname [net!]ircserver[!port]\n", argv0);
exits("usage");
}
@@ -50,13 +56,17 @@
void
main(int argc, char *argv[])
{
- char *tmp;
- int p[2], fd;
+ char *netaddr[3];
+ int getpass = 0, getnickpass = 0;
+ int nf, p[2], fd;
ARGBEGIN{
case 'f':
file = EARGF(usage());
break;
+ case 'j':
+ chans = EARGF(usage());
+ break;
case 's':
post = EARGF(usage());
break;
@@ -63,19 +73,20 @@
case 'r':
realname = EARGF(usage());
break;
+ case 'u':
+ username = EARGF(usage());
+ break;
case 'e':
enctls = 1;
break;
case 'p':
- passwd = EARGF(usage());
- /* try to obfuscate the password so ps -a won't see it */
- tmp = passwd;
- passwd = smprint("%s", tmp);
- if(passwd)
- memset(tmp, '\0', strlen(tmp));
- else
- passwd = tmp;
+ getpass = 1;
+ enctls = 1;
break;
+ case 'i':
+ getnickpass = 1;
+ enctls = 1;
+ break;
default:
usage();
}ARGEND;
@@ -82,16 +93,34 @@
if(argc < 2)
usage();
+ if(enctls)
+ port = "6697";
-
nickname = argv[0];
server = argv[1];
- username = getuser();
+ nf = getfields(server, netaddr, 3, 0, "!");
+ host = nf == 3 ? netaddr[1] : server;
+ if(getpass){
+ pass = auth_getuserpasswd(auth_getkey,
+ "proto=pass service=irc server=%q user=%q", host, nickname);
+ if(pass == nil)
+ sysfatal("auth_getuserpasswd");
+ }
+ if(getnickpass){
+ nickpass = auth_getuserpasswd(auth_getkey,
+ "proto=pass service=ircsrv server=%q user=%q", host, nickname);
+ if(nickpass == nil)
+ sysfatal("auth_getuserpasswd");
+ }
+ if(!username)
+ username = getuser();
if(strlen(username) > 4)
username[4] = '\0';
+ if (!realname)
+ realname = "<nil>";
if(post == nil)
post = smprint("/srv/%sirc", username);
@@ -188,22 +217,51 @@
TLSconn *conn;
if(ircfd >= 0)
close(ircfd);
- if((ircfd = dial(netmkaddr(server, "tcp", "6667"), nil, nil, nil)) < 0)
+ if((ircfd = dial(netmkaddr(server, "tcp", port), nil, nil, nil)) < 0)
sysfatal("dial %r");
- if(enctls > 0) {
+ if(enctls > 0){
conn = (TLSconn *)mallocz(sizeof *conn, 1);
- ircfd = tlsClient(ircfd, conn);
+ ircfd = tlsClient(ircfd, conn);
if (ircfd < 0) { sysfatal ("tls: %r"); }
}
- if(passwd && strcmp(passwd, ""))
- fprint(ircfd, "PASS %s\r\n", passwd);
- fprint(ircfd, "USER %s %s %s :%s\r\n",
- nickname, mode, unused, realname);
+ if(pass && pass->passwd && strcmp(pass->passwd, ""))
+ fprint(ircfd, "PASS %s\r\n", pass->passwd);
+ fprint(ircfd, "USER %s * * :%s\r\n", username, realname);
fprint(ircfd, "NICK %s\r\n", nickname);
+ authnick();
+ joinchans();
}
+void
+joinchans(void)
+{
+ char *s, *e;
+ if(!chans)
+ return;
+ for(s = e = chans; *e; e++)
+ if (*e == ',' && e - s > 0) {
+ fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
+ s = e + 1;
+ }
+ if(e - s > 0)
+ fprint(ircfd, "JOIN %.*s\r\n", (int) (e - s), s);
+}
void
+authnick(void){
+ char *labels[3];
+ int nf;
+
+ if(!nickpass || !nickpass->passwd || !strcmp(nickpass->passwd, ""))
+ return;
+ nf = getfields(host, labels, 3, 0, ".");
+ if(nf == 3 && !strcmp(labels[1], "oftc") && !strcmp(labels[2], "net"))
+ fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", nickpass->passwd, nickname);
+ else
+ fprint(ircfd, "PRIVMSG NickServ :IDENTIFY %s %s\r\n", nickname, nickpass->passwd);
+}
+
+void
logger(void)
{
char buf[513];
@@ -211,6 +269,7 @@
long n;
for(;;){
+ int doreauth = 0;
while((n = readln(ircfd, buf, sizeof(buf)-1)) > 0){
fprint(logfd, "%ld ", time(0));
write(logfd, buf, n);
@@ -221,15 +280,21 @@
fprint(ircfd, "PONG %s\r\n", f[2]);
fprint(logfd, "%ld PONG %s\r\n", time(0), f[2]);
qunlock(&lck);
- } else if(n == 2 && !cistrcmp(f[0], "PING")){
+ }else if(n == 2 && !cistrcmp(f[0], "PING")){
qlock(&lck);
fprint(ircfd, "PONG %s\r\n", f[1]);
fprint(logfd, "%ld PONG %s\r\n", time(0), f[1]);
qunlock(&lck);
- } else if(n == 3 && atoi(f[1]) == 433) {
+ }else if(n == 3 && (atoi(f[1]) == 433 || atoi(f[1]) == 437)){
reregister();
+ doreauth = 1;
+ }else if (doreauth && n == 3 && atoi(f[1]) == 001){
+ authnick();
+ fprint(ircfd, "PRIVMSG NickServ :REGAIN %s\r\n", nickname);
+ joinchans();
}
}
+ sleep(ReconDelay * 1000);
reconnect();
}
}
@@ -251,5 +316,3 @@
}
killall();
}
-
-
--
⑨
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tda2484b041420163-M836f7ba4f98bd81120bd567d
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects
2025-10-15 11:49 ` hiro
@ 2025-10-15 15:30 ` noodle via 9fans
0 siblings, 0 replies; 5+ messages in thread
From: noodle via 9fans @ 2025-10-15 15:30 UTC (permalink / raw)
To: 9fans
Quoth hiro <23hiro@gmail.com>:
> pls also consider tls client-certs that oftc and freenode support
> this way authentication doesn't happen on irc layer any more.
>
o idk how they work yet but will look into those thx! (btw check my
reply to top mail. i had a diverged tree so it didn't apply well to
code.9front.org's irc7. 2nd diff should apply)
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tda2484b041420163-M2088e96dda9116de2ba6a330
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects
2025-10-14 7:27 [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects noodle via 9fans
2025-10-15 11:49 ` hiro
2025-10-15 13:08 ` noodle via 9fans
@ 2025-11-03 1:06 ` noodle via 9fans
2 siblings, 0 replies; 5+ messages in thread
From: noodle via 9fans @ 2025-11-03 1:06 UTC (permalink / raw)
To: 9fans
small fix to userpasswd query strings to have service name be "irc"
for NickServ and "ircsrv" for server PASSWD. aligns with usage in
wircrc (my bad for the mistake)
i don't use irc7 much now but if i end up patching more i'll host a
repo and link to it on this thread i guess
---
diff 9cebd95b12b4f71a542911ec23ff713c1cb331e4 e5cfbd2589a1ba03cc69445c540c89c88c1123d9
--- a/ircsrv.c
+++ b/ircsrv.c
@@ -103,13 +103,13 @@
host = nf == 3 ? netaddr[1] : server;
if(getpass){
pass = auth_getuserpasswd(auth_getkey,
- "proto=pass service=irc server=%q user=%q", host, nickname);
+ "proto=pass service=ircsrv server=%q user=%q", host, nickname);
if(pass == nil)
sysfatal("auth_getuserpasswd");
}
if(getnickpass){
nickpass = auth_getuserpasswd(auth_getkey,
- "proto=pass service=ircsrv server=%q user=%q", host, nickname);
+ "proto=pass service=irc server=%q user=%q", host, nickname);
if(nickpass == nil)
sysfatal("auth_getuserpasswd");
}
--
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tda2484b041420163-Mcbe4c69aed707e877ae508f6
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-03 2:13 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-14 7:27 [9fans] [PATCH] ircsrv: Add server PASS and NickServ factotum auth, joinlist, and 60sec sleep between reconnects noodle via 9fans
2025-10-15 11:49 ` hiro
2025-10-15 15:30 ` noodle via 9fans
2025-10-15 13:08 ` noodle via 9fans
2025-11-03 1:06 ` noodle via 9fans
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).