Example #1
0
/** @internal
 * @brief prepends a packet with the pcap header and writes packet
 * on file
 */
int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, uint32_t original_len){
	ssh_buffer header=ssh_buffer_new();
	struct timeval now;
	int err;
	if(header == NULL)
		return SSH_ERROR;
	gettimeofday(&now,NULL);
	buffer_add_u32(header,htonl(now.tv_sec));
	buffer_add_u32(header,htonl(now.tv_usec));
	buffer_add_u32(header,htonl(buffer_get_rest_len(packet)));
	buffer_add_u32(header,htonl(original_len));
	buffer_add_buffer(header,packet);
	err=ssh_pcap_file_write(pcap,header);
	ssh_buffer_free(header);
	return err;
}
Example #2
0
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;
}
Example #3
0
int ssh_message_channel_request_reply_success(ssh_message msg) {
  uint32_t channel;

  if (msg == NULL) {
    return SSH_ERROR;
  }

  if (msg->channel_request.want_reply) {
    channel = msg->channel_request.channel->remote_channel;

    SSH_LOG(SSH_LOG_PACKET,
        "Sending a channel_request success to channel %d", channel);

    if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_CHANNEL_SUCCESS) < 0) {
      return SSH_ERROR;
    }
    if (buffer_add_u32(msg->session->out_buffer, htonl(channel)) < 0) {
      return SSH_ERROR;
    }

    return packet_send(msg->session);
  }

  SSH_LOG(SSH_LOG_PACKET,
      "The client doesn't want to know the request succeeded");

  return SSH_OK;
}
int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_port) {
    SSH_LOG(SSH_LOG_FUNCTIONS, "Accepting a global request");

    if (msg->global_request.want_reply) {
        if (buffer_add_u8(msg->session->out_buffer
                    , SSH2_MSG_REQUEST_SUCCESS) < 0) {
            goto error;
        }

        if(msg->global_request.type == SSH_GLOBAL_REQUEST_TCPIP_FORWARD 
                                && msg->global_request.bind_port == 0) {
            if (buffer_add_u32(msg->session->out_buffer, htonl(bound_port)) < 0) {
                goto error;
            }
        }

        return packet_send(msg->session);
    }

    if(msg->global_request.type == SSH_GLOBAL_REQUEST_TCPIP_FORWARD 
                                && msg->global_request.bind_port == 0) {
        SSH_LOG(SSH_LOG_PACKET,
                "The client doesn't want to know the remote port!");
    }

    return SSH_OK;
error:
    return SSH_ERROR;
}
Example #5
0
int channel_write1(ssh_channel channel, const void *data, int len) {
  ssh_session session = channel->session;
  int origlen = len;
  int effectivelen;
  const unsigned char *ptr=data;
  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_OK) {
      return -1;
    }
  }

  return origlen;
}
Example #6
0
/* this function sends the first packet as explained in section 3.1
 * of the draft */
static int kbdauth_init(ssh_session session, const char *user,
    const char *submethods) {
  ssh_string usr = NULL;
  ssh_string sub = NULL;
  ssh_string service = NULL;
  ssh_string method = NULL;
  int rc = SSH_AUTH_ERROR;

  enter_function();

  usr = string_from_char(user);
  if (usr == NULL) {
    goto error;
  }
  sub = (submethods ? string_from_char(submethods) : string_from_char(""));
  if (sub == NULL) {
    goto error;
  }
  service = string_from_char("ssh-connection");
  if (service == NULL) {
    goto error;
  }
  method = string_from_char("keyboard-interactive");
  if (method == NULL) {
    goto error;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST) < 0 ||
      buffer_add_ssh_string(session->out_buffer, usr) < 0 ||
      buffer_add_ssh_string(session->out_buffer, service) < 0 ||
      buffer_add_ssh_string(session->out_buffer, method) < 0 ||
      buffer_add_u32(session->out_buffer, 0) < 0 ||
      buffer_add_ssh_string(session->out_buffer, sub) < 0) {
    goto error;
  }

  string_free(usr);
  string_free(service);
  string_free(method);
  string_free(sub);

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return rc;
  }
  rc = wait_auth_status(session,1);

  leave_function();
  return rc;
error:
  buffer_reinit(session->out_buffer);
  string_free(usr);
  string_free(service);
  string_free(method);
  string_free(sub);

  leave_function();
  return rc;
}
Example #7
0
/* this function only sends the predefined set of kex methods */
int ssh_send_kex(ssh_session session, int server_kex) {
  struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex :
      &session->next_crypto->client_kex);
  ssh_string str = NULL;
  int i;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
    goto error;
  }
  if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
    goto error;
  }

  if (hashbufout_add_cookie(session) < 0) {
    goto error;
  }

  ssh_list_kex(session, kex);

  for (i = 0; i < KEX_METHODS_SIZE; i++) {
    str = ssh_string_from_char(kex->methods[i]);
    if (str == NULL) {
      goto error;
    }

    if (buffer_add_ssh_string(session->out_hashbuf, str) < 0) {
      goto error;
    }
    if (buffer_add_ssh_string(session->out_buffer, str) < 0) {
      goto error;
    }
    ssh_string_free(str);
  }

  if (buffer_add_u8(session->out_buffer, 0) < 0) {
    goto error;
  }
  if (buffer_add_u32(session->out_buffer, 0) < 0) {
    goto error;
  }

  if (packet_send(session) == SSH_ERROR) {
    leave_function();
    return -1;
  }

  leave_function();
  return 0;
error:
  buffer_reinit(session->out_buffer);
  buffer_reinit(session->out_hashbuf);
  ssh_string_free(str);

  leave_function();
  return -1;
}
Example #8
0
/** @internal
 * @brief sends a SSH_MSG_UNIMPLEMENTED answer to an unhandled packet
 * @param session the SSH session
 * @param seqnum the sequence number of the unknown packet
 * @return SSH_ERROR on error, else SSH_OK
 */
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum){
  int r;
  enter_function();
  buffer_add_u8(session->out_buffer, SSH2_MSG_UNIMPLEMENTED);
  buffer_add_u32(session->out_buffer, htonl(seqnum));
  r = packet_send(session);
  leave_function();
  return r;
}
Example #9
0
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
    ssh_string str;
    int rc;
    int i;
    rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
    if (rc < 0) {
        goto fail;
    }
    /* username */
    str = ssh_string_from_char(session->opts.username);
    if (str == NULL) {
        goto fail;
    }
    rc = buffer_add_ssh_string(session->out_buffer, str);
    ssh_string_free(str);
    if (rc < 0) {
        goto fail;
    }
    /* service */
    str = ssh_string_from_char("ssh-connection");
    if (str == NULL) {
        goto fail;
    }
    rc = buffer_add_ssh_string(session->out_buffer, str);
    ssh_string_free(str);
    if (rc < 0) {
        goto fail;
    }
    /* method */
    str = ssh_string_from_char("gssapi-with-mic");
    if (str == NULL) {
        goto fail;
    }
    rc = buffer_add_ssh_string(session->out_buffer, str);
    ssh_string_free(str);
    if (rc < 0) {
        goto fail;
    }

    rc = buffer_add_u32(session->out_buffer, htonl(n_oid));
    if (rc < 0) {
        goto fail;
    }

    for (i=0; i<n_oid; ++i){
        rc = buffer_add_ssh_string(session->out_buffer, oid_set[i]);
        if (rc < 0) {
            goto fail;
        }
    }

    session->auth_state = SSH_AUTH_STATE_GSSAPI_REQUEST_SENT;
    return packet_send(session);
fail:
    buffer_reinit(session->out_buffer);
    return SSH_ERROR;
}
Example #10
0
/* this function only sends the predefined set of kex methods */
int ssh_send_kex(SSH_SESSION *session, int server_kex) {
  KEX *kex = (server_kex ? &session->server_kex : &session->client_kex);
  STRING *str = NULL;
  int i;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
    goto error;
  }
  if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
    goto error;
  }

  if (hashbufout_add_cookie(session) < 0) {
    goto error;
  }

  ssh_list_kex(session, kex);

  for (i = 0; i < 10; i++) {
    str = string_from_char(kex->methods[i]);
    if (str == NULL) {
      goto error;
    }

    if (buffer_add_ssh_string(session->out_hashbuf, str) < 0) {
      goto error;
    }
    if (buffer_add_ssh_string(session->out_buffer, str) < 0) {
      goto error;
    }
    string_free(str);
  }

  if (buffer_add_u8(session->out_buffer, 0) < 0) {
    goto error;
  }
  if (buffer_add_u32(session->out_buffer, 0) < 0) {
    goto error;
  }

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return -1;
  }

  leave_function();
  return 0;
error:
  buffer_free(session->out_buffer);
  buffer_free(session->out_hashbuf);
  string_free(str);

  leave_function();
  return -1;
}
Example #11
0
int sftp_reply_attr(SFTP_CLIENT_MESSAGE *msg, SFTP_ATTRIBUTES *attr) {
    BUFFER *out=buffer_new();
    int r;
    buffer_add_u32(out,msg->id);
    buffer_add_attributes(out,attr);
    r=sftp_packet_write(msg->sftp,SSH_FXP_ATTRS,out);
    buffer_free(out);
    return r<0;
}
Example #12
0
int sftp_reply_handle(SFTP_CLIENT_MESSAGE *msg, STRING *handle) {
    BUFFER *out=buffer_new();
    int r;
    buffer_add_u32(out,msg->id);
    buffer_add_ssh_string(out,handle);
    r=sftp_packet_write(msg->sftp,SSH_FXP_HANDLE,out);
    buffer_free(out);
    return r<0;
}
Example #13
0
/**
 * @brief Open a TCP/IP forwarding channel.
 *
 * @param channel       An allocated channel.
 *
 * @param remotehost    The remote host to connected (host name or IP).
 *
 * @param remoteport    The remote port.
 *
 * @param sourcehost    The source host (your local computer). It's facultative
 *                      and for logging purpose.
 *
 * @param localport     The source port (your local computer). It's facultative
 *                      and for logging purpose.
 *
 * @return SSH_OK on success\n
 *         SSH_ERROR on error
 */
int channel_open_forward(CHANNEL *channel, const char *remotehost,
    int remoteport, const char *sourcehost, int localport) {
  SSH_SESSION *session = channel->session;
  BUFFER *payload = NULL;
  STRING *str = NULL;
  int rc = SSH_ERROR;

  enter_function();

  payload = buffer_new();
  if (payload == NULL) {
    goto error;
  }
  str = string_from_char(remotehost);
  if (str == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(payload, str) < 0 ||
      buffer_add_u32(payload,htonl(remoteport)) < 0) {
    goto error;
  }

  string_free(str);
  str = string_from_char(sourcehost);
  if (str == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(payload, str) < 0 ||
      buffer_add_u32(payload,htonl(localport)) < 0) {
    goto error;
  }

  rc = channel_open(channel, "direct-tcpip", 64000, 32000, payload);

error:
  buffer_free(payload);
  string_free(str);

  leave_function();
  return rc;
}
Example #14
0
/**
 * @brief Request a pty with a specific type and size.
 *
 * @param channel       The channel to sent the request.
 *
 * @param terminal      The terminal type ("vt100, xterm,...").
 *
 * @param col           The number of columns.
 *
 * @param row           The number of rows.
 *
 * @return SSH_SUCCESS on success, SSH_ERROR on error.
 */
int channel_request_pty_size(CHANNEL *channel, const char *terminal,
    int col, int row) {
  SSH_SESSION *session = channel->session;
  STRING *term = NULL;
  BUFFER *buffer = NULL;
  int rc = SSH_ERROR;

  enter_function();
#ifdef HAVE_SSH1
  if (channel->version==1) {
    channel_request_pty_size1(channel,terminal, col, row);
    leave_function();
    return rc;
    }
#endif
  buffer = buffer_new();
  if (buffer == NULL) {
    goto error;
  }

  term = string_from_char(terminal);
  if (term == NULL) {
    goto error;
  }

  if (buffer_add_ssh_string(buffer, term) < 0 ||
      buffer_add_u32(buffer, htonl(col)) < 0 ||
      buffer_add_u32(buffer, htonl(row)) < 0 ||
      buffer_add_u32(buffer, 0) < 0 ||
      buffer_add_u32(buffer, 0) < 0 ||
      buffer_add_u32(buffer, htonl(1)) < 0 || /* Add a 0byte string */
      buffer_add_u8(buffer, 0) < 0) {
    goto error;
  }

  rc = channel_request(channel, "pty-req", buffer, 1);
error:
  buffer_free(buffer);
  string_free(term);

  leave_function();
  return rc;
}
Example #15
0
/* Reduced version of the reply default that only reply with
 * SSH_MSG_UNIMPLEMENTED
 */
static int ssh_message_reply_default(ssh_message msg) {
  SSH_LOG(SSH_LOG_FUNCTIONS, "Reporting unknown packet");

  if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_UNIMPLEMENTED) < 0)
    goto error;
  if (buffer_add_u32(msg->session->out_buffer,
      htonl(msg->session->recv_seq-1)) < 0)
    goto error;
  return packet_send(msg->session);
  error:
  return SSH_ERROR;
}
Example #16
0
int channel_change_pty_size1(ssh_channel channel, int cols, int rows) {
  ssh_session session = channel->session;

  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 -1;
  }

  if (packet_send(session)) {
    return -1;
  }

  ssh_log(session, SSH_LOG_RARE, "Change pty size send");

  if (packet_wait(session, SSH_SMSG_SUCCESS, 1) != SSH_OK) {
    return -1;
  }

  switch (session->in_packet.type) {
    case SSH_SMSG_SUCCESS:
      ssh_log(session, SSH_LOG_RARE, "pty size changed");
      return 0;
    case SSH_SMSG_FAILURE:
      ssh_log(session, SSH_LOG_RARE, "pty size change denied");
      ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied");
      return -1;
  }

  ssh_set_error(session, SSH_FATAL, "Received unexpected packet type %d",
      session->in_packet.type);

  return -1;
}
Example #17
0
/** @internal
 * @brief sends a SSH_MSG_UNIMPLEMENTED answer to an unhandled packet
 * @param session the SSH session
 * @param seqnum the sequence number of the unknown packet
 * @return SSH_ERROR on error, else SSH_OK
 */
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum){
  int r;

  r = buffer_add_u8(session->out_buffer, SSH2_MSG_UNIMPLEMENTED);
  if (r < 0) {
    return SSH_ERROR;
  }
  r = buffer_add_u32(session->out_buffer, htonl(seqnum));
  if (r < 0) {
    return SSH_ERROR;
  }
  r = packet_send(session);

  return r;
}
Example #18
0
/** \brief disconnect from a session (client or server)
 * \param session ssh session
 */
void ssh_disconnect(SSH_SESSION *session){
    STRING *str;
    if(session->fd!= -1) {
        packet_clear_out(session);
        buffer_add_u8(session->out_buffer,SSH2_MSG_DISCONNECT);
        buffer_add_u32(session->out_buffer,htonl(SSH2_DISCONNECT_BY_APPLICATION));
        str=string_from_char("Bye Bye");
        buffer_add_ssh_string(session->out_buffer,str);
        free(str);
        packet_send(session);
        close(session->fd);
        session->fd=-1;
    }
    session->alive=0;
    ssh_cleanup(session);
}
Example #19
0
static int ssh_gssapi_send_mic(ssh_session session){
    OM_uint32 maj_stat, min_stat;
    gss_buffer_desc mic_buf = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc mic_token_buf = GSS_C_EMPTY_BUFFER;
    ssh_buffer mic_buffer;
    int rc;

    SSH_LOG(SSH_LOG_PACKET,"Sending SSH_MSG_USERAUTH_GSSAPI_MIC");

    mic_buffer = ssh_gssapi_build_mic(session);
    if (mic_buffer == NULL) {
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }
    mic_buf.length = ssh_buffer_get_len(mic_buffer);
    mic_buf.value = ssh_buffer_get_begin(mic_buffer);

    maj_stat = gss_get_mic(&min_stat,session->gssapi->ctx, GSS_C_QOP_DEFAULT, &mic_buf, &mic_token_buf);
    if (GSS_ERROR(maj_stat)){
        ssh_buffer_free(mic_buffer);
        ssh_gssapi_log_error(0, "generating MIC", maj_stat);
        return SSH_ERROR;
    }

    rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_MIC);
    if (rc < 0) {
        ssh_buffer_free(mic_buffer);
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }

    rc = buffer_add_u32(session->out_buffer, htonl(mic_token_buf.length));
    if (rc < 0) {
        ssh_buffer_free(mic_buffer);
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }

    rc = buffer_add_data(session->out_buffer, mic_token_buf.value, mic_token_buf.length);
    ssh_buffer_free(mic_buffer);
    if (rc < 0) {
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }

    return packet_send(session);
}
Example #20
0
/* sends challenge back to the server */
static int kbdauth_send(ssh_session session) {
  ssh_string answer = NULL;
  int rc = SSH_AUTH_ERROR;
  uint32_t i;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE) < 0 ||
      buffer_add_u32(session->out_buffer,
        htonl(session->kbdint->nprompts)) < 0) {
    goto error;
  }

  for (i = 0; i < session->kbdint->nprompts; i++) {
    if (session->kbdint->answers[i]) {
      answer = string_from_char(session->kbdint->answers[i]);
    } else {
      answer = string_from_char("");
    }
    if (answer == NULL) {
      goto error;
    }

    if (buffer_add_ssh_string(session->out_buffer, answer) < 0) {
      goto error;
    }

    string_burn(answer);
    string_free(answer);
  }

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return rc;
  }
  rc = wait_auth_status(session,1);

  leave_function();
  return rc;
error:
  buffer_reinit(session->out_buffer);
  string_burn(answer);
  string_free(answer);

  leave_function();
  return rc;
}
Example #21
0
/* this function only sends the predefined set of kex methods */    
void ssh_send_kex(SSH_SESSION *session, int server_kex){
    STRING *str;
    int i=0;
    KEX *kex=(server_kex ? &session->server_kex : &session->client_kex);
    packet_clear_out(session);
    buffer_add_u8(session->out_buffer,SSH2_MSG_KEXINIT);
    buffer_add_data(session->out_buffer,kex->cookie,16);
    hashbufout_add_cookie(session);
    ssh_list_kex(kex);
    for(i=0;i<10;i++){
        str=string_from_char(kex->methods[i]);
        buffer_add_ssh_string(session->out_hashbuf,str);
        buffer_add_ssh_string(session->out_buffer,str);
        free(str);
    }
    i=0;
    buffer_add_u8(session->out_buffer,0);
    buffer_add_u32(session->out_buffer,0);
    packet_send(session);
}
Example #22
0
/**
 * @brief Close a channel.
 *
 * This sends an end of file and then closes the channel. You won't be able
 * to recover any data the server was going to send or was in buffers.
 *
 * @param channel       The channel to close.
 *
 * @return SSH_SUCCESS on success\n
 *         SSH_ERROR on error
 *
 * @see channel_free()
 * @see channel_eof()
 */
int channel_close(CHANNEL *channel){
  SSH_SESSION *session = channel->session;
  int rc = 0;

  enter_function();

  if (channel->local_eof == 0) {
    rc = channel_send_eof(channel);
  }

  if (rc != SSH_OK) {
    leave_function();
    return rc;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_CLOSE) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->remote_channel)) < 0) {
    goto error;
  }

  rc = packet_send(session);
  ssh_log(session, SSH_LOG_PACKET,
      "Sent a close on client channel (%d:%d)",
      channel->local_channel,
      channel->remote_channel);

  if(rc == SSH_OK) {
    channel->open = 0;
  }

  leave_function();
  return rc;
error:
  buffer_free(session->out_buffer);

  leave_function();
  return rc;
}
Example #23
0
static int ssh_message_channel_request_reply_default(ssh_message msg) {
  uint32_t channel;

  if (msg->channel_request.want_reply) {
    channel = msg->channel_request.channel->remote_channel;

    SSH_LOG(SSH_LOG_PACKET,
        "Sending a default channel_request denied to channel %d", channel);

    if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_CHANNEL_FAILURE) < 0) {
      return SSH_ERROR;
    }
    if (buffer_add_u32(msg->session->out_buffer, htonl(channel)) < 0) {
      return SSH_ERROR;
    }

    return packet_send(msg->session);
  }

  SSH_LOG(SSH_LOG_PACKET,
      "The client doesn't want to know the request failed!");

  return SSH_OK;
}
Example #24
0
/* sends challenge back to the server */
static int kbdauth_send(SSH_SESSION *session) {
    STRING *answer;
    u32 i;
    int err;
    enter_function();
    buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_INFO_RESPONSE);
    buffer_add_u32(session->out_buffer,htonl(session->kbdint->nprompts));
    for(i=0;i<session->kbdint->nprompts;++i){
        if(session->kbdint->answers[i])
            answer=string_from_char(session->kbdint->answers[i]);
        else
            answer=string_from_char("");
        buffer_add_ssh_string(session->out_buffer,answer);
        string_burn(answer);
        free(answer);
    }
    if(packet_send(session)){
        leave_function();
    	return SSH_AUTH_ERROR;
    }
    err = wait_auth_status(session,1);
    leave_function();
    return err;
}
Example #25
0
/**
 * @brief Disconnect from a session (client or server).
 * The session can then be reused to open a new session.
 *
 * @param[in]  session  The SSH session to use.
 */
void ssh_disconnect(ssh_session session) {
  ssh_string str = NULL;
  struct ssh_iterator *it;

  if (session == NULL) {
    return;
  }

  if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
    if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
      goto error;
    }
    if (buffer_add_u32(session->out_buffer,
          htonl(SSH2_DISCONNECT_BY_APPLICATION)) < 0) {
      goto error;
    }

    str = ssh_string_from_char("Bye Bye");
    if (str == NULL) {
      goto error;
    }

    if (buffer_add_ssh_string(session->out_buffer,str) < 0) {
      ssh_string_free(str);
      goto error;
    }
    ssh_string_free(str);

    packet_send(session);
    ssh_socket_close(session->socket);
  }
error:
  session->alive = 0;
  if (session->socket != NULL){
    ssh_socket_reset(session->socket);
  }
  session->opts.fd = SSH_INVALID_SOCKET;
  session->session_state=SSH_SESSION_STATE_DISCONNECTED;

  while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
    ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
    ssh_list_remove(session->channels, it);
  }
  if(session->current_crypto){
    crypto_free(session->current_crypto);
    session->current_crypto=NULL;
  }
  if (session->in_buffer) {
    ssh_buffer_reinit(session->in_buffer);
  }
  if (session->out_buffer) {
    ssh_buffer_reinit(session->out_buffer);
  }
  if (session->in_hashbuf) {
    ssh_buffer_reinit(session->in_hashbuf);
  }
  if (session->out_hashbuf) {
    ssh_buffer_reinit(session->out_hashbuf);
  }
  session->auth_methods = 0;
  SAFE_FREE(session->serverbanner);
  SAFE_FREE(session->clientbanner);

  if(session->ssh_message_list){
    ssh_message msg;
    while((msg=ssh_list_pop_head(ssh_message ,session->ssh_message_list))
        != NULL){
      ssh_message_free(msg);
    }
    ssh_list_free(session->ssh_message_list);
    session->ssh_message_list=NULL;
  }

  if (session->packet_callbacks){
    ssh_list_free(session->packet_callbacks);
    session->packet_callbacks=NULL;
  }
}
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;
}
Example #27
0
ssh_string ssh_agent_sign_data(ssh_session session,
                               const ssh_key pubkey,
                               struct ssh_buffer_struct *data)
{
    ssh_buffer request;
    ssh_buffer reply;
    ssh_string key_blob;
    ssh_string sig_blob;
    int type = SSH2_AGENT_FAILURE;
    int flags = 0;
    uint32_t dlen;
    int rc;

    request = ssh_buffer_new();
    if (request == NULL) {
        return NULL;
    }

    /* create request */
    if (buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) {
        return NULL;
    }

    rc = ssh_pki_export_pubkey_blob(pubkey, &key_blob);
    if (rc < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    /* adds len + blob */
    rc = buffer_add_ssh_string(request, key_blob);
    ssh_string_free(key_blob);
    if (rc < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    /* Add data */
    dlen = buffer_get_rest_len(data);
    if (buffer_add_u32(request, htonl(dlen)) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }
    if (buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    if (buffer_add_u32(request, htonl(flags)) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }

    reply = ssh_buffer_new();
    if (reply == NULL) {
        ssh_buffer_free(request);
        return NULL;
    }

    /* send the request */
    if (agent_talk(session, request, reply) < 0) {
        ssh_buffer_free(request);
        return NULL;
    }
    ssh_buffer_free(request);

    /* check if reply is valid */
    if (buffer_get_u8(reply, (uint8_t *) &type) != sizeof(uint8_t)) {
        ssh_buffer_free(reply);
        return NULL;
    }

    if (agent_failed(type)) {
        SSH_LOG(session, SSH_LOG_WARN, "Agent reports failure in signing the key");
        ssh_buffer_free(reply);
        return NULL;
    } else if (type != SSH2_AGENT_SIGN_RESPONSE) {
        ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type);
        ssh_buffer_free(reply);
        return NULL;
    }

    sig_blob = buffer_get_ssh_string(reply);
    ssh_buffer_free(reply);

    return sig_blob;
}
Example #28
0
int ssh_get_kex1(SSH_SESSION *session) {
  STRING *server_exp = NULL;
  STRING *server_mod = NULL;
  STRING *host_exp = NULL;
  STRING *host_mod = NULL;
  STRING *serverkey = NULL;
  STRING *hostkey = NULL;
  STRING *enc_session = NULL;
  PUBLIC_KEY *srv = NULL;
  PUBLIC_KEY *host = NULL;
  u32 server_bits;
  u32 host_bits;
  u32 protocol_flags;
  u32 supported_ciphers_mask;
  u32 supported_authentications_mask;
  u16 bits;
  int rc = -1;
  int ko;

  enter_function();
  ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");
  if (packet_wait(session, SSH_SMSG_PUBLIC_KEY, 1) != SSH_OK) {
    leave_function();
    return -1;
  }

  ssh_log(session, SSH_LOG_PROTOCOL, "Got a SSH_SMSG_PUBLIC_KEY");
  if (buffer_get_data(session->in_buffer, session->server_kex.cookie, 8) != 8) {
    ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer");
    leave_function();
    return -1;
  }

  buffer_get_u32(session->in_buffer, &server_bits);
  server_exp = buffer_get_mpint(session->in_buffer);
  if (server_exp == NULL) {
    goto error;
  }
  server_mod = buffer_get_mpint(session->in_buffer);
  if (server_mod == NULL) {
    goto error;
  }
  buffer_get_u32(session->in_buffer, &host_bits);
  host_exp = buffer_get_mpint(session->in_buffer);
  if (host_exp == NULL) {
    goto error;
  }
  host_mod = buffer_get_mpint(session->in_buffer);
  if (host_mod == NULL) {
    goto error;
  }
  buffer_get_u32(session->in_buffer, &protocol_flags);
  buffer_get_u32(session->in_buffer, &supported_ciphers_mask);
  ko = buffer_get_u32(session->in_buffer, &supported_authentications_mask);

  if ((ko != sizeof(u32)) || !host_mod || !host_exp
      || !server_mod || !server_exp) {
    ssh_log(session, SSH_LOG_RARE, "Invalid SSH_SMSG_PUBLIC_KEY packet");
    ssh_set_error(session, SSH_FATAL, "Invalid SSH_SMSG_PUBLIC_KEY packet");
    goto error;
  }

  server_bits = ntohl(server_bits);
  host_bits = ntohl(host_bits);
  protocol_flags = ntohl(protocol_flags);
  supported_ciphers_mask = ntohl(supported_ciphers_mask);
  supported_authentications_mask = ntohl(supported_authentications_mask);
  ssh_log(session, SSH_LOG_PROTOCOL,
      "Server bits: %d; Host bits: %d; Protocol flags: %.8lx; "
      "Cipher mask: %.8lx; Auth mask: %.8lx",
      server_bits,
      host_bits,
      (unsigned long int) protocol_flags,
      (unsigned long int) supported_ciphers_mask,
      (unsigned long int) supported_authentications_mask);

  serverkey = make_rsa1_string(server_exp, server_mod);
  if (serverkey == NULL) {
    goto error;
  }
  hostkey = make_rsa1_string(host_exp,host_mod);
  if (serverkey == NULL) {
    goto error;
  }
  if (build_session_id1(session, server_mod, host_mod) < 0) {
    goto error;
  }

  srv = publickey_from_string(session, serverkey);
  if (srv == NULL) {
    goto error;
  }
  host = publickey_from_string(session, hostkey);
  if (host == NULL) {
    goto error;
  }

  session->next_crypto->server_pubkey = string_copy(hostkey);
  if (session->next_crypto->server_pubkey == NULL) {
    goto error;
  }
  session->next_crypto->server_pubkey_type = "ssh-rsa1";

  /* now, we must choose an encryption algo */
  /* hardcode 3des */
  if (!(supported_ciphers_mask & (1 << SSH_CIPHER_3DES))) {
    ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES");
    goto error;
  }

  ssh_log(session, SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY");

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
    goto error;
  }
  if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) {
    goto error;
  }
  if (buffer_add_data(session->out_buffer, session->server_kex.cookie, 8) < 0) {
    goto error;
  }

  enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits);
  if (enc_session == NULL) {
    goto error;
  }

  bits = string_len(enc_session) * 8 - 7;
  ssh_log(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session",
      bits, string_len(enc_session));
  bits = htons(bits);
  /* the encrypted mpint */
  if (buffer_add_data(session->out_buffer, &bits, sizeof(u16)) < 0) {
    goto error;
  }
  if (buffer_add_data(session->out_buffer, enc_session->string,
        string_len(enc_session)) < 0) {
    goto error;
  }
  /* the protocol flags */
  if (buffer_add_u32(session->out_buffer, 0) < 0) {
    goto error;
  }

  if (packet_send(session) != SSH_OK) {
    goto error;
  }

  /* we can set encryption */
  if (crypt_set_algorithms(session)) {
    goto error;
  }

  session->current_crypto = session->next_crypto;
  session->next_crypto = NULL;

  ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
  if (packet_wait(session,SSH_SMSG_SUCCESS,1) != SSH_OK) {
    char buffer[1024] = {0};
    snprintf(buffer, sizeof(buffer),
        "Key exchange failed: %s", ssh_get_error(session));
    ssh_set_error(session, SSH_FATAL, "%s",buffer);
    goto error;
  }
  ssh_log(session, SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n");

  rc = 0;
error:
  string_free(host_mod);
  string_free(host_exp);
  string_free(server_mod);
  string_free(server_exp);
  string_free(serverkey);
  string_free(hostkey);

  publickey_free(srv);
  publickey_free(host);

  leave_function();
  return rc;
}
Example #29
0
int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
                            const char *instruction, unsigned int num_prompts,
                            const char **prompts, char *echo) {
  int r;
  unsigned int i = 0;
  ssh_string tmp = NULL;

  if(name == NULL || instruction == NULL) {
    return SSH_ERROR;
  }
  if(num_prompts > 0 && (prompts == NULL || echo == NULL)) {
    return SSH_ERROR;
  }

  if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_USERAUTH_INFO_REQUEST) < 0) {
    return SSH_ERROR;
  }

  /* name */
  tmp = ssh_string_from_char(name);
  if (tmp == NULL) {
      return SSH_ERROR;
  }

  r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
  ssh_string_free(tmp);
  if (r < 0) {
    return SSH_ERROR;
  }

  /* instruction */
  tmp = ssh_string_from_char(instruction);
  if (tmp == NULL) {
      return SSH_ERROR;
  }

  r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
  ssh_string_free(tmp);
  if (r < 0) {
    return SSH_ERROR;
  }

  /* language tag */
  tmp = ssh_string_from_char("");
  if (tmp == NULL) {
      return SSH_ERROR;
  }

  r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
  ssh_string_free(tmp);
  if (r < 0) {
    return SSH_ERROR;
  }

  /* num prompts */
  if (buffer_add_u32(msg->session->out_buffer, ntohl(num_prompts)) < 0) {
    return SSH_ERROR;
  }

  for(i = 0; i < num_prompts; i++) {
    /* prompt[i] */
    tmp = ssh_string_from_char(prompts[i]);
    if (tmp == NULL) {
        return SSH_ERROR;
    }

    r = buffer_add_ssh_string(msg->session->out_buffer, tmp);
    ssh_string_free(tmp);
    if (r < 0) {
        return SSH_ERROR;
    }

    /* echo[i] */
    if (buffer_add_u8(msg->session->out_buffer, echo[i]) < 0) {
        return SSH_ERROR;
    }
  }

  r = packet_send(msg->session);

  /* fill in the kbdint structure */
  if (msg->session->kbdint == NULL) {
    SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a "
                                        "keyboard-interactive response but it "
                                        "seems we didn't send the request.");

    msg->session->kbdint = ssh_kbdint_new();
    if (msg->session->kbdint == NULL) {
      ssh_set_error_oom(msg->session);

      return SSH_ERROR;
    }
  } else {
    ssh_kbdint_clean(msg->session->kbdint);
  }

  msg->session->kbdint->name = strdup(name);
  if(msg->session->kbdint->name == NULL) {
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_PACKET_USED;
  }
  msg->session->kbdint->instruction = strdup(instruction);
  if(msg->session->kbdint->instruction == NULL) {
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_PACKET_USED;
  }

  msg->session->kbdint->nprompts = num_prompts;
  if(num_prompts > 0) {
    msg->session->kbdint->prompts = malloc(num_prompts * sizeof(char *));
    if (msg->session->kbdint->prompts == NULL) {
      msg->session->kbdint->nprompts = 0;
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_ERROR;
    }
    msg->session->kbdint->echo = malloc(num_prompts * sizeof(unsigned char));
    if (msg->session->kbdint->echo == NULL) {
      ssh_set_error_oom(msg->session);
      ssh_kbdint_free(msg->session->kbdint);
      msg->session->kbdint = NULL;
      return SSH_ERROR;
    }
    for (i = 0; i < num_prompts; i++) {
      msg->session->kbdint->echo[i] = echo[i];
      msg->session->kbdint->prompts[i] = strdup(prompts[i]);
      if (msg->session->kbdint->prompts[i] == NULL) {
        ssh_set_error_oom(msg->session);
        msg->session->kbdint->nprompts = i;
        ssh_kbdint_free(msg->session->kbdint);
        msg->session->kbdint = NULL;
        return SSH_PACKET_USED;
      }
    }
  } else {
    msg->session->kbdint->prompts = NULL;
    msg->session->kbdint->echo = NULL;
  }

  return r;
}
Example #30
0
static int channel_request(CHANNEL *channel, const char *request,
    BUFFER *buffer, int reply) {
  SSH_SESSION *session = channel->session;
  STRING *req = NULL;
  int rc = SSH_ERROR;

  enter_function();

  req = string_from_char(request);
  if (req == NULL) {
    goto error;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_REQUEST) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->remote_channel)) < 0 ||
      buffer_add_ssh_string(session->out_buffer, req) < 0 ||
      buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
    goto error;
  }
  string_free(req);

  if (buffer != NULL) {
    if (buffer_add_data(session->out_buffer, buffer_get(buffer),
        buffer_get_len(buffer)) < 0) {
      goto error;
    }
  }

  if (packet_send(session) != SSH_OK) {
    leave_function();
    return rc;
  }

  ssh_log(session, SSH_LOG_RARE,
      "Sent a SSH_MSG_CHANNEL_REQUEST %s", request);
  if (reply == 0) {
    leave_function();
    return SSH_OK;
  }

  rc = packet_wait(session, SSH2_MSG_CHANNEL_SUCCESS, 1);
  if (rc) {
    if (session->in_packet.type == SSH2_MSG_CHANNEL_FAILURE) {
      ssh_log(session, SSH_LOG_PACKET,
          "%s channel request failed", request);
      ssh_set_error(session, SSH_REQUEST_DENIED,
          "Channel request %s failed", request);
    } else {
      ssh_log(session, SSH_LOG_RARE,
          "Received an unexpected %d message", session->in_packet.type);
    }
  } else {
    ssh_log(session, SSH_LOG_RARE, "Received a SUCCESS");
  }

  leave_function();
  return rc;
error:
  buffer_free(session->out_buffer);
  string_free(req);

  leave_function();
  return rc;
}