if ((flags & FLAG_CONNECTION) && !*cfg.username) {
if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt){    static unsigned long remote_winsize;    static unsigned long remote_maxpkt;    crBegin;    /*     * Request userauth protocol, and await a response to it.     */    ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);    ssh2_pkt_addstring("ssh-userauth");    ssh2_pkt_send();    crWaitUntilV(ispkt);    if (pktin.type != SSH2_MSG_SERVICE_ACCEPT)        fatalbox("Server refused user authentication protocol");    /*     * FIXME: currently we support only password authentication.     * (This places us technically in violation of the SSH2 spec.     * We must fix this.)     */    while (1) {        /*         * Get a username and a password.         */	static char username[100];	static char password[100];	static int pos = 0;	static char c;	if ((flags & FLAG_CONNECTION) && !*cfg.username) {	    c_write("login as: ", 10);	    while (pos >= 0) {		crWaitUntilV(!ispkt);		while (inlen--) switch (c = *in++) {		  case 10: case 13:		    username[pos] = 0;		    pos = -1;		    break;		  case 8: case 127:		    if (pos > 0) {			c_write("\b \b", 3);			pos--;		    }		    break;		  case 21: case 27:		    while (pos > 0) {			c_write("\b \b", 3);			pos--;		    }		    break;		  case 3: case 4:		    random_save_seed();		    exit(0);		    break;		  default:		    if (((c >= ' ' && c <= '~') ||                         ((unsigned char)c >= 160)) && pos < 40) {			username[pos++] = c;			c_write(&c, 1);		    }		    break;		}	    }	    c_write("\r\n", 2);	    username[strcspn(username, "\n\r")] = '\0';	} else {	    char stuff[200];	    strncpy(username, cfg.username, 99);	    username[99] = '\0';	    if (flags & FLAG_VERBOSE) {		sprintf(stuff, "Using username \"%s\".\r\n", username);		c_write(stuff, strlen(stuff));	    }	}	if (!(flags & FLAG_WINDOWED)) {	    char prompt[200];	    sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);	    if (!ssh_get_password(prompt, password, sizeof(password))) {                /*                 * get_password failed to get a password (for                 * example because one was supplied on the command                 * line which has already failed to work).                 * Terminate.                 */                logevent("No more passwords to try");                ssh_state = SSH_STATE_CLOSED;                crReturnV;            }	} else {            c_write("password: ", 10);            pos = 0;            while (pos >= 0) {                crWaitUntilV(!ispkt);                while (inlen--) switch (c = *in++) {                  case 10: case 13:                    password[pos] = 0;                    pos = -1;                    break;                  case 8: case 127:                    if (pos > 0)                        pos--;                    break;                  case 21: case 27:                    pos = 0;                    break;                  case 3: case 4:                    random_save_seed();                    exit(0);                    break;                  default:                    if (((c >= ' ' && c <= '~') ||                         ((unsigned char)c >= 160)) && pos < 40)                        password[pos++] = c;                    break;                }            }            c_write("\r\n", 2);	}        ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);        ssh2_pkt_addstring(username);        ssh2_pkt_addstring("ssh-connection");   /* service requested */        ssh2_pkt_addstring("password");        ssh2_pkt_addbool(FALSE);        ssh2_pkt_addstring(password);        ssh2_pkt_send();        crWaitUntilV(ispkt);        if (pktin.type != SSH2_MSG_USERAUTH_SUCCESS) {	    c_write("Access denied\r\n", 15);	    logevent("Authentication refused");        } else            break;    }    /*     * Now we're authenticated for the connection protocol. The     * connection protocol will automatically have started at this     * point; there's no need to send SERVICE_REQUEST.     */    /*     * So now create a channel with a session in it.     */    mainchan = malloc(sizeof(struct ssh_channel));    mainchan->localid = 100;           /* as good as any */    ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);    ssh2_pkt_addstring("session");    ssh2_pkt_adduint32(mainchan->localid);    ssh2_pkt_adduint32(0x7FFFFFFFUL);  /* our window size */    ssh2_pkt_adduint32(0x4000UL);  /* our max pkt size */    ssh2_pkt_send();    crWaitUntilV(ispkt);    if (pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {        fatalbox("Server refused to open a session");        /* FIXME: error data comes back in FAILURE packet */    }    if (ssh2_pkt_getuint32() != mainchan->localid) {        fatalbox("Server's channel confirmation cited wrong channel");    }    mainchan->remoteid = ssh2_pkt_getuint32();    mainchan->u.v2.remwindow = ssh2_pkt_getuint32();    mainchan->u.v2.remmaxpkt = ssh2_pkt_getuint32();    mainchan->u.v2.outbuffer = NULL;    mainchan->u.v2.outbuflen = mainchan->u.v2.outbufsize = 0;    logevent("Opened channel for session");    /*     * Now allocate a pty for the session.     */    ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);    ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */    ssh2_pkt_addstring("pty-req");    ssh2_pkt_addbool(1);               /* want reply */    ssh2_pkt_addstring(cfg.termtype);    ssh2_pkt_adduint32(cols);    ssh2_pkt_adduint32(rows);    ssh2_pkt_adduint32(0);             /* pixel width */    ssh2_pkt_adduint32(0);             /* pixel height */    ssh2_pkt_addstring_start();    ssh2_pkt_addstring_data("\0", 1);  /* TTY_OP_END, no special options */    ssh2_pkt_send();    do {                               /* FIXME: pay attention to these */        crWaitUntilV(ispkt);    } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);    if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {        if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {            fatalbox("Server got confused by pty request");        }        c_write("Server refused to allocate pty\r\n", 32);    } else {        logevent("Allocated pty");    }    /*     * Start a shell.     */    ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);    ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */    ssh2_pkt_addstring("shell");    ssh2_pkt_addbool(1);               /* want reply */    ssh2_pkt_send();    do {        crWaitUntilV(ispkt);        if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {            /* FIXME: be able to handle other channels here */            if (ssh2_pkt_getuint32() != mainchan->localid)                continue;          /* wrong channel */            mainchan->u.v2.remwindow += ssh2_pkt_getuint32();        }    } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);    if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {        if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {            fatalbox("Server got confused by shell request");        }        fatalbox("Server refused to start a shell");    } else {        logevent("Started a shell");    }    /*     * Transfer data!     */    ssh_send_ok = 1;    while (1) {        static int try_send;	crReturnV;        try_send = FALSE;	if (ispkt) {	    if (pktin.type == SSH2_MSG_CHANNEL_DATA ||                pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {                char *data;                int length;                /* FIXME: be able to handle other channels here */                if (ssh2_pkt_getuint32() != mainchan->localid)                    continue;          /* wrong channel */                if (pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&                    ssh2_pkt_getuint32() != SSH2_EXTENDED_DATA_STDERR)                    continue;          /* extended but not stderr */                ssh2_pkt_getstring(&data, &length);                if (data) {                    c_write(data, length);                    /*                     * Enlarge the window again at the remote side,                     * just in case it ever runs down and they fail                     * to send us any more data.                     */                    ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);                    ssh2_pkt_adduint32(mainchan->remoteid);                    ssh2_pkt_adduint32(length);                    ssh2_pkt_send();                }	    } else if (pktin.type == SSH2_MSG_DISCONNECT) {                ssh_state = SSH_STATE_CLOSED;		logevent("Received disconnect message");	    } else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {                continue;              /* exit status et al; ignore (FIXME?) */	    } else if (pktin.type == SSH2_MSG_CHANNEL_EOF) {                continue;              /* remote sends EOF; ignore */	    } else if (pktin.type == SSH2_MSG_CHANNEL_CLOSE) {                /* FIXME: be able to handle other channels here */                if (ssh2_pkt_getuint32() != mainchan->localid)                    continue;          /* wrong channel */                ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);                ssh2_pkt_adduint32(mainchan->remoteid);                ssh2_pkt_send();                /* FIXME: mark the channel as closed */                if (1 /* FIXME: "all channels are closed" */) {                    logevent("All channels closed. Disconnecting");                    ssh2_pkt_init(SSH2_MSG_DISCONNECT);                    ssh2_pkt_send();                }                continue;              /* remote sends close; ignore (FIXME) */	    } else if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {                /* FIXME: be able to handle other channels here */                if (ssh2_pkt_getuint32() != mainchan->localid)                    continue;          /* wrong channel */                mainchan->u.v2.remwindow += ssh2_pkt_getuint32();                try_send = TRUE;	    } else {		fatalbox("Strange packet received: type %d", pktin.type);	    }	} else {            /*             * We have spare data. Add it to the channel buffer.             */            if (mainchan->u.v2.outbufsize <                mainchan->u.v2.outbuflen + inlen) {                mainchan->u.v2.outbufsize =                    mainchan->u.v2.outbuflen + inlen + 1024;                mainchan->u.v2.outbuffer = srealloc(mainchan->u.v2.outbuffer,                                                    mainchan->u.v2.outbufsize);            }            memcpy(mainchan->u.v2.outbuffer + mainchan->u.v2.outbuflen,                   in, inlen);            mainchan->u.v2.outbuflen += inlen;            try_send = TRUE;	}        if (try_send) {            /*             * Try to send data on the channel if we can. (FIXME:             * on _all_ channels.)             */            while (mainchan->u.v2.remwindow > 0 &&                   mainchan->u.v2.outbuflen > 0) {                unsigned len = mainchan->u.v2.remwindow;                if (len > mainchan->u.v2.outbuflen)                    len = mainchan->u.v2.outbuflen;                if (len > mainchan->u.v2.remmaxpkt)                    len = mainchan->u.v2.remmaxpkt;                ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);                ssh2_pkt_adduint32(mainchan->remoteid);                ssh2_pkt_addstring_start();                ssh2_pkt_addstring_data(mainchan->u.v2.outbuffer, len);                ssh2_pkt_send();                mainchan->u.v2.outbuflen -= len;                memmove(mainchan->u.v2.outbuffer, mainchan->u.v2.outbuffer+len,                        mainchan->u.v2.outbuflen);                mainchan->u.v2.remwindow -= len;            }        }    }    crFinishV;}