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 }