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);
}