mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
2fa: new command
This commit is contained in:
parent
5eb3e39156
commit
7caa350950
1 changed files with 165 additions and 0 deletions
165
src/cmd/auth/2fa.c
Normal file
165
src/cmd/auth/2fa.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <auth.h>
|
||||
#include <fcall.h>
|
||||
#include <thread.h>
|
||||
#include <9pclient.h>
|
||||
#include <bio.h>
|
||||
|
||||
#define nelems(a) (sizeof(a)/sizeof((a)[0]))
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: %s [-w code] [fmt]\n", argv0);
|
||||
threadexits("usage");
|
||||
}
|
||||
|
||||
static int
|
||||
dorpc(AuthRpc *rpc, char *verb, char *val)
|
||||
{
|
||||
int ret, len;
|
||||
|
||||
len = 0;
|
||||
if(val != nil)
|
||||
len = strlen(val);
|
||||
for(;;){
|
||||
if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
|
||||
return ret;
|
||||
if(auth_getkey(rpc->arg) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
getcode(AuthRpc *rpc, char *params)
|
||||
{
|
||||
if(dorpc(rpc, "start", params) != ARok)
|
||||
sysfatal("auth_rpc start: %r");
|
||||
if(dorpc(rpc, "read", nil) != ARok)
|
||||
sysfatal("auth_rpc: %r");
|
||||
rpc->arg[rpc->narg] = '\0';
|
||||
return rpc->arg;
|
||||
}
|
||||
|
||||
int
|
||||
verifycode(AuthRpc *rpc, char *params, char *code)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(dorpc(rpc, "start", params) != ARok)
|
||||
sysfatal("auth_rpc start: %r");
|
||||
ret = dorpc(rpc, "write", code);
|
||||
if(ret < 0)
|
||||
sysfatal("auth_rpc: write %s: %r", code);
|
||||
return ret != ARok;
|
||||
}
|
||||
|
||||
typedef struct Params Params;
|
||||
struct Params
|
||||
{
|
||||
char *proto;
|
||||
char *user;
|
||||
char *dom;
|
||||
};
|
||||
|
||||
void
|
||||
parseparams(char *s, Params *p)
|
||||
{
|
||||
char *a[10];
|
||||
int n, i;
|
||||
|
||||
n = tokenize(s, a, nelems(a));
|
||||
for(i = 0; i < n; i++)
|
||||
if(strncmp(a[i], "proto=", 6) == 0)
|
||||
p->proto = a[i]+6;
|
||||
else if(strncmp(a[i], "user=", 5) == 0)
|
||||
p->user = a[i]+5;
|
||||
else if(strncmp(a[i], "dom=", 4) == 0)
|
||||
p->dom = a[i]+4;
|
||||
}
|
||||
|
||||
void
|
||||
list(void)
|
||||
{
|
||||
CFsys *fs;
|
||||
int fd;
|
||||
char *s, *params;
|
||||
Biobuf b;
|
||||
AuthRpc *rpc;
|
||||
Params p;
|
||||
|
||||
fs = nsamount("factotum", nil);
|
||||
if(fs == nil)
|
||||
sysfatal("mount: %r");
|
||||
fd = fsopenfd(fs, "ctl", OREAD);
|
||||
if(fd < 0)
|
||||
sysfatal("open: %r");
|
||||
Binit(&b, fd, OREAD);
|
||||
while((s=Brdline(&b, '\n')) != nil){
|
||||
s[Blinelen(&b)-1] = '\0';
|
||||
if(strncmp(s, "key ", 4) != 0)
|
||||
continue;
|
||||
memset(&p, 0, sizeof p);
|
||||
parseparams(s, &p);
|
||||
if(strcmp(p.proto, "totp") != 0)
|
||||
continue;
|
||||
if(p.user == nil || p.dom == nil)
|
||||
continue;
|
||||
rpc = auth_allocrpc();
|
||||
if(rpc == nil)
|
||||
sysfatal("auth_allocrpc: %r");
|
||||
params = smprint("proto=totp role=client user=%s dom=%s", p.user, p.dom);
|
||||
if(params == nil)
|
||||
sysfatal("smprint: %r");
|
||||
print("%s %s %s\n", p.user, p.dom, getcode(rpc, params));
|
||||
free(params);
|
||||
auth_freerpc(rpc);
|
||||
}
|
||||
close(fd);
|
||||
fsunmount(fs);
|
||||
}
|
||||
|
||||
void
|
||||
threadmain(int argc, char **argv)
|
||||
{
|
||||
AuthRpc *rpc;
|
||||
char *params, *role, *code;
|
||||
|
||||
code = nil;
|
||||
role = "client";
|
||||
ARGBEGIN{
|
||||
case 'w':
|
||||
code = EARGF(usage());
|
||||
role = "server";
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND
|
||||
|
||||
quotefmtinstall();
|
||||
if(argc == 0 && code == nil){
|
||||
list();
|
||||
threadexits(nil);
|
||||
}
|
||||
|
||||
if(argc != 1)
|
||||
usage();
|
||||
|
||||
rpc = auth_allocrpc();
|
||||
if(rpc == nil)
|
||||
sysfatal("auth_allocrpc: %r");
|
||||
params = smprint("proto=totp role=%s %s", role, argv[0]);
|
||||
if(params == nil)
|
||||
sysfatal("smprint: %r");
|
||||
|
||||
if(code == nil)
|
||||
print("%s\n", getcode(rpc, params));
|
||||
else{
|
||||
if(!verifycode(rpc, params, code))
|
||||
fprint(2, "%s: %r");
|
||||
}
|
||||
free(params);
|
||||
auth_freerpc(rpc);
|
||||
threadexits(nil);
|
||||
}
|
Loading…
Reference in a new issue