ref: 2ab93fd7168a7d0ad8e1bc19f4e9cbee45237c99
dir: /utotp.c/
#include <u.h> #include <libc.h> #include <auth.h> #include <libsec.h> #define FValueLen 32 #define SecretLen 4096 #define TotpMKeyLen 4096 char *argv0; char provider[FValueLen], account[FValueLen]; void beput8(uchar *buf, u64int v) { buf[7] = v & 0xff; v >>= 8; buf[6] = v & 0xff; v >>= 8; buf[5] = v & 0xff; v >>= 8; buf[4] = v & 0xff; v >>= 8; buf[3] = v & 0xff; v >>= 8; buf[2] = v & 0xff; v >>= 8; buf[1] = v & 0xff; v >>= 8; buf[0] = v & 0xff; } u32int beget4(uchar *buf) { return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24; } u32int gettoken(char *secret) { ulong ts; u32int token; long keylen; uchar key[TotpMKeyLen], digest[SHA1dlen], buf[8], offset; ts = (ulong)time(nil) / 30; keylen = dec32(key, TotpMKeyLen, secret, strlen(secret)); beput8(buf, ts); hmac_sha1(buf, 8, key, keylen, digest, nil); offset = digest[SHA1dlen - 1] & 0x0f; token = beget4(&digest[offset]); token &= 0x7fffffff; token %= 1000000; return token; } char* getsecret(void) { UserPasswd *up; char *secret; up = auth_getuserpasswd(auth_getkey, "proto=pass totp=%s user=%s", provider, account); if(up == nil) return nil; secret = malloc(sizeof(char) * SecretLen); strcpy(secret, up->passwd); return secret; } void usage(void) { fprint(2, "usage: %s provider account\n", argv0); exits("usage"); } void main(int argc, char **argv) { u32int token; char *secret; argv0 = argv[0]; if(argc != 3) usage(); strcpy(provider, argv[1]); strcpy(account, argv[2]); if((secret = getsecret()) == nil) { fprint(2, "unable to find secret\n"); exits("nocreds\n"); } token = gettoken(secret); print("%06ud\n", token); }