Exemple #1
0
int ssh_execute_message_callbacks(ssh_session session){
  ssh_message msg=NULL;
  int ret;
  ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
  if(!session->ssh_message_list)
    return SSH_OK;
  if(session->ssh_message_callback){
    while((msg=ssh_message_pop_head(session)) != NULL) {
      ret=session->ssh_message_callback(session,msg,
                                        session->ssh_message_callback_data);
      if(ret==1){
        ret = ssh_message_reply_default(msg);
        ssh_message_free(msg);
        if(ret != SSH_OK)
          return ret;
      } else {
        ssh_message_free(msg);
      }
    }
  } else {
    while((msg=ssh_message_pop_head(session)) != NULL) {
      ret = ssh_message_reply_default(msg);
      ssh_message_free(msg);
      if(ret != SSH_OK)
        return ret;
    }
  }
  return SSH_OK;
}
int channel_write1(ssh_channel channel, const void *data, int len) {
  ssh_session session;
  int origlen = len;
  int effectivelen;
  const unsigned char *ptr=data;

  if (channel == NULL) {
    return -1;
  }
  session = channel->session;

  while (len > 0) {
    if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) {
      return -1;
    }

    effectivelen = len > 32000 ? 32000 : len;

    if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 ||
        buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
      return -1;
    }

    ptr += effectivelen;
    len -= effectivelen;

    if (packet_send(session) == SSH_ERROR) {
      return -1;
    }
    ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
  }
  if (ssh_blocking_flush(session,SSH_TIMEOUT_USER) == SSH_ERROR)
      return -1;
  return origlen;
}
Exemple #3
0
int ssh_send_keepalive(ssh_session session)
{
  int rc;

  rc = ssh_buffer_pack(session->out_buffer,
                       "bsb",
                       SSH2_MSG_GLOBAL_REQUEST,
                       "*****@*****.**",
                       1);
  if (rc != SSH_OK) {
    goto err;
  }

  if (packet_send(session) == SSH_ERROR) {
    goto err;
  }

  ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);

  SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
  return SSH_OK;

err:
  ssh_set_error_oom(session);
  ssh_buffer_reinit(session->out_buffer);
  return SSH_ERROR;
}
Exemple #4
0
int ssh_send_keepalive(ssh_session session)
{
	/* TODO check the reply and all that */
	struct ssh_string_struct *req;
	int reply = 1;
	int rc = SSH_ERROR;

	enter_function();
	req = ssh_string_from_char("*****@*****.**");
	if (req == NULL) {
		ssh_set_error_oom(session);
		goto out;
	}

	if (buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST) < 0 ||
	    buffer_add_ssh_string(session->out_buffer, req) < 0 ||
	    buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
		ssh_set_error_oom(session);
		goto out;
	}

	if (packet_send(session) == SSH_ERROR)
		goto out;

	ssh_handle_packets(session, 0);

	ssh_log(session, SSH_LOG_PACKET, "Sent a keepalive");
	rc = SSH_OK;

out:
	ssh_string_free(req);
	leave_function();
	return rc;
}
Exemple #5
0
int ssh_get_kex1(ssh_session session) {
  SSH_LOG(SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");

  /* Here the callback is called */
  while(session->session_state==SSH_SESSION_STATE_INITIAL_KEX){
    ssh_handle_packets(session, SSH_TIMEOUT_USER);
  }
  if (session->session_state==SSH_SESSION_STATE_ERROR) {
      return SSH_ERROR;
  }
  SSH_LOG(SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
  /* Waiting for SSH_SMSG_SUCCESS */
  while(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
    ssh_handle_packets(session, SSH_TIMEOUT_USER);
  }
  if(session->session_state==SSH_SESSION_STATE_ERROR) {
      return SSH_ERROR;
  }
  SSH_LOG(SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n");

  return SSH_OK;
}
Exemple #6
0
int ssh_get_kex1(ssh_session session) {
  int ret=SSH_ERROR;
  enter_function();
  ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");
  /* Here the callback is called */
  while(session->session_state==SSH_SESSION_STATE_INITIAL_KEX){
    ssh_handle_packets(session, -2);
  }
  if(session->session_state==SSH_SESSION_STATE_ERROR)
    goto error;
  ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
  /* Waiting for SSH_SMSG_SUCCESS */
  while(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
    ssh_handle_packets(session, -2);
  }
  if(session->session_state==SSH_SESSION_STATE_ERROR)
      goto error;
  ssh_log(session, SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n");
  ret=SSH_OK;
error:
  leave_function();
  return ret;
}
int channel_change_pty_size1(ssh_channel channel, int cols, int rows) {
  ssh_session session;

  if (channel == NULL) {
    return SSH_ERROR;
  }
  session = channel->session;

  if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
    ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
    return SSH_ERROR;
  }
  if (buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0 ||
      buffer_add_u32(session->out_buffer, ntohl(rows)) < 0 ||
      buffer_add_u32(session->out_buffer, ntohl(cols)) < 0 ||
      buffer_add_u32(session->out_buffer, 0) < 0 ||
      buffer_add_u32(session->out_buffer, 0) < 0) {
    return SSH_ERROR;
  }
  channel->request_state=SSH_CHANNEL_REQ_STATE_PENDING;
  if (packet_send(session) == SSH_ERROR) {
    return SSH_ERROR;
  }

  ssh_log(session, SSH_LOG_PROTOCOL, "Change pty size send");
  while(channel->request_state==SSH_CHANNEL_REQ_STATE_PENDING){
    ssh_handle_packets(session, SSH_TIMEOUT_INFINITE);
  }
  switch(channel->request_state){
    case SSH_CHANNEL_REQ_STATE_ERROR:
    case SSH_CHANNEL_REQ_STATE_PENDING:
    case SSH_CHANNEL_REQ_STATE_NONE:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      return SSH_ERROR;
    case SSH_CHANNEL_REQ_STATE_ACCEPTED:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      ssh_log(session, SSH_LOG_PROTOCOL, "pty size changed");
      return SSH_OK;
    case SSH_CHANNEL_REQ_STATE_DENIED:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      ssh_log(session, SSH_LOG_RARE, "pty size change denied");
      ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied");
      return SSH_ERROR;
  }
  // Not reached
  return SSH_ERROR;

}
/*
 * This function acts as a meta select.
 *
 * First, channels are analyzed to seek potential can-write or can-read ones,
 * then if no channel has been elected, it goes in a loop with the posix
 * select(2).
 * This is made in two parts: protocol select and network select. The protocol
 * select does not use the network functions at all
 */
static int channel_protocol_select(CHANNEL **rchans, CHANNEL **wchans,
    CHANNEL **echans, CHANNEL **rout, CHANNEL **wout, CHANNEL **eout) {
  CHANNEL *chan;
  int i;
  int j = 0;

  for (i = 0; rchans[i] != NULL; i++) {
    chan = rchans[i];

    while (chan->open && ssh_socket_data_available(chan->session->socket)) {
      ssh_handle_packets(chan->session);
    }

    if ((chan->stdout_buffer && buffer_get_len(chan->stdout_buffer) > 0) ||
        (chan->stderr_buffer && buffer_get_len(chan->stderr_buffer) > 0) ||
        chan->remote_eof) {
      rout[j] = chan;
      j++;
    }
  }
  rout[j] = NULL;

  j = 0;
  for(i = 0; wchans[i] != NULL; i++) {
    chan = wchans[i];
    /* It's not our business to seek if the file descriptor is writable */
    if (ssh_socket_data_writable(chan->session->socket) &&
        chan->open && (chan->remote_window > 0)) {
      wout[j] = chan;
      j++;
    }
  }
  wout[j] = NULL;

  j = 0;
  for (i = 0; echans[i] != NULL; i++) {
    chan = echans[i];

    if (!ssh_socket_is_open(chan->session->socket) || !chan->open) {
      eout[j] = chan;
      j++;
    }
  }
  eout[j] = NULL;

  return 0;
}
Exemple #9
0
static int wait_auth1_status(ssh_session session) {
  enter_function();
  /* wait for a packet */
  while(session->auth_state == SSH_AUTH_STATE_NONE)
    if (ssh_handle_packets(session, -2) != SSH_OK)
      break;
  ssh_log(session,SSH_LOG_PROTOCOL,"Auth state : %d",session->auth_state);
  leave_function();
  switch(session->auth_state) {
    case SSH_AUTH_STATE_SUCCESS:
      return SSH_AUTH_SUCCESS;
    case SSH_AUTH_STATE_FAILED:
      return SSH_AUTH_DENIED;
    default:
      return SSH_AUTH_ERROR;
  }
  return SSH_AUTH_ERROR;
}
Exemple #10
0
/* Do the banner and key exchange */
int ssh_handle_key_exchange(ssh_session session) {
    int rc;

    rc = ssh_send_banner(session, 1);
    if (rc < 0) {
        return SSH_ERROR;
    }

    session->alive = 1;

    session->ssh_connection_callback = ssh_server_connection_callback;
    session->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED;
    ssh_socket_set_callbacks(session->socket,&session->socket_callbacks);
    session->socket_callbacks.data=callback_receive_banner;
    session->socket_callbacks.exception=ssh_socket_exception_callback;
    session->socket_callbacks.userdata=session;

    rc = server_set_kex(session);
    if (rc < 0) {
        return SSH_ERROR;
    }

    while (session->session_state != SSH_SESSION_STATE_ERROR &&
           session->session_state != SSH_SESSION_STATE_AUTHENTICATING &&
           session->session_state != SSH_SESSION_STATE_DISCONNECTED) {
        /*
         * loop until SSH_SESSION_STATE_BANNER_RECEIVED or
         * SSH_SESSION_STATE_ERROR
         */
        ssh_handle_packets(session, -2);
        ssh_log(session,SSH_LOG_PACKET, "ssh_handle_key_exchange: Actual state : %d",
                session->session_state);
    }

    if (session->session_state == SSH_SESSION_STATE_ERROR ||
        session->session_state == SSH_SESSION_STATE_DISCONNECTED) {
        return SSH_ERROR;
    }

  return SSH_OK;
}
Exemple #11
0
int ssh_send_keepalive(ssh_session session)
{
  struct ssh_string_struct *req;
  int rc;

  rc = buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST);
  if (rc < 0) {
    goto err;
  }

  req = ssh_string_from_char("*****@*****.**");
  if (req == NULL) {
    goto err;
  }

  rc = buffer_add_ssh_string(session->out_buffer, req);
  ssh_string_free(req);
  if (rc < 0) {
    goto err;
  }

  rc = buffer_add_u8(session->out_buffer, 1);
  if (rc < 0) {
    goto err;
  }

  if (packet_send(session) == SSH_ERROR) {
    goto err;
  }

  ssh_handle_packets(session, 0);

  SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
  return SSH_OK;

err:
  ssh_set_error_oom(session);
  ssh_buffer_reinit(session->out_buffer);
  return SSH_ERROR;
}
Exemple #12
0
/**
 * @brief Retrieve a SSH message from a SSH session.
 *
 * @param[in]  session  The SSH session to get the message.
 *
 * @returns             The SSH message received, NULL in case of error.
 *
 * @warning This function blocks until a message has been received. Betterset up
 *          a callback if this behavior is unwanted.
 */
ssh_message ssh_message_get(ssh_session session) {
  ssh_message msg = NULL;
  enter_function();

  msg=ssh_message_pop_head(session);
  if(msg) {
      leave_function();
      return msg;
  }
  if(session->ssh_message_list == NULL) {
      session->ssh_message_list = ssh_list_new();
  }
  do {
    if (ssh_handle_packets(session,-1) == SSH_ERROR) {
      leave_function();
      return NULL;
    }
    msg=ssh_list_pop_head(ssh_message, session->ssh_message_list);
  } while(msg==NULL);
  leave_function();
  return msg;
}
/**
 * @brief Polls a channel for data to read.
 *
 * @param channel       The channel to poll.
 *
 * @param is_stderr     A boolean to select the stderr stream.
 *
 * @return The number of bytes available for reading, 0 if nothing is available
 *         or SSH_ERROR on error.
 *
 * @warning When the channel is in EOF state, the function returns SSH_EOF.
 *
 * @see channel_is_eof()
 */
int channel_poll(CHANNEL *channel, int is_stderr){
  SSH_SESSION *session = channel->session;
  BUFFER *stdbuf = channel->stdout_buffer;

  enter_function();

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

  while (buffer_get_rest_len(stdbuf) == 0 && channel->remote_eof == 0) {
    if (ssh_handle_packets(channel->session) <= 0) {
      break;
    }
  }

  if (channel->remote_eof) {
    leave_function();
    return SSH_EOF;
  }

  leave_function();
  return buffer_get_rest_len(stdbuf);
}
int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col,
    int row) {
  ssh_session session;
  ssh_string str = NULL;

  if (channel == NULL) {
    return SSH_ERROR;
  }
  session = channel->session;

  if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
    ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
    return SSH_ERROR;
  }
  str = ssh_string_from_char(terminal);
  if (str == NULL) {
    ssh_set_error_oom(session);
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 ||
      buffer_add_ssh_string(session->out_buffer, str) < 0) {
    ssh_string_free(str);
    return -1;
  }
  ssh_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");
  channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING;
  if (packet_send(session) == SSH_ERROR) {
    return -1;
  }

  while (channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING) {
      ssh_handle_packets(session, SSH_TIMEOUT_INFINITE);
  }

  switch(channel->request_state){
    case SSH_CHANNEL_REQ_STATE_ERROR:
    case SSH_CHANNEL_REQ_STATE_PENDING:
    case SSH_CHANNEL_REQ_STATE_NONE:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      return SSH_ERROR;
    case SSH_CHANNEL_REQ_STATE_ACCEPTED:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      ssh_log(session, SSH_LOG_RARE, "PTY: Success");
      return SSH_OK;
    case SSH_CHANNEL_REQ_STATE_DENIED:
      channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
      ssh_set_error(session, SSH_REQUEST_DENIED,
          "Server denied PTY allocation");
      ssh_log(session, SSH_LOG_RARE, "PTY: denied\n");
      return SSH_ERROR;
  }
  // Not reached
  return SSH_ERROR;
}