plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

main.c (3534B)


      1 #include "std.h"
      2 #include "dat.h"
      3 #include <9pclient.h>
      4 
      5 int extrafactotumdir;
      6 int debug;
      7 int trysecstore = 1;
      8 char *factname = "factotum";
      9 char *service = "factotum";
     10 char *owner;
     11 char *authaddr;
     12 void gflag(char*);
     13 
     14 void
     15 usage(void)
     16 {
     17 	fprint(2, "usage: factotum [-Dd] [-a authaddr] [-m mtpt] [-s service]\n");
     18 	fprint(2, " or   factotum -g keypattern\n");
     19 	fprint(2, " or   factotum -g 'badkeyattr\\nmsg\\nkeypattern'\n");
     20 	threadexitsall("usage");
     21 }
     22 
     23 int
     24 threadmaybackground(void)
     25 {
     26 	return 1;
     27 }
     28 
     29 void
     30 threadmain(int argc, char *argv[])
     31 {
     32 	char *mtpt;
     33 	char err[ERRMAX];
     34 
     35 /*	mtpt = "/mnt"; */
     36 	mtpt = nil;
     37 	owner = getuser();
     38 	quotefmtinstall();
     39 	fmtinstall('A', attrfmt);
     40 	fmtinstall('H', encodefmt);
     41 	fmtinstall('N', attrnamefmt);
     42 
     43 	if(argc == 3 && strcmp(argv[1], "-g") == 0){
     44 		gflag(argv[2]);
     45 		threadexitsall(nil);
     46 	}
     47 
     48 	ARGBEGIN{
     49 	default:
     50 		usage();
     51 	case 'D':
     52 		chatty9p++;
     53 		break;
     54 	case 'a':
     55 		authaddr = EARGF(usage());
     56 		break;
     57 	case 'd':
     58 		debug = 1;
     59 		break;
     60 	case 'g':
     61 		usage();
     62 	case 'm':
     63 		mtpt = EARGF(usage());
     64 		break;
     65 	case 's':
     66 		service = EARGF(usage());
     67 		break;
     68 	case 'n':
     69 		trysecstore = 0;
     70 		break;
     71 	case 'x':
     72 		extrafactotumdir = 1;
     73 		break;
     74 	}ARGEND
     75 
     76 	if(argc != 0)
     77 		usage();
     78 
     79 	if(trysecstore && havesecstore()){
     80 		while(secstorefetch() < 0){
     81 			rerrstr(err, sizeof err);
     82 			if(strcmp(err, "cancel") == 0)
     83 				break;
     84 			fprint(2, "secstorefetch: %r\n");
     85 			fprint(2, "Enter an empty password to quit.\n");
     86 		}
     87 	}
     88 
     89 	rfork(RFNOTEG);
     90 
     91 	fsinit0();
     92 	threadpostmountsrv(&fs, service, mtpt, MBEFORE);
     93 	threadexits(nil);
     94 }
     95 
     96 /*
     97  *  prompt user for a key.  don't care about memory leaks, runs standalone
     98  */
     99 static Attr*
    100 promptforkey(int fd, char *params)
    101 {
    102 	char *v;
    103 	Attr *a, *attr;
    104 	char *def;
    105 
    106 	attr = _parseattr(params);
    107 	fprint(fd, "!adding key:");
    108 	for(a=attr; a; a=a->next)
    109 		if(a->type != AttrQuery && a->name[0] != '!')
    110 			fprint(fd, " %q=%q", a->name, a->val);
    111 	fprint(fd, "\n");
    112 
    113 	for(a=attr; a; a=a->next){
    114 		v = a->name;
    115 		if(a->type != AttrQuery || v[0]=='!')
    116 			continue;
    117 		def = nil;
    118 		if(strcmp(v, "user") == 0)
    119 			def = getuser();
    120 		a->val = readcons(v, def, 0);
    121 		if(a->val == nil)
    122 			sysfatal("user terminated key input");
    123 		a->type = AttrNameval;
    124 	}
    125 	for(a=attr; a; a=a->next){
    126 		v = a->name;
    127 		if(a->type != AttrQuery || v[0]!='!')
    128 			continue;
    129 		def = nil;
    130 		if(strcmp(v+1, "user") == 0)
    131 			def = getuser();
    132 		a->val = readcons(v+1, def, 1);
    133 		if(a->val == nil)
    134 			sysfatal("user terminated key input");
    135 		a->type = AttrNameval;
    136 	}
    137 	fprint(fd, "!\n");
    138 	close(fd);
    139 	return attr;
    140 }
    141 
    142 /*
    143  *  send a key to the mounted factotum
    144  */
    145 static int
    146 sendkey(Attr *attr)
    147 {
    148 	int rv;
    149 	char buf[8192];
    150 	CFid *fid;
    151 
    152 	fid = nsopen("factotum", nil, "ctl", OWRITE);
    153 	if(fid == nil)
    154 		sysfatal("opening factotum/ctl: %r");
    155 	snprint(buf, sizeof buf, "key %A\n", attr);
    156 	rv = fswrite(fid, buf, strlen(buf));
    157 	fsclose(fid);
    158 	return rv;
    159 }
    160 
    161 static void
    162 askuser(int fd, char *params)
    163 {
    164 	Attr *attr;
    165 
    166 	attr = promptforkey(fd, params);
    167 	if(attr == nil)
    168 		sysfatal("no key supplied");
    169 	if(sendkey(attr) < 0)
    170 		sysfatal("sending key to factotum: %r");
    171 }
    172 
    173 void
    174 gflag(char *s)
    175 {
    176 	char *f[4];
    177 	int nf;
    178 	int fd;
    179 
    180 	if((fd = open("/dev/tty", ORDWR)) < 0)
    181 		sysfatal("open /dev/tty: %r");
    182 
    183 	nf = getfields(s, f, nelem(f), 0, "\n");
    184 	if(nf == 1){	/* needkey or old badkey */
    185 		fprint(fd, "\n");
    186 		askuser(fd, s);
    187 		threadexitsall(nil);
    188 	}
    189 	if(nf == 3){	/* new badkey */
    190 		fprint(fd, "\n");
    191 		fprint(fd, "!replace: %s\n", f[0]);
    192 		fprint(fd, "!because: %s\n", f[1]);
    193 		askuser(fd, f[2]);
    194 		threadexitsall(nil);
    195 	}
    196 	usage();
    197 }