util.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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[32];
  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. void
  94. calcsessid(Conn *c)
  95. {
  96. int n;
  97. uchar buf[1024];
  98. n = mptobe(c->hostkey->n, buf, sizeof buf, nil);
  99. n += mptobe(c->serverkey->n, buf+n, sizeof buf-n, nil);
  100. memmove(buf+n, c->cookie, COOKIELEN);
  101. n += COOKIELEN;
  102. md5(buf, n, c->sessid, nil);
  103. }
  104. void
  105. sshlog(char *f, ...)
  106. {
  107. char *s;
  108. va_list arg;
  109. Fmt fmt;
  110. static int pid;
  111. if(pid == 0)
  112. pid = getpid();
  113. va_start(arg, f);
  114. va_end(arg);
  115. if(fmtstrinit(&fmt) < 0)
  116. sysfatal("fmtstrinit: %r");
  117. fmtprint(&fmt, "[%d] ", pid);
  118. fmtvprint(&fmt, f, arg);
  119. s = fmtstrflush(&fmt);
  120. if(s == nil)
  121. sysfatal("fmtstrflush: %r");
  122. syslog(0, "ssh", "%s", s);
  123. free(s);
  124. }
  125. /*
  126. * this is far too smart.
  127. */
  128. static int
  129. pstrcmp(const void *a, const void *b)
  130. {
  131. return strcmp(*(char**)a, *(char**)b);
  132. }
  133. static char*
  134. trim(char *s)
  135. {
  136. char *t;
  137. int i, last, n, nf;
  138. char **f;
  139. char *p;
  140. t = emalloc(strlen(s)+1);
  141. t[0] = '\0';
  142. n = 1;
  143. for(p=s; *p; p++)
  144. if(*p == ' ')
  145. n++;
  146. f = emalloc((n+1)*sizeof(f[0]));
  147. nf = tokenize(s, f, n+1);
  148. qsort(f, nf, sizeof(f[0]), pstrcmp);
  149. last=-1;
  150. for(i=0; i<nf; i++){
  151. if(last==-1 || strcmp(f[last], f[i])!=0){
  152. if(last >= 0)
  153. strcat(t, ",");
  154. strcat(t, f[i]);
  155. last = i;
  156. }
  157. }
  158. return t;
  159. }
  160. static void
  161. usetuple(Conn *c, Ndbtuple *t, int scanentries)
  162. {
  163. int first;
  164. Ndbtuple *l, *e;
  165. char *s;
  166. first=1;
  167. s = c->host;
  168. for(l=t; first||l!=t; l=l->line, first=0){
  169. if(scanentries){
  170. for(e=l; e; e=e->entry){
  171. if(strcmp(e->val, c->host) != 0 &&
  172. (strcmp(e->attr, "ip")==0 || strcmp(e->attr, "dom")==0 || strcmp(e->attr, "sys")==0)){
  173. s = smprint("%s %s", s, e->val);
  174. if(s == nil)
  175. error("out of memory");
  176. }
  177. }
  178. }
  179. if(strcmp(l->val, c->host) != 0 &&
  180. (strcmp(l->attr, "ip")==0 || strcmp(l->attr, "dom")==0 || strcmp(l->attr, "sys")==0)){
  181. s = smprint("%s %s", s, l->val);
  182. if(s == nil)
  183. error("out of memory");
  184. }
  185. }
  186. s = trim(s);
  187. c->aliases = s;
  188. }
  189. void
  190. setaliases(Conn *c, char *name)
  191. {
  192. char *p, *net;
  193. char *attr[2];
  194. Ndbtuple *t;
  195. net = "/net";
  196. if(name[0]=='/'){
  197. p = strchr(name+1, '/');
  198. if(p){
  199. net = emalloc(p-name+1);
  200. memmove(net, name, p-name);
  201. }
  202. }
  203. if(p = strchr(name, '!'))
  204. name = p+1;
  205. c->host = emalloc(strlen(name)+1);
  206. strcpy(c->host, name);
  207. c->aliases = c->host;
  208. attr[0] = "dom";
  209. attr[1] = "ip";
  210. t = csipinfo(nil, ipattr(name), name, attr, 2);
  211. if(t != nil){
  212. usetuple(c, t, 0);
  213. ndbfree(t);
  214. }else{
  215. t = dnsquery(net, name, "ip");
  216. if(t != nil){
  217. usetuple(c, t, 1);
  218. ndbfree(t);
  219. }
  220. }
  221. }
  222. void
  223. privatefactotum(void)
  224. {
  225. char *user;
  226. Dir *d;
  227. if((user=getuser()) && (d=dirstat("/mnt/factotum/rpc")) && strcmp(user, d->uid)!=0){
  228. /* grab the terminal's factotum */
  229. rfork(RFNOTEG);
  230. if(access("/mnt/term/mnt/factotum", AEXIST) >= 0){
  231. // fprint(2, "binding terminal's factotum\n");
  232. if(bind("/mnt/term/mnt/factotum", "/mnt/factotum", MREPL) < 0)
  233. sysfatal("cannot find factotum");
  234. }
  235. }
  236. }