static void server_input_window_size(int type, u_int32_t seq, void *ctxt) { u_int row = packet_get_int(); u_int col = packet_get_int(); u_int xpixel = packet_get_int(); u_int ypixel = packet_get_int(); debug("Window change received."); packet_check_eom(); if (fdin != -1) pty_change_window_size(fdin, row, col, xpixel, ypixel); }
void PTYPars::read_from_packet (CoreConnection* con) { u_int len; int n_bytes; #if 0 // FIXME if (s->ttyfd != -1) { packet_disconnect("Protocol error: you already have a pty."); return 0; } #endif const char* term2 = con-> packet_get_string(&len); term = term2; xfree ((void*) term2); col = con-> packet_get_int(); row = con-> packet_get_int(); xpixel = con-> packet_get_int(); ypixel = con-> packet_get_int(); #if 0 /* Allocate a pty and open it. */ debug("Allocating pty."); if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { if (s->term) xfree(s->term); s->term = NULL; s->ptyfd = -1; s->ttyfd = -1; error("session_pty_req: session %d alloc failed", s->self); return 0; } debug("session_pty_req: session %d alloc %s", s->self, s->tty); #endif PTY::tty_parse_modes(con, &n_bytes); #if 0 /* Set window size from the packet. */ pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); #endif packet_check_eom (con); }
/* Let the process know that the window size has changed, as notified from the * client. Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ static int sessionwinchange(struct ChanSess *chansess) { if (chansess->master < 0) { /* haven't got a pty yet */ return DROPBEAR_FAILURE; } chansess->termc = buf_getint(ses.payload); chansess->termr = buf_getint(ses.payload); chansess->termw = buf_getint(ses.payload); chansess->termh = buf_getint(ses.payload); pty_change_window_size(chansess->master, chansess->termr, chansess->termc, chansess->termw, chansess->termh); return DROPBEAR_FAILURE; }
static int server_input_window_size(int type, u_int32_t seq, struct ssh *ssh) { u_int row, col, xpixel, ypixel; int r; if ((r = sshpkt_get_u32(ssh, &row)) != 0 || (r = sshpkt_get_u32(ssh, &col)) != 0 || (r = sshpkt_get_u32(ssh, &xpixel)) != 0 || (r = sshpkt_get_u32(ssh, &ypixel)) != 0 || (r = sshpkt_get_end(ssh))) return r; debug("Window change received."); if (fdin != -1) pty_change_window_size(fdin, row, col, xpixel, ypixel); return 0; }
/* Set up a session pty which will be used to execute the shell or program. * The pty is allocated now, and kept for when the shell/program executes. * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ static int sessionpty(struct ChanSess * chansess) { unsigned int termlen; unsigned char namebuf[65]; struct termios termio; TRACE(("enter sessionpty")); chansess->term = buf_getstring(ses.payload, &termlen); if (termlen > MAX_TERM_LEN) { /* TODO send disconnect ? */ TRACE(("leave sessionpty: term len too long")); return DROPBEAR_FAILURE; } chansess->termc = buf_getint(ses.payload); chansess->termr = buf_getint(ses.payload); chansess->termw = buf_getint(ses.payload); chansess->termh = buf_getint(ses.payload); /* allocate the pty */ assert(chansess->master == -1); /* haven't already got one */ if (pty_allocate(&chansess->master, &chansess->slave, namebuf, 64) == 0) { TRACE(("leave sessionpty: failed to allocate pty")); return DROPBEAR_FAILURE; } chansess->tty = (char*)strdup(namebuf); if (!chansess->tty) { dropbear_exit("out of memory"); /* TODO disconnect */ } pty_setowner(ses.authstate.pw, chansess->tty); pty_change_window_size(chansess->master, chansess->termr, chansess->termc, chansess->termw, chansess->termh); /* Term modes */ /* We'll ignore errors and continue if we can't set modes. * We're ignoring baud rates since they seem evil */ if (tcgetattr(chansess->master, &termio) == 0) { unsigned char opcode; unsigned int value; const struct TermCode * termcode; while (((opcode = buf_getbyte(ses.payload)) != 0x00) && opcode <= 159) { /* handle types of code */ if (opcode > MAX_TERMCODE) { continue; } termcode = &termcodes[(unsigned int)opcode]; value = buf_getint(ses.payload); switch (termcode->type) { case TERMCODE_NONE: break; case TERMCODE_CONTROLCHAR: termio.c_cc[termcode->mapcode] = value; break; case TERMCODE_INPUT: if (value) { termio.c_iflag |= termcode->mapcode; } else { termio.c_iflag &= ~(termcode->mapcode); } break; case TERMCODE_OUTPUT: if (value) { termio.c_oflag |= termcode->mapcode; } else { termio.c_oflag &= ~(termcode->mapcode); } break; case TERMCODE_LOCAL: if (value) { termio.c_lflag |= termcode->mapcode; } else { termio.c_lflag &= ~(termcode->mapcode); } break; case TERMCODE_CONTROL: if (value) { termio.c_cflag |= termcode->mapcode; } else { termio.c_cflag &= ~(termcode->mapcode); } break; } } if (tcsetattr(chansess->master, TCSANOW, &termio) < 0) { dropbear_log(LOG_INFO, "error setting terminal attributes"); } } TRACE(("leave sessionpty")); return DROPBEAR_SUCCESS; }