Prompt for empty server or SASL passwords
parent
9c384de6db
commit
397b4ce6bd
13
catgirl.1
13
catgirl.1
|
@ -1,4 +1,4 @@
|
|||
.Dd February 3, 2022
|
||||
.Dd February 12, 2022
|
||||
.Dt CATGIRL 1
|
||||
.Os
|
||||
.
|
||||
|
@ -222,11 +222,9 @@ Authenticate as
|
|||
with
|
||||
.Ar pass
|
||||
using SASL PLAIN.
|
||||
Since this requires the account password
|
||||
in plain text,
|
||||
it is recommended to use CertFP instead.
|
||||
See
|
||||
.Sx Configuring CertFP .
|
||||
Leave
|
||||
.Ar pass
|
||||
blank to prompt for the password.
|
||||
.
|
||||
.It Fl c Ar path | Cm cert No = Ar path
|
||||
Load the TLS client certificate from
|
||||
|
@ -375,6 +373,9 @@ if it is not a terminal.
|
|||
.It Fl w Ar pass | Cm pass No = Ar pass
|
||||
Log in with the server password
|
||||
.Ar pass .
|
||||
Leave
|
||||
.Ar pass
|
||||
blank to prompt for the password.
|
||||
.El
|
||||
.
|
||||
.Ss Configuring CertFP
|
||||
|
|
24
chat.c
24
chat.c
|
@ -50,6 +50,8 @@
|
|||
#include <capsicum_helpers.h>
|
||||
#endif
|
||||
|
||||
char *readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags);
|
||||
|
||||
#include "chat.h"
|
||||
|
||||
#ifndef OPENSSL_BIN
|
||||
|
@ -131,6 +133,12 @@ static void parseHash(char *str) {
|
|||
if (*str) hashBound = strtoul(&str[1], NULL, 0);
|
||||
}
|
||||
|
||||
static void parsePlain(char *str) {
|
||||
self.plainUser = strsep(&str, ":");
|
||||
if (!str) errx(EX_USAGE, "SASL PLAIN missing colon");
|
||||
self.plainPass = str;
|
||||
}
|
||||
|
||||
static volatile sig_atomic_t signals[NSIG];
|
||||
static void signalHandler(int signal) {
|
||||
signals[signal] = 1;
|
||||
|
@ -288,7 +296,7 @@ int main(int argc, char *argv[]) {
|
|||
uiTime.enable = true;
|
||||
if (optarg) uiTime.format = optarg;
|
||||
}
|
||||
break; case 'a': sasl = true; self.plain = optarg;
|
||||
break; case 'a': sasl = true; parsePlain(optarg);
|
||||
break; case 'c': cert = optarg;
|
||||
break; case 'e': sasl = true;
|
||||
break; case 'g': genCert(optarg);
|
||||
|
@ -337,6 +345,20 @@ int main(int argc, char *argv[]) {
|
|||
user = hash;
|
||||
}
|
||||
|
||||
if (pass && !pass[0]) {
|
||||
char *buf = malloc(512);
|
||||
if (!buf) err(EX_OSERR, "malloc");
|
||||
pass = readpassphrase("Server password: ", buf, 512, 0);
|
||||
if (!pass) errx(EX_IOERR, "unable to read passphrase");
|
||||
}
|
||||
|
||||
if (self.plainPass && !self.plainPass[0]) {
|
||||
char *buf = malloc(512);
|
||||
if (!buf) err(EX_OSERR, "malloc");
|
||||
self.plainPass = readpassphrase("Account password: ", buf, 512, 0);
|
||||
if (!self.plainPass) errx(EX_IOERR, "unable to read passphrase");
|
||||
}
|
||||
|
||||
// Modes defined in RFC 1459:
|
||||
set(&network.chanTypes, "#&");
|
||||
set(&network.prefixes, "@+");
|
||||
|
|
3
chat.h
3
chat.h
|
@ -193,7 +193,8 @@ extern struct Self {
|
|||
bool restricted;
|
||||
size_t pos;
|
||||
enum Cap caps;
|
||||
char *plain;
|
||||
char *plainUser;
|
||||
char *plainPass;
|
||||
char *mode;
|
||||
char *join;
|
||||
char *nick;
|
||||
|
|
18
handle.c
18
handle.c
|
@ -164,7 +164,9 @@ static void handleCap(struct Message *msg) {
|
|||
} else if (!strcmp(msg->params[1], "ACK")) {
|
||||
self.caps |= caps;
|
||||
if (caps & CapSASL) {
|
||||
ircFormat("AUTHENTICATE %s\r\n", (self.plain ? "PLAIN" : "EXTERNAL"));
|
||||
ircFormat(
|
||||
"AUTHENTICATE %s\r\n", (self.plainUser ? "PLAIN" : "EXTERNAL")
|
||||
);
|
||||
}
|
||||
if (!(self.caps & CapSASL)) ircFormat("CAP END\r\n");
|
||||
} else if (!strcmp(msg->params[1], "NAK")) {
|
||||
|
@ -203,18 +205,18 @@ static void base64(char *dst, const byte *src, size_t len) {
|
|||
|
||||
static void handleAuthenticate(struct Message *msg) {
|
||||
(void)msg;
|
||||
if (!self.plain) {
|
||||
if (!self.plainUser) {
|
||||
ircFormat("AUTHENTICATE +\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
byte buf[299] = {0};
|
||||
size_t len = 1 + strlen(self.plain);
|
||||
size_t userLen = strlen(self.plainUser);
|
||||
size_t passLen = strlen(self.plainPass);
|
||||
size_t len = 1 + userLen + 1 + passLen;
|
||||
if (sizeof(buf) < len) errx(EX_USAGE, "SASL PLAIN is too long");
|
||||
memcpy(&buf[1], self.plain, len - 1);
|
||||
byte *sep = memchr(buf, ':', len);
|
||||
if (!sep) errx(EX_USAGE, "SASL PLAIN missing colon");
|
||||
*sep = 0;
|
||||
memcpy(&buf[1], self.plainUser, userLen);
|
||||
memcpy(&buf[1 + userLen + 1], self.plainPass, passLen);
|
||||
|
||||
char b64[BASE64_SIZE(sizeof(buf))];
|
||||
base64(b64, buf, len);
|
||||
|
@ -224,7 +226,7 @@ static void handleAuthenticate(struct Message *msg) {
|
|||
|
||||
explicit_bzero(b64, sizeof(b64));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
explicit_bzero(self.plain, strlen(self.plain));
|
||||
explicit_bzero(self.plainPass, strlen(self.plainPass));
|
||||
}
|
||||
|
||||
static void handleReplyLoggedIn(struct Message *msg) {
|
||||
|
|
Loading…
Reference in New Issue