commit f31cd5a448ae963454d16aeaaf1766feff159bfa from: Omar Polo date: Mon Jan 16 13:03:23 2023 UTC totp: extract the secret from otpauth:// URIs More often than not, services provide the URI for TOTP and not the raw secret. While it's easy to manually extract the secret from the querystring, teach totp how to do that on behalf of the user. Manpage bits will follow. Discussed with heph. commit - 87986040c34281a3660bec9a65057f5a6aabfd1d commit + f31cd5a448ae963454d16aeaaf1766feff159bfa blob - c44a7fcb1e7af1dbd2a1bdb9efc83c8237e8c13b blob + b201ae6ed769bb76d9c28d34bbfb8ba97dcb80fa --- totp.c +++ totp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Omar Polo + * Copyright (c) 2022, 2023 Omar Polo * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -95,6 +95,23 @@ b32decode(const char *s, char *q, size_t qlen) return (q - t); } +static int +uri2secret(char *s) +{ + char *q, *t; + + if ((q = strchr(s, '?')) == NULL) + return (-1); + if ((t = strstr(q, "?secret=")) == NULL && + (t = strstr(q, "&secret=")) == NULL) + return (-1); + t += 8; + while (*t != '\0' && *t != '&' && *t != '#') + *s++ = *t++; + *s = '\0'; + return (0); +} + int main(int argc, char **argv) { @@ -142,6 +159,9 @@ main(int argc, char **argv) if (linelen < 1) errx(1, "no secret provided"); + if (!strncmp(line, "otpauth://", 10) && uri2secret(line) == -1) + errx(1, "failed to decode otpauth URI"); + if ((buflen = b32decode(line, buf, sizeof(buf))) == 0) err(1, "can't base32 decode the secret");