void main(int argc, char **argv) { char *f[16]; int i; Conn c; fmtinstall('B', mpfmt); fmtinstall('H', encodefmt); atexit(atexitkiller); atexitkill(getpid()); memset(&c, 0, sizeof c); ARGBEGIN{ case 'D': debuglevel = atoi(EARGF(usage())); break; case 'A': authlist = EARGF(usage()); break; case 'c': cipherlist = EARGF(usage()); break; default: usage(); }ARGEND if(argc != 1) usage(); c.host = argv[0]; sshlog("connect from %s", c.host); /* limit of 768 bits in remote host key? */ c.serverpriv = rsagen(768, 6, 0); if(c.serverpriv == nil) sysfatal("rsagen failed: %r"); c.serverkey = &c.serverpriv->pub; c.nokcipher = getfields(cipherlist, f, nelem(f), 1, ", "); c.okcipher = emalloc(sizeof(Cipher*)*c.nokcipher); for(i=0; i<c.nokcipher; i++) c.okcipher[i] = findcipher(f[i], allcipher, nelem(allcipher)); c.nokauthsrv = getfields(authlist, f, nelem(f), 1, ", "); c.okauthsrv = emalloc(sizeof(Authsrv*)*c.nokauthsrv); for(i=0; i<c.nokauthsrv; i++) c.okauthsrv[i] = findauthsrv(f[i], allauthsrv, nelem(allauthsrv)); sshserverhandshake(&c); fromnet(&c); }
/* Return the next netmsg from the input buffer or NETMSG_NONE if none. */ netmsg net_next_message(netconnection_t *nc, nm_frame_t last_frame) { netbuf_t *in; netmsg msg; int p; int type, size; /* Message details */ in = &nc->input; /* Small variable name for convenience */ msg.type = NETMSG_NONE; /* Early returns (errors) will be NETMSG_NONE */ if( last_frame == NM_LAST_FRAME && in->frames == -1 ) { printf("Waiting for the rest of frame......\n"); return msg; } if( in->end - in->start <= 0 ) { /* Nothing in input buffer */ printf("in->start = %d, in->end = %d!\n", in->start, in->end); return msg; /* NONE */ } /* Go from beginning of input buffer, if messages we want to discard lie outside of the boundaries, then on to the next message */ for( p = in->pos ; p < in->end ; p += size ) { type = (byte)in->buf[p]; /* Fixes DoS attack. Added Jan 11 2003 David Lawrence */ if( type >= NUM_NETMESSAGES ) { printf("Net: Unknown message type from client.\n"); return msg; } size = netmsg_table[type].size; in->pos += size; if( p < in->start && netmsg_table[type].frame_constrained ) continue; /* Drop in frame message up till current frame. */ if( size > 0 && in->end - p >= size ) { memcpy( &msg, in->buf + p, size ); msg.type = type; break; } } fromnet(&msg); /* To host byte order */ return msg; }
/* * two processes pass bytes back and forth between the * terminal and the network. */ void telnet(int net) { int pid; int p[2]; char *svc; rawoff(); svc = nil; if (srv) { if(pipe(p) < 0) sysfatal("pipe: %r"); if (srv[0] != '/') svc = smprint("/srv/%s", srv); else svc = srv; post(svc, p[0]); close(p[0]); dup(p[1], 0); dup(p[1], 1); /* pipe is now std in & out */ } ttypid = getpid(); switch(pid = rfork(RFPROC|RFFDG|RFMEM)){ case -1: perror("con"); exits("fork"); case 0: rawoff(); notify(notifyf); fromnet(net); if (svc) remove(svc); sendnote(ttypid, "die"); exits(0); default: netpid = pid; notify(notifyf); fromkbd(net); if(notkbd) for(;;) sleep(0); if (svc) remove(svc); sendnote(netpid, "die"); exits(0); } }
void main(int argc, char **argv) { int i, dowinchange, fd, usepty; char *host, *cmd, *user, *p; char *f[16]; Conn c; Msg *m; fmtinstall('B', mpfmt); fmtinstall('H', encodefmt); atexit(atexitkiller); atexitkill(getpid()); dowinchange = 0; if(getenv("LINES")) dowinchange = 1; usepty = -1; user = nil; ARGBEGIN{ case 'B': /* undocumented, debugging */ doabort = 1; break; case 'D': /* undocumented, debugging */ debuglevel = strtol(EARGF(usage()), nil, 0); break; case 'l': /* deprecated */ case 'u': user = EARGF(usage()); break; case 'a': /* used by Unix scp implementations; we must ignore them. */ case 'x': break; case 'A': authlist = EARGF(usage()); break; case 'C': cooked = 1; break; case 'c': cipherlist = EARGF(usage()); break; case 'f': forwardagent = 1; break; case 'I': interactive = 0; break; case 'i': interactive = 1; break; case 'm': usemenu = 0; break; case 'P': usepty = 0; break; case 'p': usepty = 1; break; case 'R': rawhack = 1; break; case 'r': crstrip = 1; break; default: usage(); }ARGEND if(argc < 1) usage(); host = argv[0]; cmd = nil; if(argc > 1) cmd = buildcmd(argc-1, argv+1); if((p = strchr(host, '@')) != nil){ *p++ = '\0'; user = host; host = p; } if(user == nil) user = getenv("user"); if(user == nil) sysfatal("cannot find user name"); privatefactotum(); if(interactive==-1) interactive = isatty(0); if((fd = dial(netmkaddr(host, "tcp", "ssh"), nil, nil, nil)) < 0) sysfatal("dialing %s: %r", host); memset(&c, 0, sizeof c); c.interactive = interactive; c.fd[0] = c.fd[1] = fd; c.user = user; c.host = host; setaliases(&c, host); c.nokcipher = getfields(cipherlist, f, nelem(f), 1, ", "); c.okcipher = emalloc(sizeof(Cipher*)*c.nokcipher); for(i=0; i<c.nokcipher; i++) c.okcipher[i] = findcipher(f[i], allcipher, nelem(allcipher)); c.nokauth = getfields(authlist, f, nelem(f), 1, ", "); c.okauth = emalloc(sizeof(Auth*)*c.nokauth); for(i=0; i<c.nokauth; i++) c.okauth[i] = findauth(f[i], allauth, nelem(allauth)); sshclienthandshake(&c); if(forwardagent){ if(startagent(&c) < 0) forwardagent = 0; } if(usepty == -1) usepty = cmd==nil; if(usepty) requestpty(&c); if(cmd){ m = allocmsg(&c, SSH_CMSG_EXEC_CMD, 4+strlen(cmd)); putstring(m, cmd); }else m = allocmsg(&c, SSH_CMSG_EXEC_SHELL, 0); sendmsg(m); fromstdin(&c); rfork(RFNOTEG); /* only fromstdin gets notes */ if(dowinchange) winchanges(&c); fromnet(&c); exits(0); }