aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/auth/factotum/main.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-02-13 05:59:29 +0000
committerrsc <devnull@localhost>2005-02-13 05:59:29 +0000
commit6e527fbc4d8f404a7eec934e5c9efaaaa92ffdff (patch)
tree4d9ed63c88e5a8dd8a4d5bd3582e7d5e6a24065f /src/cmd/auth/factotum/main.c
parent0f8ec41b0ae522b73085fa1662461e6351ba7e54 (diff)
downloadplan9port-6e527fbc4d8f404a7eec934e5c9efaaaa92ffdff.tar.gz
plan9port-6e527fbc4d8f404a7eec934e5c9efaaaa92ffdff.tar.bz2
plan9port-6e527fbc4d8f404a7eec934e5c9efaaaa92ffdff.zip
new auth
Diffstat (limited to 'src/cmd/auth/factotum/main.c')
-rw-r--r--src/cmd/auth/factotum/main.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/cmd/auth/factotum/main.c b/src/cmd/auth/factotum/main.c
new file mode 100644
index 00000000..1a8c4ffc
--- /dev/null
+++ b/src/cmd/auth/factotum/main.c
@@ -0,0 +1,185 @@
+#include "std.h"
+#include "dat.h"
+#include <9pclient.h>
+
+int extrafactotumdir;
+int debug;
+int trysecstore = 1;
+char *factname = "factotum";
+char *service = "factotum";
+char *owner;
+char *authaddr;
+void gflag(char*);
+
+void
+usage(void)
+{
+ fprint(2, "usage: factotum [-Dd] [-a authaddr] [-m mtpt] [-s service]\n");
+ fprint(2, " or factotum -g keypattern\n");
+ fprint(2, " or factotum -g 'badkeyattr\\nmsg\\nkeypattern'\n");
+ threadexitsall("usage");
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+ char *mtpt;
+ char err[ERRMAX];
+
+// mtpt = "/mnt";
+ mtpt = nil;
+ owner = getuser();
+ quotefmtinstall();
+ fmtinstall('A', attrfmt);
+ fmtinstall('H', encodefmt);
+ fmtinstall('N', attrnamefmt);
+
+ if(argc == 3 && strcmp(argv[1], "-g") == 0){
+ gflag(argv[2]);
+ threadexitsall(nil);
+ }
+
+ ARGBEGIN{
+ default:
+ usage();
+ case 'D':
+ chatty9p++;
+ break;
+ case 'a':
+ authaddr = EARGF(usage());
+ break;
+ case 'g':
+ usage();
+ case 'm':
+ mtpt = EARGF(usage());
+ break;
+ case 's':
+ service = EARGF(usage());
+ break;
+ case 'n':
+ trysecstore = 0;
+ break;
+ case 'x':
+ extrafactotumdir = 1;
+ break;
+ }ARGEND
+
+ if(argc != 0)
+ usage();
+
+ if(trysecstore && havesecstore()){
+ while(secstorefetch() < 0){
+ rerrstr(err, sizeof err);
+ if(strcmp(err, "cancel") == 0)
+ break;
+ fprint(2, "secstorefetch: %r\n");
+ fprint(2, "Enter an empty password to quit.\n");
+ }
+ }
+
+ threadpostmountsrv(&fs, service, mtpt, MBEFORE);
+ threadexits(nil);
+}
+
+/*
+ * prompt user for a key. don't care about memory leaks, runs standalone
+ */
+static Attr*
+promptforkey(int fd, char *params)
+{
+ char *v;
+ Attr *a, *attr;
+ char *def;
+
+ attr = _parseattr(params);
+ fprint(fd, "!adding key:");
+ for(a=attr; a; a=a->next)
+ if(a->type != AttrQuery && a->name[0] != '!')
+ fprint(fd, " %q=%q", a->name, a->val);
+ fprint(fd, "\n");
+
+ for(a=attr; a; a=a->next){
+ v = a->name;
+ if(a->type != AttrQuery || v[0]=='!')
+ continue;
+ def = nil;
+ if(strcmp(v, "user") == 0)
+ def = getuser();
+ a->val = readcons(v, def, 0);
+ if(a->val == nil)
+ sysfatal("user terminated key input");
+ a->type = AttrNameval;
+ }
+ for(a=attr; a; a=a->next){
+ v = a->name;
+ if(a->type != AttrQuery || v[0]!='!')
+ continue;
+ def = nil;
+ if(strcmp(v+1, "user") == 0)
+ def = getuser();
+ a->val = readcons(v+1, def, 1);
+ if(a->val == nil)
+ sysfatal("user terminated key input");
+ a->type = AttrNameval;
+ }
+ fprint(fd, "!\n");
+ close(fd);
+ return attr;
+}
+
+/*
+ * send a key to the mounted factotum
+ */
+static int
+sendkey(Attr *attr)
+{
+ int rv;
+ char buf[8192];
+ CFid *fid;
+
+ fid = nsopen("factotum", nil, "ctl", OWRITE);
+ if(fid == nil)
+ sysfatal("opening factotum/ctl: %r");
+ snprint(buf, sizeof buf, "key %A\n", attr);
+ rv = fswrite(fid, buf, strlen(buf));
+ fsclose(fid);
+ return rv;
+}
+
+static void
+askuser(int fd, char *params)
+{
+ Attr *attr;
+
+ attr = promptforkey(fd, params);
+ if(attr == nil)
+ sysfatal("no key supplied");
+ if(sendkey(attr) < 0)
+ sysfatal("sending key to factotum: %r");
+}
+
+void
+gflag(char *s)
+{
+ char *f[4];
+ int nf;
+ int fd;
+
+ if((fd = open("/dev/tty", ORDWR)) < 0)
+ sysfatal("open /dev/tty: %r");
+
+ nf = getfields(s, f, nelem(f), 0, "\n");
+ if(nf == 1){ /* needkey or old badkey */
+ fprint(fd, "\n");
+ askuser(fd, s);
+ threadexitsall(nil);
+ }
+ if(nf == 3){ /* new badkey */
+ fprint(fd, "\n");
+ fprint(fd, "!replace: %s\n", f[0]);
+ fprint(fd, "!because: %s\n", f[1]);
+ askuser(fd, f[2]);
+ threadexitsall(nil);
+ }
+ usage();
+}