From 776fc1cccb2e17799528b35864f64ab0ef7ebfd2 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Thu, 3 Mar 2022 21:29:16 -0500 Subject: Prompt for account password --- enroll.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 10 deletions(-) diff --git a/enroll.c b/enroll.c index ac97414..9776e80 100644 --- a/enroll.c +++ b/enroll.c @@ -122,6 +122,47 @@ static int yesno(bool *resp, bool def, const char *format, ...) { } } +static int password(char **resp, bool confirm, const char *format, ...) +__attribute__((format(printf, 3, 4))); +static int password(char **resp, bool confirm, const char *format, ...) { + va_list ap; + char desc[1024]; + va_start(ap, format); + vsnprintf(desc, sizeof(desc), format, ap); + va_end(ap); + + enum { Cap = 1024 }; + char *buf1 = malloc(Cap); + if (!buf1) err(EX_OSERR, "malloc"); + + char *buf2 = NULL; + if (confirm) { + buf2 = malloc(Cap); + if (!buf2) errx(EX_OSERR, "malloc"); + } + + for (;;) { + *resp = readpassphrase(desc, buf1, Cap, 0); + if (!*resp) errx(EX_IOERR, "could not read passphrase"); + if (!buf1[0]) { + *resp = NULL; + free(buf1); + free(buf2); + return -1; + } + if (!confirm) return 0; + + *resp = readpassphrase("Confirm password: ", buf2, Cap, 0); + if (!*resp) errx(EX_IOERR, "could not read passphrase"); + if (!strcmp(buf2, buf1)) { + explicit_bzero(buf1, Cap); + free(buf1); + return 0; + } + printf("Passwords do not match.\n"); + } +} + static struct { char *network; char *config; @@ -130,7 +171,10 @@ static struct { struct addrinfo *addr; struct tls_config *tls; char *trust; - char *account; + struct { + char *name; + char *pass; + } account; char *nick; char *pronouns; } info; @@ -426,24 +470,29 @@ fail: return -1; } -static int getAccount(void) { +static int getAccountName(void) { int pop = prompt( - &info.account, "", + &info.account.name, "", "If you already have an account on %s, what is its name?\n" "If you have a NickServ account already, enter the name of the\n" "account. If you aren't sure, leave this blank.\n", info.network ); if (pop) return pop; - if (!info.account[0]) return 0; + if (!info.account.name[0]) return 0; - info.nick = strdup(info.account); + info.nick = strdup(info.account.name); if (!info.nick) err(EX_OSERR, "strdup"); - - // TODO: Prompt for account password. return 0; } +static int getAccountPass(void) { + return password( + &info.account.pass, false, + "Password for %s on %s: ", info.account.name, info.network + ); +} + static int getNick(void) { return prompt( &info.nick, getenv("USER"), @@ -527,8 +576,8 @@ int main(int argc, char *argv[]) { unset(&info.host); unset(&info.port); } - } else if (!info.account) { - pop = getAccount(); + } else if (!info.account.name) { + pop = getAccountName(); if (pop) { unset(&info.trust); freeaddrinfo(info.addr); @@ -536,9 +585,15 @@ int main(int argc, char *argv[]) { unset(&info.host); unset(&info.port); } + } else if (info.account.name[0] && !info.account.pass) { + pop = getAccountPass(); + if (pop) unset(&info.account.name); } else if (!info.nick) { pop = getNick(); - if (pop) unset(&info.account); + if (pop) { + unset(&info.account.name); + unset(&info.account.pass); + } } else if (!info.pronouns) { pop = getPronouns(); if (pop) unset(&info.nick); @@ -559,6 +614,25 @@ int main(int argc, char *argv[]) { if (info.trust) { fprintf(file, "trust = %s.pem\n", info.host); } + + // TODO: Check for CertFP instead. + bool saslPass; + pop = yesno( + &saslPass, true, + "Would you like to save your account password?\n" + "If yes, your account password will be written to the configuration\n" + "file and sent automatically using SASL when catgirl connects.\n" + "Otherwise, only your account name will be saved, and catgirl will\n" + "prompt you for the password every time.\n" + ); + if (!pop && saslPass) { + fprintf( + file, "sasl-plain = %s:%s\n", info.account.name, info.account.pass + ); + } else { + fprintf(file, "sasl-plain = %s:\n", info.account.name); + } + fprintf(file, "nick = %s\n", info.nick); if (strlen(info.pronouns) > 1) { fprintf(file, "real = %s [%s]\n", info.nick, info.pronouns); -- cgit 1.4.1