Ejemplo n.º 1
0
static InterpretCommand parseoption(TelnetState* ts, TAction action, TOption option)
{

  switch (option)
  {
    case TIMING_MARK:
      // Send a reply when this is a request
      if (action == DO)
        SendOption(ts, WILL, TIMING_MARK);

      break;

    case SUPPRESS_GO_AHEAD:
      break;

    case ECHO:
      if (action == WILL) // we do the echo, not the client !
        SendOption(ts, DONT, ECHO);

      break;

    case NAWS:
      // nothing special to do here...
      break;

    default:
      // Default unknown option, reply DONT/WONT
      if (action == DO || action == WILL)
        SendOption(ts, action<=WONT?DONT:WONT, option);
      break;
  }
  return IC_NOP;
}
Ejemplo n.º 2
0
void TelnetOption::Start()
{
  if (stateLocal == osYes)
    SendOption(TelnetProtocol::cdWILL);

  if (stateRemote == osYes)
    SendOption(TelnetProtocol::cdDO);
}
Ejemplo n.º 3
0
void TelnetProtocol::SendSubNegotiation(int option, const BYTE_vector &params)
{
  SendOption(cdSB, (BYTE)option);

  printf("  ");
  for (BYTE_vector::const_iterator i = params.begin() ; i != params.end() ; i++) {
    BYTE b = *i;

    printf("%u ", (unsigned)b);
    SendRaw(&b, sizeof(b));
  }
  printf("SE\n");

  BYTE buf[2] = {cdIAC, cdSE};

  SendRaw(buf, sizeof(buf));
}
Ejemplo n.º 4
0
void TelnetProtocol::SendSubNegotiation(BYTE option, const BYTE_vector &params)
{
  SendOption(cdSB, option);

  cout << "  ";
  for (BYTE_vector::const_iterator i = params.begin() ; i != params.end() ; i++) {
    BYTE b = *i;

    cout << (unsigned)b << " ";
    streamEncoded += b;

    if (b == cdIAC)
      streamEncoded += b;
  }
  cout << "SE" << endl;

  streamEncoded += (BYTE)cdIAC;
  streamEncoded += (BYTE)cdSE;
}
Ejemplo n.º 5
0
static int l_newinterpreter(lua_State *L)
{
  TelnetState* ts;
  ts = lua_newuserdata(L, sizeof(*ts));
  // Assign the metatable to the userdata
  luaL_getmetatable(L, OBJ_NAME);
  lua_setmetatable(L, -2);


  // Initialize default values
  memset(ts, 0, sizeof(*ts));
  ts->L = L;

  // default settings
  ts->editmode = TELNET_LINE_MODE;
  ts->autocompletefuncref = LUA_NOREF;

  // Parse params
  int historysize = 0;
  if (lua_type(L, -2) == LUA_TTABLE)
  {
    // Edit mode setting
    lua_getfield(L, -2, "mode");
    const char* m = lua_tostring(L, -1);
    if (m)
    {
      if (!strcmp("line", m))
        ts->editmode = TELNET_LINE_MODE;
      else if (!strcmp("edit", m))
        ts->editmode = TELNET_EDIT_MODE;
      else
        luaL_error(L, "mode should be either 'line' or 'edit' (got '%s' instead)", m);
    }
    lua_pop(L, 1);

    if (ts->editmode == TELNET_EDIT_MODE)
    {
      // History Size
      lua_getfield(L, -2, "history");
      historysize = lua_tointeger(L, -1);
      lua_pop(L, 1);

      // Autocomplete function
      lua_getfield(L, -2, "autocomplete");
      if (!lua_isnil(L, -1))
      {
        if (lua_type(L, -1) == LUA_TFUNCTION)
        {
          ts->autocompletefuncref = luaL_ref(L, LUA_REGISTRYINDEX);
          lua_pushnil(L); // to make it even with the following pop
        }
        else
          luaL_error(L, "autocomplete must be a function");
      }

      lua_pop(L, 1);
    }
  }




  if (ts->editmode == TELNET_EDIT_MODE)
  {
    // Do teel initialization and setup
    ts->teel = teel_initialize(teel_reader, teel_writer, ts);
    if (!ts->teel)
      return luaL_error(L, "Failed to initialize teel library");

    teel_sethistorysize(ts->teel, historysize);

    teel_setautocompletefunc(ts->teel, teel_autocomplete);

    // Request that all char are sent when typed
    SendOption(ts, DO, SUPPRESS_GO_AHEAD);
    SendOption(ts, WILL, SUPPRESS_GO_AHEAD);

    // Request to echo
    SendOption(ts, WILL, ECHO);

    // Request negotiation of windows size
    SendOption(ts, DO, NAWS);
  }

  return 1;
}
Ejemplo n.º 6
0
int TelnetProtocol::Write(const void *pBuf, int count)
{
  for (int i = 0 ; i < count ; i++) {
    BYTE ch = ((const BYTE *)pBuf)[i];

    switch (state) {
      case stData:
        if (ch == cdIAC)
          state = stCode;
        else
          WriteRaw(&ch, 1);
        break;
      case stCode:
        switch (ch) {
          case cdIAC:
            WriteRaw(&ch, 1);
            state = stData;
            break;
          case cdSB:
          case cdWILL:
          case cdWONT:
          case cdDO:
          case cdDONT:
            code = ch;
            state = stOption;
            break;
          default:
            printf("RECV: unknown code %u\n", (unsigned)ch);
            state = stData;
        }
        break;
      case stOption:
        printf("RECV: %s %u\n", code2name(code), (unsigned)ch);
        switch (code) {
          case cdSB:
            option = ch;
            params.clear();
            state = stSubParams;
            break;
          case cdWILL:
            switch (options[ch].remoteOptionState) {
              case OptionState::osCant:
                SendOption(cdDONT, ch);
                break;
              case OptionState::osNo:
                options[ch].remoteOptionState = OptionState::osYes;
                SendOption(cdDO, ch);
                break;
              case OptionState::osYes:
                break;
            }
            break;
          case cdWONT:
            switch (options[ch].remoteOptionState) {
              case OptionState::osCant:
              case OptionState::osNo:
                break;
              case OptionState::osYes:
                options[ch].remoteOptionState = OptionState::osNo;
                SendOption(cdDONT, ch);
                break;
            }
            break;
          case cdDO:
            switch (options[ch].localOptionState) {
              case OptionState::osCant:
                SendOption(cdWONT, ch);
                break;
              case OptionState::osNo:
                options[ch].localOptionState = OptionState::osYes;
                SendOption(cdWILL, ch);
                break;
              case OptionState::osYes:
                break;
            }
            break;
          case cdDONT:
            switch (options[ch].localOptionState) {
              case OptionState::osCant:
              case OptionState::osNo:
                break;
              case OptionState::osYes:
                options[ch].localOptionState = OptionState::osNo;
                SendOption(cdWONT, ch);
                break;
            }
            break;
          default:
            printf("  ignored\n");
        };
        if (state == stOption)
          state = stData;
        break;
      case stSubParams:
        if (ch == cdIAC)
          state = stSubCode;
        else
          params.push_back(ch);
        break;
      case stSubCode:
        switch (ch) {
          case cdIAC:
            state = stSubParams;
            break;
          case cdSE:
            printf("  ");
            {
              for (BYTE_vector::const_iterator i = params.begin() ; i != params.end() ; i++)
                printf("%u ", (unsigned)*i);
            }
            printf("SE\n");

            switch (option) {
              case opTerminalType:
                params.clear();
                params.push_back(0);
                params.insert(params.end(), terminalType.begin(), terminalType.end());
                SendSubNegotiation(option, params);
                break;
              default:
                printf("  ignored\n");
            }

            state = stData;
            break;
          default:
            printf("RECV: unknown sub code %u\n", (unsigned)ch);
            state = stData;
        };
        break;
    }
  }

  return count;
}
Ejemplo n.º 7
0
HUB_MSG *TelnetProtocol::Decode(HUB_MSG *pMsg)
{
  _ASSERTE(started == TRUE);
  _ASSERTE(pMsg->type == HUB_MSG_TYPE_LINE_DATA);

  DWORD len = pMsg->u.buf.size;
  BYTE_string org(pMsg->u.buf.pBuf, len);
  const BYTE *pBuf = org.data();

  // discard original data from the stream
  if (!pMsgReplaceBuf(pMsg, HUB_MSG_TYPE_LINE_DATA, NULL, 0))
    return NULL;

  for (; len ; len--) {
    BYTE ch = *pBuf++;

    switch (state) {
      case stData:
        if (ch == cdIAC)
          state = stCode;
        else
          streamDecoded += ch;
        break;
      case stCode:
        switch (ch) {
          case cdIAC:
            streamDecoded += ch;
            state = stData;
            break;
          case cdNOP:
            cout << name << " RECV: " << code2name(ch) << endl;
            state = stData;
            break;
          case cdSB:
          case cdWILL:
          case cdWONT:
          case cdDO:
          case cdDONT:
            code = ch;
            state = stOption;
            break;
          default:
            cout << name << " RECV: unknown code " << (unsigned)ch << endl;
            state = stData;
        }
        break;
      case stOption:
        cout << name << " RECV: " << code2name(code) << " " << (unsigned)ch << endl;
        switch (code) {
          case cdSB:
            option = ch;
            params.clear();
            state = stSubParams;
            break;
          case cdWILL:
            if (options[ch] == NULL || options[ch]->stateRemote == TelnetOption::osCant) {
              SendOption(cdDONT, ch);
            }
            else
            if (options[ch]->stateRemote == TelnetOption::osNo) {
              options[ch]->stateRemote = TelnetOption::osYes;
              SendOption(cdDO, ch);
            }
            break;
          case cdWONT:
            if (options[ch] != NULL && options[ch]->stateRemote == TelnetOption::osYes) {
              options[ch]->stateRemote = TelnetOption::osNo;
              SendOption(cdDONT, ch);
            }
            break;
          case cdDO:
            if (options[ch] == NULL || options[ch]->stateLocal == TelnetOption::osCant) {
              SendOption(cdWONT, ch);
            }
            else
            if (options[ch]->stateLocal == TelnetOption::osNo) {
              options[ch]->stateLocal = TelnetOption::osYes;
              SendOption(cdWILL, ch);
            }
            break;
          case cdDONT:
            if (options[ch] != NULL && options[ch]->stateLocal == TelnetOption::osYes) {
              options[ch]->stateLocal = TelnetOption::osNo;
              SendOption(cdWONT, ch);
            }
            break;
          default:
            cout << "  ignored" << endl;
        };
        if (state == stOption)
          state = stData;
        break;
      case stSubParams:
        if (ch == cdIAC)
          state = stSubCode;
        else
          params.push_back(ch);
        break;
      case stSubCode:
        switch (ch) {
          case cdIAC:
            params.push_back(ch);
            state = stSubParams;
            break;
          case cdSE:
            cout << "  ";
            {
              for (BYTE_vector::const_iterator i = params.begin() ; i != params.end() ; i++)
                cout << (unsigned)*i << " ";
            }
            cout << "SE" << endl;

            if (!options[option] || !options[option]->OnSubNegotiation(params, &pMsg))
              cout << "  ignored" << endl;

            if (!pMsg)
              return NULL;

            state = stData;
            break;
          default:
            cout << name << " RECV: unknown sub code " << (unsigned)ch << endl;
            state = stData;
        };
        break;
    }
  }

  return FlushDecodedStream(pMsg);
}