summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJune McEnroe2022-02-12 13:26:38 -0500
committerJune McEnroe2022-02-12 13:26:38 -0500
commit397b4ce6bd9064aa36f8b9c264e4bbc226822d6f (patch)
treea8f45e286765c4bab90cf561cd7762ebed5114e7
parent9c384de6dbe526374af5075e06260063a9764cb9 (diff)
Prompt for empty server or SASL passwords
-rw-r--r--catgirl.113
-rw-r--r--chat.c24
-rw-r--r--chat.h3
-rw-r--r--handle.c18
4 files changed, 42 insertions, 16 deletions
diff --git a/catgirl.1 b/catgirl.1
index 34b9718..065002b 100644
--- a/catgirl.1
+++ b/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
diff --git a/chat.c b/chat.c
index ba6c9a1..4898411 100644
--- a/chat.c
+++ b/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, "@+");
diff --git a/chat.h b/chat.h
index 19d2b18..753d1a3 100644
--- a/chat.h
+++ b/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;
diff --git a/handle.c b/handle.c
index e460c7c..d663ca1 100644
--- a/handle.c
+++ b/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) {