util.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. #include "ssh.h"
  2. #include <bio.h>
  3. #include <ndb.h>
  4. char Edecode[] = "error decoding input packet";
  5. char Eencode[] = "out of space encoding output packet (BUG)";
  6. char Ehangup[] = "hungup connection";
  7. char Ememory[] = "out of memory";
  8. int debuglevel;
  9. int doabort;
  10. void
  11. error(char *fmt, ...)
  12. {
  13. va_list arg;
  14. char buf[2048];
  15. va_start(arg, fmt);
  16. vseprint(buf, buf+sizeof(buf), fmt, arg);
  17. va_end(arg);
  18. fprint(2, "%s: %s\n", argv0, buf);
  19. if(doabort)
  20. abort();
  21. exits(buf);
  22. }
  23. void
  24. debug(int level, char *fmt, ...)
  25. {
  26. va_list arg;
  27. if((level&debuglevel) == 0)
  28. return;
  29. va_start(arg, fmt);
  30. vfprint(2, fmt, arg);
  31. va_end(arg);
  32. }
  33. void*
  34. emalloc(long n)
  35. {
  36. void *a;
  37. a = mallocz(n, 1);
  38. if(a == nil)
  39. error(Ememory);
  40. setmalloctag(a, getcallerpc(&n));
  41. return a;
  42. }
  43. void*
  44. erealloc(void *v, long n)
  45. {
  46. v = realloc(v, n);
  47. if(v == nil)
  48. error(Ememory);
  49. setrealloctag(v, getcallerpc(&v));
  50. return v;
  51. }
  52. static int killpid[16];
  53. static int nkillpid;
  54. void
  55. atexitkiller(void)
  56. {
  57. int i, pid;
  58. pid = getpid();
  59. debug(DBG, "atexitkiller: nkillpid=%d mypid=%d\n", nkillpid, pid);
  60. for(i=0; i<nkillpid; i++)
  61. if(pid != killpid[i]){
  62. debug(DBG, "killing %d\n", killpid[i]);
  63. postnote(PNPROC, killpid[i], "kill");
  64. }
  65. }
  66. void
  67. atexitkill(int pid)
  68. {
  69. killpid[nkillpid++] = pid;
  70. }
  71. int
  72. readstrnl(int fd, char *buf, int nbuf)
  73. {
  74. int i;
  75. for(i=0; i<nbuf; i++){
  76. switch(read(fd, buf+i, 1)){
  77. case -1:
  78. return -1;
  79. case 0:
  80. werrstr("unexpected EOF");
  81. return -1;
  82. default:
  83. if(buf[i]=='\n'){
  84. buf[i] = '\0';
  85. return 0;
  86. }
  87. break;
  88. }
  89. }
  90. werrstr("line too long");
  91. return -1;
  92. }
  93. RSApriv*
  94. readsecretkey(char *name)
  95. {
  96. char *buf;
  97. char *p;
  98. mpint *ek, *dk, *n, *pp, *q, *kp, *kq, *c2;
  99. Biobuf *b;
  100. RSApriv *key;
  101. if((b = Bopen(name, OREAD)) == nil)
  102. return nil;
  103. if((buf = Brdstr(b, '\n', 1)) == nil){
  104. Bterm(b);
  105. return nil;
  106. }
  107. Bterm(b);
  108. /*
  109. * size ek dk n p q kp kq c2
  110. */
  111. ek = dk = n = pp = q = kp = kq = c2 = nil;
  112. if((p = strchr(buf, ' ')) == nil
  113. || (ek=strtomp(p, &p, 16, nil)) == nil
  114. || (dk=strtomp(p, &p, 16, nil)) == nil
  115. || (n=strtomp(p, &p, 16, nil)) == nil
  116. || (pp=strtomp(p, &p, 16, nil)) == nil
  117. || (q=strtomp(p, &p, 16, nil)) == nil
  118. || (kp=strtomp(p, &p, 16, nil)) == nil
  119. || (kq=strtomp(p, &p, 16, nil)) == nil
  120. || (c2=strtomp(p, &p, 16, nil)) == nil
  121. || (key=rsaprivalloc()) == nil){
  122. mpfree(ek);
  123. mpfree(dk);
  124. mpfree(n);
  125. mpfree(pp);
  126. mpfree(q);
  127. mpfree(kp);
  128. mpfree(kq);
  129. mpfree(c2);
  130. free(buf);
  131. return nil;
  132. }
  133. key->pub.ek = ek;
  134. key->dk = dk;
  135. key->pub.n = n;
  136. key->p = pp;
  137. key->q = q;
  138. key->kp = kp;
  139. key->kq = kq;
  140. key->c2 = c2;
  141. free(buf);
  142. return key;
  143. }
  144. void
  145. calcsessid(Conn *c)
  146. {
  147. int n;
  148. uchar buf[1024];
  149. n = mptobe(c->hostkey->n, buf, sizeof buf, nil);
  150. n += mptobe(c->serverkey->n, buf+n, sizeof buf-n, nil);
  151. memmove(buf+n, c->cookie, COOKIELEN);
  152. n += COOKIELEN;
  153. md5(buf, n, c->sessid, nil);
  154. }
  155. void
  156. sshlog(char *f, ...)
  157. {
  158. char *s;
  159. va_list arg;
  160. Fmt fmt;
  161. static int pid;
  162. if(pid == 0)
  163. pid = getpid();
  164. va_start(arg, f);
  165. va_end(arg);
  166. if(fmtstrinit(&fmt) < 0)
  167. sysfatal("fmtstrinit: %r");
  168. fmtprint(&fmt, "[%d] ", pid);
  169. fmtvprint(&fmt, f, arg);
  170. s = fmtstrflush(&fmt);
  171. if(s == nil)
  172. sysfatal("fmtstrflush: %r");
  173. syslog(0, "ssh", "%s", s);
  174. free(s);
  175. }
  176. /*
  177. * this is far too smart.
  178. */
  179. static int
  180. pstrcmp(const void *a, const void *b)
  181. {
  182. return strcmp(*(char**)a, *(char**)b);
  183. }
  184. static char*
  185. trim(char *s)
  186. {
  187. char *t;
  188. int i, last, n, nf;
  189. char **f;
  190. char *p;
  191. t = emalloc(strlen(s)+1);
  192. t[0] = '\0';
  193. n = 1;
  194. for(p=s; *p; p++)
  195. if(*p == ' ')
  196. n++;
  197. f = emalloc((n+1)*sizeof(f[0]));
  198. nf = tokenize(s, f, n+1);
  199. qsort(f, nf, sizeof(f[0]), pstrcmp);
  200. last=-1;
  201. for(i=0; i<nf; i++){
  202. if(last==-1 || strcmp(f[last], f[i])!=0){
  203. if(last >= 0)
  204. strcat(t, ",");
  205. strcat(t, f[i]);
  206. last = i;
  207. }
  208. }
  209. return t;
  210. }
  211. static void
  212. usetuple(Conn *c, Ndbtuple *t, int scanentries)
  213. {
  214. int first;
  215. Ndbtuple *l, *e;
  216. char *s;
  217. first=1;
  218. s = c->host;
  219. for(l=t; first||l!=t; l=l->line, first=0){
  220. if(scanentries){
  221. for(e=l; e; e=e->entry){
  222. if(strcmp(e->val, c->host) != 0 &&
  223. (strcmp(e->attr, "ip")==0 || strcmp(e->attr, "dom")==0 || strcmp(e->attr, "sys")==0)){
  224. s = smprint("%s %s", s, e->val);
  225. if(s == nil)
  226. error("out of memory");
  227. }
  228. }
  229. }
  230. if(strcmp(l->val, c->host) != 0 &&
  231. (strcmp(l->attr, "ip")==0 || strcmp(l->attr, "dom")==0 || strcmp(l->attr, "sys")==0)){
  232. s = smprint("%s %s", s, l->val);
  233. if(s == nil)
  234. error("out of memory");
  235. }
  236. }
  237. s = trim(s);
  238. c->aliases = s;
  239. }
  240. void
  241. setaliases(Conn *c, char *name)
  242. {
  243. char *p, *net;
  244. char *attr[2];
  245. Ndbtuple *t;
  246. net = "/net";
  247. if(name[0]=='/'){
  248. p = strchr(name+1, '/');
  249. if(p){
  250. net = emalloc(p-name+1);
  251. memmove(net, name, p-name);
  252. }
  253. }
  254. if(p = strchr(name, '!'))
  255. name = p+1;
  256. c->host = emalloc(strlen(name)+1);
  257. strcpy(c->host, name);
  258. c->aliases = c->host;
  259. attr[0] = "dom";
  260. attr[1] = "ip";
  261. t = csipinfo(nil, ipattr(name), name, attr, 2);
  262. if(t != nil){
  263. usetuple(c, t, 0);
  264. ndbfree(t);
  265. }else{
  266. t = dnsquery(net, name, "ip");
  267. if(t != nil){
  268. usetuple(c, t, 1);
  269. ndbfree(t);
  270. }
  271. }
  272. }
  273. void
  274. privatefactotum(void)
  275. {
  276. char *user;
  277. Dir *d;
  278. if((user=getuser()) && (d=dirstat("/mnt/factotum/rpc")) && strcmp(user, d->uid)!=0){
  279. /* grab the terminal's factotum */
  280. rfork(RFNOTEG);
  281. if(access("/mnt/term/mnt/factotum", AEXIST) >= 0){
  282. // fprint(2, "binding terminal's factotum\n");
  283. if(bind("/mnt/term/mnt/factotum", "/mnt/factotum", MREPL) < 0)
  284. sysfatal("cannot find factotum");
  285. }
  286. }
  287. }