Exemplo n.º 1
0
static int packet_wait1(SSH_SESSION *session, int type, int blocking) {

  enter_function();

  ssh_log(session, SSH_LOG_PROTOCOL, "packet_wait1 waiting for %d", type);

  do {
    if ((packet_read1(session) != SSH_OK) ||
        (packet_translate(session) != SSH_OK)) {
      leave_function();
      return SSH_ERROR;
    }
    ssh_log(session, SSH_LOG_PACKET, "packet_wait1() received a type %d packet",
        session->in_packet.type);
    switch (session->in_packet.type) {
      case SSH_MSG_DISCONNECT:
        packet_parse(session);
        leave_function();
        return SSH_ERROR;
      case SSH_SMSG_STDOUT_DATA:
      case SSH_SMSG_STDERR_DATA:
      case SSH_SMSG_EXITSTATUS:
        if (channel_handle1(session,type) < 0) {
          leave_function();
          return SSH_ERROR;
        }
        break;
      case SSH_MSG_DEBUG:
      case SSH_MSG_IGNORE:
        break;
        /*          case SSH2_MSG_CHANNEL_CLOSE:
                    packet_parse(session);
                    break;;
                    */               
      default:
        if (type && (type != session->in_packet.type)) {
          ssh_set_error(session, SSH_FATAL,
              "packet_wait1(): Received a %d type packet, but expected %d\n",
              session->in_packet.type, type);
          leave_function();
          return SSH_ERROR;
        }
        leave_function();
        return SSH_OK;
    }

    if (blocking == 0) {
      leave_function();
      return SSH_OK;
    }
  } while(1);

  leave_function();
  return SSH_OK;
}
Exemplo n.º 2
0
int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col,
    int row) {
  ssh_session session = channel->session;
  ssh_string str = NULL;

  str = string_from_char(terminal);
  if (str == NULL) {
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 ||
      buffer_add_ssh_string(session->out_buffer, str) < 0) {
    string_free(str);
    return -1;
  }
  string_free(str);

  if (buffer_add_u32(session->out_buffer, ntohl(row)) < 0 ||
      buffer_add_u32(session->out_buffer, ntohl(col)) < 0 ||
      buffer_add_u32(session->out_buffer, 0) < 0 || /* x */
      buffer_add_u32(session->out_buffer, 0) < 0 || /* y */
      buffer_add_u8(session->out_buffer, 0) < 0) { /* tty things */
    return -1;
  }

  ssh_log(session, SSH_LOG_FUNCTIONS, "Opening a ssh1 pty");
  if (packet_send(session) != SSH_OK ||
      packet_read(session) != SSH_OK ||
      packet_translate(session) != SSH_OK) {
    return -1;
  }

  switch (session->in_packet.type) {
    case SSH_SMSG_SUCCESS:
      ssh_log(session, SSH_LOG_RARE, "PTY: Success");
      return 0;
      break;
    case SSH_SMSG_FAILURE:
      ssh_set_error(session, SSH_REQUEST_DENIED,
          "Server denied PTY allocation");
      ssh_log(session, SSH_LOG_RARE, "PTY: denied\n");
      break;
    default:
      ssh_log(session, SSH_LOG_RARE, "PTY: error\n");
      ssh_set_error(session, SSH_FATAL,
          "Received unexpected packet type %d",
          session->in_packet.type);
      return -1;
  }

  return -1;
}
Exemplo n.º 3
0
static int packet_wait2(SSH_SESSION *session, int type, int blocking) {
  int rc = SSH_ERROR;

  enter_function();
  do {
    rc = packet_read2(session);
    if (rc != SSH_OK) {
      leave_function();
      return rc;
    }
    if (packet_translate(session) != SSH_OK) {
      leave_function();
      return SSH_ERROR;
    }
    switch (session->in_packet.type) {
      case SSH2_MSG_DISCONNECT:
        packet_parse(session);
        ssh_log(session, SSH_LOG_PACKET, "received disconnect packet");
        leave_function();
        return SSH_ERROR;
      case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
      case SSH2_MSG_CHANNEL_DATA:
      case SSH2_MSG_CHANNEL_EXTENDED_DATA:
      case SSH2_MSG_CHANNEL_REQUEST:
      case SSH2_MSG_CHANNEL_EOF:
      case SSH2_MSG_CHANNEL_CLOSE:
        packet_parse(session);
        break;
      case SSH2_MSG_IGNORE:
        break;
      default:
        if (type && (type != session->in_packet.type)) {
          ssh_set_error(session, SSH_FATAL,
              "packet_wait2(): Received a %d type packet, but expected a %d\n",
              session->in_packet.type, type);
          leave_function();
          return SSH_ERROR;
        }
        leave_function();
        return SSH_OK;
    }
    if (blocking == 0) {
      leave_function();
      return SSH_OK; //shouldn't it return SSH_AGAIN here ?
    }
  } while(1);

  leave_function();
  return SSH_OK;
}
Exemplo n.º 4
0
/**
 * @brief Reads data from a channel.
 *
 * @param channel       The channel to read from.
 *
 * @param dest          The destination buffer which will get the data.
 *
 * @param count         The count of bytes to be read.
 *
 * @param is_stderr     A boolean value to mark reading from the stderr flow.
 *
 * @return The number of bytes read, 0 on end of file or SSH_ERROR on error.
 *
 * @warning The read function using a buffer has been renamed to
 *          channel_read_buffer().
 */
int channel_read(CHANNEL *channel, void *dest, u32 count, int is_stderr) {
  SSH_SESSION *session = channel->session;
  BUFFER *stdbuf = channel->stdout_buffer;
  u32 len;

  enter_function();

  if (count == 0) {
    leave_function();
    return 0;
  }

  if (is_stderr) {
    stdbuf=channel->stderr_buffer;
  }

  /*
   * We may have problem if the window is too small to accept as much data
   * as asked
   */
  ssh_log(session, SSH_LOG_PROTOCOL,
      "Read (%d) buffered : %d bytes. Window: %d",
      count,
      buffer_get_rest_len(stdbuf),
      channel->local_window);

  if (count > buffer_get_rest_len(stdbuf) + channel->local_window) {
    if (grow_window(session, channel,
          count - buffer_get_rest_len(stdbuf)) < 0) {
      leave_function();
      return -1;
    }
  }

  /* block reading if asked bytes=0 */
  while (buffer_get_rest_len(stdbuf) == 0 ||
      buffer_get_rest_len(stdbuf) < count) {
    if (channel->remote_eof && buffer_get_rest_len(stdbuf) == 0) {
      leave_function();
      return 0;
    }

    if (channel->remote_eof) {
      /* Return the resting bytes in buffer */
      break;
    }

    if (buffer_get_rest_len(stdbuf) >= count) {
      /* Stop reading when buffer is full enough */
      break;
    }

    if ((packet_read(session)) != SSH_OK ||
        (packet_translate(session) != SSH_OK)) {
      leave_function();
      return -1;
    }
    packet_parse(session);
  }

  if (channel->local_window < WINDOWLIMIT) {
    if (grow_window(session, channel, 0) < 0) {
      leave_function();
      return -1;
    }
  }

  len = buffer_get_rest_len(stdbuf);
  /* Read count bytes if len is greater, everything otherwise */
  len = (len > count ? count : len);
  memcpy(dest, buffer_get_rest(stdbuf), len);
  buffer_pass_bytes(stdbuf,len);

  leave_function();
  return len;
}
Exemplo n.º 5
0
static int wait_auth_status(SSH_SESSION *session,int kbdint){
    int err=SSH_AUTH_ERROR;
    int cont=1;
    STRING *auth;
    u8 partial=0;
    int todo = 0;
    char *auth_methods = NULL;
    enter_function();
    while(cont){
        if(packet_read(session))
            break;
        if(packet_translate(session))
            break;
        switch(session->in_packet.type){
            case SSH2_MSG_USERAUTH_FAILURE:
                auth = buffer_get_ssh_string(session->in_buffer);
                if(!auth || buffer_get_u8(session->in_buffer,&partial)!=1 ){
                    ssh_set_error(session,SSH_FATAL,
                            "invalid SSH_MSG_USERAUTH_FAILURE message");
                    leave_function();
                    return SSH_AUTH_ERROR;
                }
                auth_methods = string_to_char(auth);
                if(partial) {
                    err=SSH_AUTH_PARTIAL;
                    ssh_set_error(session,SSH_NO_ERROR,"partial success, authentications that can continue : %s", auth_methods);
                } else {
                    err=SSH_AUTH_DENIED;
                    ssh_set_error(session,SSH_REQUEST_DENIED,"Access denied. authentications that can continue : %s", auth_methods);

                    session->auth_methods = 0;
                    if (strstr(auth_methods, "password") != NULL) {
                        session->auth_methods |= SSH_AUTH_METHOD_PASSWORD;
                    }
                    if (strstr(auth_methods, "keyboard-interactive") != NULL) {
                        session->auth_methods |= SSH_AUTH_METHOD_INTERACTIVE;
                    }
                    if (strstr(auth_methods, "publickey") != NULL) {
                        session->auth_methods |= SSH_AUTH_METHOD_PUBLICKEY;
                    }
                    if (strstr(auth_methods, "hostbased") != NULL) {
                        session->auth_methods |= SSH_AUTH_METHOD_HOSTBASED;
                    }
                }


                free(auth);
                free(auth_methods);
                cont=0;
                break;
            case SSH2_MSG_USERAUTH_PK_OK:
                /* SSH monkeys have defined the same number for both */
                /* SSH_MSG_USERAUTH_PK_OK and SSH_MSG_USERAUTH_INFO_REQUEST */
                /* which is not really smart; */
          /*case SSH2_MSG_USERAUTH_INFO_REQUEST: */
                if(kbdint){
                    err=SSH_AUTH_INFO;
                    cont=0;
                    break;
                }
                /* continue through success */
            case SSH2_MSG_USERAUTH_SUCCESS:
                err=SSH_AUTH_SUCCESS;
                cont=0;
                break;
            case SSH2_MSG_USERAUTH_BANNER:
                {
                    STRING *banner=buffer_get_ssh_string(session->in_buffer);
                    if(!banner){
                        ssh_say(1,"The banner message was invalid. continuing though\n");
                        break;
                    }
                    ssh_say(2,"Received a message banner\n");
                    if(session->banner)
                        free(session->banner); /* erase the older one */
                    session->banner=banner;
                    break;
                }
            default:
                packet_parse(session);
                break;
        }
    }
    leave_function();
    return err;
}
Exemplo n.º 6
0
static int wait_auth_status(ssh_session session, int kbdint) {
  char *auth_methods = NULL;
  ssh_string auth;
  int rc = SSH_AUTH_ERROR;
  int cont = 1;
  uint8_t partial = 0;

  enter_function();

  while (cont) {
    if (packet_read(session) != SSH_OK) {
      break;
    }
    if (packet_translate(session) != SSH_OK) {
      break;
    }

    switch (session->in_packet.type) {
      case SSH2_MSG_USERAUTH_FAILURE:
        auth = buffer_get_ssh_string(session->in_buffer);
        if (auth == NULL || buffer_get_u8(session->in_buffer, &partial) != 1) {
          ssh_set_error(session, SSH_FATAL,
              "Invalid SSH_MSG_USERAUTH_FAILURE message");
          leave_function();
          return SSH_AUTH_ERROR;
        }

        auth_methods = string_to_char(auth);
        if (auth_methods == NULL) {
          ssh_set_error(session, SSH_FATAL,
              "Not enough space");
          string_free(auth);
          leave_function();
          return SSH_AUTH_ERROR;
        }

        if (partial) {
          rc = SSH_AUTH_PARTIAL;
          ssh_set_error(session, SSH_NO_ERROR,
              "Partial success. Authentication that can continue: %s",
              auth_methods);
        } else {
          rc = SSH_AUTH_DENIED;
          ssh_set_error(session, SSH_REQUEST_DENIED,
              "Access denied. Authentication that can continue: %s",
              auth_methods);

          session->auth_methods = 0;
          if (strstr(auth_methods, "password") != NULL) {
            session->auth_methods |= SSH_AUTH_METHOD_PASSWORD;
          }
          if (strstr(auth_methods, "keyboard-interactive") != NULL) {
            session->auth_methods |= SSH_AUTH_METHOD_INTERACTIVE;
          }
          if (strstr(auth_methods, "publickey") != NULL) {
            session->auth_methods |= SSH_AUTH_METHOD_PUBLICKEY;
          }
          if (strstr(auth_methods, "hostbased") != NULL) {
            session->auth_methods |= SSH_AUTH_METHOD_HOSTBASED;
          }
        }

        string_free(auth);
        SAFE_FREE(auth_methods);
        cont = 0;
        break;
      case SSH2_MSG_USERAUTH_PK_OK:
        /* SSH monkeys have defined the same number for both */
        /* SSH_MSG_USERAUTH_PK_OK and SSH_MSG_USERAUTH_INFO_REQUEST */
        /* which is not really smart; */
        /*case SSH2_MSG_USERAUTH_INFO_REQUEST: */
        if (kbdint) {
          rc = SSH_AUTH_INFO;
          cont = 0;
          break;
        }
        /* continue through success */
      case SSH2_MSG_USERAUTH_SUCCESS:
        rc = SSH_AUTH_SUCCESS;
        cont = 0;
        break;
      case SSH2_MSG_USERAUTH_BANNER:
        {
          ssh_string banner;

          banner = buffer_get_ssh_string(session->in_buffer);
          if (banner == NULL) {
            ssh_log(session, SSH_LOG_PACKET,
                "The banner message was invalid. Continuing though\n");
            break;
          }
          ssh_log(session, SSH_LOG_PACKET,
              "Received a message banner\n");
          string_free(session->banner); /* erase the older one */
          session->banner = banner;
          break;
        }
      default:
        packet_parse(session);
        break;
    }
  }

  leave_function();
  return rc;
}