Exemplo n.º 1
0
Arquivo: ask.go Projeto: beoran/woe
// Switches to "normal, or non-password mode.
func (me *Client) NormalMode() telnet.Event {
	// When the server wants the client to start local echoing again, it s}s
	// "IAC WONT ECHO" - the client must respond to this with "IAC DONT ECHO".
	// Again don't use Q state machine.
	me.telnet.TelnetSendBytes(t.TELNET_IAC, t.TELNET_WONT, t.TELNET_TELOPT_ECHO)
	tev, _, _ := me.TryReadEvent(100)
	if tev != nil && !telnet.IsEventType(tev, t.TELNET_DONT_EVENT) {
		return tev
	}
	return nil
}
Exemplo n.º 2
0
Arquivo: ask.go Projeto: beoran/woe
// Switches to "password" mode.
func (me *Client) PasswordMode() telnet.Event {
	// The server sends "IAC WILL ECHO", meaning "I, the server, will do any
	// echoing from now on." The client should acknowledge this with an IAC DO
	// ECHO, and then stop putting echoed text in the input buffer.
	// It should also do whatever is appropriate for password entry to the input
	// box thing - for example, it might * it out. Text entered in server-echoes
	// mode should also not be placed any command history.
	// don't use the Q state machne for echos
	me.telnet.TelnetSendBytes(t.TELNET_IAC, t.TELNET_WILL, t.TELNET_TELOPT_ECHO)
	tev, _, _ := me.TryReadEvent(100)
	if tev != nil && !telnet.IsEventType(tev, t.TELNET_DO_EVENT) {
		return tev
	}
	return nil
}
Exemplo n.º 3
0
// Negotiate NAWS (window size) support
func (me *Client) SetupNAWS() telnet.Event {
	ok, tev := me.SetupNegotiate(1000, t.TELNET_DO, t.TELNET_TELOPT_NAWS, t.TELNET_WILL_EVENT, t.TELNET_WONT_EVENT)
	if !ok {
		return tev
	}

	tev2, _, _ := me.TryReadEvent(1000)
	if (tev2 == nil) || (!telnet.IsEventType(tev2, t.TELNET_NAWS_EVENT)) {
		return tev2
	}

	nawsevent, ok := tev2.(*telnet.NAWSEvent)
	if ok {
		me.info.w = nawsevent.W
		me.info.h = nawsevent.H
		monolog.Info("Client %d window size #{%d}x#{%d}", me.id, me.info.w, me.info.h)
		me.info.naws = true
	}
	return nil
}
Exemplo n.º 4
0
// Negotiate MTTS/TTYPE (TERMINAL TYPE) support
func (me *Client) SetupTType() telnet.Event {
	me.info.terminals = nil
	ok, tev := me.SetupNegotiate(1000, t.TELNET_DO, t.TELNET_TELOPT_TTYPE, t.TELNET_WILL_EVENT, t.TELNET_WONT_EVENT)
	if !ok {
		return tev
	}

	var last string = "none"
	var now string = ""

	for last != now {
		last = now
		me.telnet.TelnetTTypeSend()
		var tev2 telnet.Event = nil
		// Some clients (like KildClient, but not TinTin or telnet),
		// insist on spamming useless NUL characters
		// here... So we have to retry a few times to get a ttype_is
		// throwing away any undesirable junk in between.
	GET_TTYPE:
		for index := 0; index < 3; index++ {
			tev2, _, _ = me.TryReadEvent(1000)
			if tev2 != nil {
				etyp := telnet.EventTypeOf(tev2)
				monolog.Info("Waiting for TTYPE: %T %v %d", tev2, tev2, etyp)
				if telnet.IsEventType(tev2, t.TELNET_TTYPE_EVENT) {
					monolog.Info("TTYPE received: %T %v %d", tev2, tev2, etyp)
					break GET_TTYPE
				}
			} else { // and some clients don't respond, even
				monolog.Info("Waiting for TTYPE: %T", tev2)
			}
		}

		if tev2 == nil || !telnet.IsEventType(tev2, t.TELNET_TTYPE_EVENT) {
			etyp := telnet.EventTypeOf(tev2)
			monolog.Warning("Received no TTYPE: %T %v %d", tev2, tev2, etyp)
			return tev2
		}

		ttypeevent := tev2.(*telnet.TTypeEvent)
		now = ttypeevent.Name
		if !me.HasTerminal(now) {
			me.info.terminals = append(me.info.terminals, now)
		}
		me.info.terminal = now
	}

	monolog.Info("Client %d supports terminals %v", me.id, me.info.terminals)
	monolog.Info("Client %d active terminal %v", me.id, me.info.terminal)

	//  MTTS support
	for i := range me.info.terminals {
		term := me.info.terminals[i]
		monolog.Info("Checking MTTS support: %s", term)
		if strings.HasPrefix(term, "MTTS ") {
			// it's an mtts terminal
			strnum := strings.TrimPrefix(term, "MTTS ")
			num, err := strconv.Atoi(strnum)
			if err == nil {
				me.info.mtts = num
				monolog.Info("Client %d supports mtts %d", me.id, me.info.mtts)
			} else {
				monolog.Warning("Client %d could not parse mtts %s %v", me.id, strnum, err)
			}
		}
	}
	me.info.ttype = true
	return nil
}