예제 #1
0
static void log_option(Telnet telnet, char *sender, int cmd, int option)
{
    char *buf;
    /*
     * The strange-looking "<?""?>" below is there to avoid a
     * trigraph - a double question mark followed by > maps to a
     * closing brace character!
     */
    buf = dupprintf("%s:\t%s %s", sender,
		    (cmd == WILL ? "WILL" : cmd == WONT ? "WONT" :
		     cmd == DO ? "DO" : cmd == DONT ? "DONT" : "<?""?>"),
		    telopt(option));
    logevent(telnet->frontend, buf);
    sfree(buf);
}
예제 #2
0
void term_init()
{
  tel_init();

  telopt(1, WILL, TELOPT_SGA);
  telopt(1, DO,   TELOPT_SGA);
  telopt(1, WILL, TELOPT_BINARY);
  telopt(1, DO,   TELOPT_BINARY);
  telopt(1, WILL, TELOPT_ECHO);
  telopt(1, DO,   TELOPT_WINCH);
}
예제 #3
0
static void process_subneg(Telnet telnet)
{
    unsigned char b[2048], *p, *q;
    int var, value, n;
    char *e;

    switch (telnet->sb_opt) {
      case TELOPT_TSPEED:
	if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
	    char *logbuf;
	    b[0] = IAC;
	    b[1] = SB;
	    b[2] = TELOPT_TSPEED;
	    b[3] = TELQUAL_IS;
	    strcpy((char *)(b + 4), telnet->cfg.termspeed);
	    n = 4 + strlen(telnet->cfg.termspeed);
	    b[n] = IAC;
	    b[n + 1] = SE;
	    telnet->bufsize = sk_write(telnet->s, (char *)b, n + 2);
	    logevent(telnet->frontend, "server:\tSB TSPEED SEND");
	    logbuf = dupprintf("client:\tSB TSPEED IS %s", telnet->cfg.termspeed);
	    logevent(telnet->frontend, logbuf);
	    sfree(logbuf);
	} else
	    logevent(telnet->frontend, "server:\tSB TSPEED <something weird>");
	break;
      case TELOPT_TTYPE:
	if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
	    char *logbuf;
	    b[0] = IAC;
	    b[1] = SB;
	    b[2] = TELOPT_TTYPE;
	    b[3] = TELQUAL_IS;
	    for (n = 0; telnet->cfg.termtype[n]; n++)
		b[n + 4] = (telnet->cfg.termtype[n] >= 'a'
			    && telnet->cfg.termtype[n] <=
			    'z' ? telnet->cfg.termtype[n] + 'A' -
			    'a' : telnet->cfg.termtype[n]);
	    b[n + 4] = IAC;
	    b[n + 5] = SE;
	    telnet->bufsize = sk_write(telnet->s, (char *)b, n + 6);
	    b[n + 4] = 0;
	    logevent(telnet->frontend, "server:\tSB TTYPE SEND");
	    logbuf = dupprintf("client:\tSB TTYPE IS %s", b + 4);
	    logevent(telnet->frontend, logbuf);
	    sfree(logbuf);
	} else
	    logevent(telnet->frontend, "server:\tSB TTYPE <something weird>\r\n");
	break;
      case TELOPT_OLD_ENVIRON:
      case TELOPT_NEW_ENVIRON:
	p = telnet->sb_buf;
	q = p + telnet->sb_len;
	if (p < q && *p == TELQUAL_SEND) {
	    char *logbuf;
	    p++;
	    logbuf = dupprintf("server:\tSB %s SEND", telopt(telnet->sb_opt));
	    logevent(telnet->frontend, logbuf);
	    sfree(logbuf);
	    if (telnet->sb_opt == TELOPT_OLD_ENVIRON) {
		if (telnet->cfg.rfc_environ) {
		    value = RFC_VALUE;
		    var = RFC_VAR;
		} else {
		    value = BSD_VALUE;
		    var = BSD_VAR;
		}
		/*
		 * Try to guess the sense of VAR and VALUE.
		 */
		while (p < q) {
		    if (*p == RFC_VAR) {
			value = RFC_VALUE;
			var = RFC_VAR;
		    } else if (*p == BSD_VAR) {
			value = BSD_VALUE;
			var = BSD_VAR;
		    }
		    p++;
		}
	    } else {
		/*
		 * With NEW_ENVIRON, the sense of VAR and VALUE
		 * isn't in doubt.
		 */
		value = RFC_VALUE;
		var = RFC_VAR;
	    }
	    b[0] = IAC;
	    b[1] = SB;
	    b[2] = telnet->sb_opt;
	    b[3] = TELQUAL_IS;
	    n = 4;
	    e = telnet->cfg.environmt;
	    while (*e) {
		b[n++] = var;
		while (*e && *e != '\t')
		    b[n++] = *e++;
		if (*e == '\t')
		    e++;
		b[n++] = value;
		while (*e)
		    b[n++] = *e++;
		e++;
	    }
	    if (*telnet->cfg.username) {
		b[n++] = var;
		b[n++] = 'U';
		b[n++] = 'S';
		b[n++] = 'E';
		b[n++] = 'R';
		b[n++] = value;
		e = telnet->cfg.username;
		while (*e)
		    b[n++] = *e++;
	    }
	    b[n++] = IAC;
	    b[n++] = SE;
	    telnet->bufsize = sk_write(telnet->s, (char *)b, n);
	    logbuf = dupprintf("client:\tSB %s IS %s%s%s%s",
			       telopt(telnet->sb_opt),
			       *telnet->cfg.username ? "USER="******"",
			       telnet->cfg.username,
			       *telnet->cfg.username ? " " : "",
			       n == 6 ? "<nothing>" :
			       (*telnet->cfg.environmt ? "<stuff>" : ""));
	    logevent(telnet->frontend, logbuf);
	    sfree(logbuf);
	}
	break;
    }
}
예제 #4
0
static void handlenetinput(int len)
{
	int i;
	int cstart = 0;

	for (i = 0; i < len; i++)
	{
		byte c = G.buf[i];

		if (G.telstate == 0) /* most of the time state == 0 */
		{
			if (c == IAC)
			{
				cstart = i;
				G.telstate = TS_IAC;
			}
		}
		else
			switch (G.telstate)
			 {
			 case TS_0:
				 if (c == IAC)
					 G.telstate = TS_IAC;
				 else
					 G.buf[cstart++] = c;
				 break;

			 case TS_IAC:
				 if (c == IAC) /* IAC IAC -> 0xFF */
				 {
					 G.buf[cstart++] = c;
					 G.telstate = TS_0;
					 break;
				 }
				 /* else */
				 switch (c)
				 {
				 case SB:
					 G.telstate = TS_SUB1;
					 break;
				 case DO:
				 case DONT:
				 case WILL:
				 case WONT:
					 G.telwish =  c;
					 G.telstate = TS_OPT;
					 break;
				 default:
					 G.telstate = TS_0;	/* DATA MARK must be added later */
				 }
				 break;
			 case TS_OPT: /* WILL, WONT, DO, DONT */
				 telopt(c);
				 G.telstate = TS_0;
				 break;
			 case TS_SUB1: /* Subnegotiation */
			 case TS_SUB2: /* Subnegotiation */
				 if (subneg(c))
					 G.telstate = TS_0;
				 break;
			 }
	}
	if (G.telstate)
	{
		if (G.iaclen)			iacflush();
		if (G.telstate == TS_0)	G.telstate = 0;

		len = cstart;
	}

	if (len)
		write(1, G.buf, len);
}
예제 #5
0
static void handle_net_input(int len)
{
	int i;
	int cstart = 0;

	for (i = 0; i < len; i++) {
		byte c = G.buf[i];

		if (G.telstate == TS_NORMAL) { /* most typical state */
			if (c == IAC) {
				cstart = i;
				G.telstate = TS_IAC;
			}
			else if (c == '\r') {
				cstart = i + 1;
				G.telstate = TS_CR;
			}
			/* No IACs were seen so far, no need to copy
			 * bytes within G.buf: */
			continue;
		}

		switch (G.telstate) {
		case TS_CR:
			/* Prev char was CR. If cur one is NUL, ignore it.
			 * See RFC 1123 section 3.3.1 for discussion of telnet EOL handling.
			 */
			G.telstate = TS_COPY;
			if (c == '\0')
				break;
			/* else: fall through - need to handle CR IAC ... properly */

		case TS_COPY: /* Prev char was ordinary */
			/* Similar to NORMAL, but in TS_COPY we need to copy bytes */
			if (c == IAC)
				G.telstate = TS_IAC;
			else
				G.buf[cstart++] = c;
			if (c == '\r')
				G.telstate = TS_CR;
			break;

		case TS_IAC: /* Prev char was IAC */
			if (c == IAC) { /* IAC IAC -> one IAC */
				G.buf[cstart++] = c;
				G.telstate = TS_COPY;
				break;
			}
			/* else */
			switch (c) {
			case SB:
				G.telstate = TS_SUB1;
				break;
			case DO:
			case DONT:
			case WILL:
			case WONT:
				G.telwish = c;
				G.telstate = TS_OPT;
				break;
			/* DATA MARK must be added later */
			default:
				G.telstate = TS_COPY;
			}
			break;

		case TS_OPT: /* Prev chars were IAC WILL/WONT/DO/DONT */
			telopt(c);
			G.telstate = TS_COPY;
			break;

		case TS_SUB1: /* Subnegotiation */
		case TS_SUB2: /* Subnegotiation */
			subneg(c); /* can change G.telstate */
			break;
		}
	}

	if (G.telstate != TS_NORMAL) {
		/* We had some IACs, or CR */
		if (G.iaclen)
			iac_flush();
		if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */
			G.telstate = TS_NORMAL;
		len = cstart;
	}

	if (len)
		full_write(STDOUT_FILENO, G.buf, len);
}