Exemple #1
0
ssh_string ssh_pki_do_sign_agent(ssh_session session,
                                 struct ssh_buffer_struct *buf,
                                 const ssh_key pubkey) {
    struct ssh_crypto_struct *crypto;
    ssh_string session_id;
    ssh_string sig_blob;
    ssh_buffer sig_buf;
    int rc;

    if (session->current_crypto) {
        crypto = session->current_crypto;
    } else {
        crypto = session->next_crypto;
    }

    /* prepend session identifier */
    session_id = ssh_string_new(crypto->digest_len);
    if (session_id == NULL) {
        return NULL;
    }
    ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);

    sig_buf = ssh_buffer_new();
    if (sig_buf == NULL) {
        ssh_string_free(session_id);
        return NULL;
    }

    rc = buffer_add_ssh_string(sig_buf, session_id);
    if (rc < 0) {
        ssh_string_free(session_id);
        ssh_buffer_free(sig_buf);
        return NULL;
    }
    ssh_string_free(session_id);

    /* append out buffer */
    if (buffer_add_buffer(sig_buf, buf) < 0) {
        ssh_buffer_free(sig_buf);
        return NULL;
    }

    /* create signature */
    sig_blob = ssh_agent_sign_data(session, pubkey, sig_buf);

    ssh_buffer_free(sig_buf);

    return sig_blob;
}
Exemple #2
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;
}
Exemple #3
0
ssh_string ssh_do_sign_with_agent(ssh_session session,
                                  struct ssh_buffer_struct *buf, struct ssh_public_key_struct *publickey) {
    struct ssh_buffer_struct *sigbuf = NULL;
    struct ssh_string_struct *signature = NULL;
    struct ssh_string_struct *session_id = NULL;
    struct ssh_crypto_struct *crypto = NULL;

    if (session->current_crypto) {
        crypto = session->current_crypto;
    } else {
        crypto = session->next_crypto;
    }

    /* prepend session identifier */
    session_id = ssh_string_new(crypto->digest_len);
    if (session_id == NULL) {
        return NULL;
    }
    ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);

    sigbuf = ssh_buffer_new();
    if (sigbuf == NULL) {
        ssh_string_free(session_id);
        return NULL;
    }

    if (buffer_add_ssh_string(sigbuf, session_id) < 0) {
        ssh_buffer_free(sigbuf);
        ssh_string_free(session_id);
        return NULL;
    }
    ssh_string_free(session_id);

    /* append out buffer */
    if (buffer_add_buffer(sigbuf, buf) < 0) {
        ssh_buffer_free(sigbuf);
        return NULL;
    }

    /* create signature */
    signature = agent_sign_data(session, sigbuf, publickey);

    ssh_buffer_free(sigbuf);

    return signature;
}
static int channel_open(CHANNEL *channel, const char *type_c, int window,
    int maxpacket, BUFFER *payload) {
  SSH_SESSION *session = channel->session;
  STRING *type = NULL;
  u32 tmp = 0;

  enter_function();

  channel->local_channel = ssh_channel_new_id(session);
  channel->local_maxpacket = maxpacket;
  channel->local_window = window;

  ssh_log(session, SSH_LOG_RARE,
      "Creating a channel %d with %d window and %d max packet",
      channel->local_channel, window, maxpacket);

  type = string_from_char(type_c);
  if (type == NULL) {
    leave_function();
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN) < 0 ||
      buffer_add_ssh_string(session->out_buffer,type) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->local_channel)) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->local_window)) < 0 ||
      buffer_add_u32(session->out_buffer, htonl(channel->local_maxpacket)) < 0) {
    string_free(type);
    leave_function();
    return -1;
  }

  string_free(type);

  if (payload != NULL) {
    if (buffer_add_buffer(session->out_buffer, payload) < 0) {
      leave_function();
      return -1;
    }
  }

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

  ssh_log(session, SSH_LOG_RARE,
      "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %d",
      type_c, channel->local_channel);

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

  switch(session->in_packet.type) {
    case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
      buffer_get_u32(session->in_buffer, &tmp);

      if (channel->local_channel != ntohl(tmp)) {
        ssh_set_error(session, SSH_FATAL,
            "Server answered with sender channel number %lu instead of given %u",
            (long unsigned int) ntohl(tmp),
            channel->local_channel);
        leave_function();
        return -1;
      }
      buffer_get_u32(session->in_buffer, &tmp);
      channel->remote_channel = ntohl(tmp);

      buffer_get_u32(session->in_buffer, &tmp);
      channel->remote_window = ntohl(tmp);

      buffer_get_u32(session->in_buffer,&tmp);
      channel->remote_maxpacket=ntohl(tmp);

      ssh_log(session, SSH_LOG_PROTOCOL,
          "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
          channel->local_channel,
          channel->remote_channel);
      ssh_log(session, SSH_LOG_PROTOCOL,
          "Remote window : %lu, maxpacket : %lu",
          (long unsigned int) channel->remote_window,
          (long unsigned int) channel->remote_maxpacket);

      channel->open = 1;
      leave_function();
      return 0;
    case SSH2_MSG_CHANNEL_OPEN_FAILURE:
      {
        STRING *error_s;
        char *error;
        u32 code;

        buffer_get_u32(session->in_buffer, &tmp);
        buffer_get_u32(session->in_buffer, &code);

        error_s = buffer_get_ssh_string(session->in_buffer);
        error = string_to_char(error_s);
        string_free(error_s);
        if (error == NULL) {
          leave_function();
          return -1;
        }

        ssh_set_error(session, SSH_REQUEST_DENIED,
            "Channel opening failure: channel %u error (%lu) %s",
            channel->local_channel,
            (long unsigned int) ntohl(code),
            error);
        SAFE_FREE(error);

        leave_function();
        return -1;
      }
    default:
      ssh_set_error(session, SSH_FATAL,
          "Received unknown packet %d\n", session->in_packet.type);
      leave_function();
      return -1;
  }

  leave_function();
  return -1;
}
/* Needs to be freed with safe_free() */
uint8_t *command_packet_to_bytes(command_packet_t *packet, size_t *length)
{
  buffer_t *buffer = buffer_create(BO_BIG_ENDIAN);
  buffer_t *buffer_with_size = buffer_create(BO_BIG_ENDIAN);
  uint16_t packed_id;

  packed_id  = (packet->is_request ? 0x0000 : 0x8000);
  packed_id |= (packet->request_id & 0x7FFF);
  buffer_add_int16(buffer, packed_id);

  buffer_add_int16(buffer, packet->command_id);

  switch(packet->command_id)
  {
    case COMMAND_PING:
      if(packet->is_request)
        buffer_add_ntstring(buffer, packet->r.request.body.ping.data);
      else
        buffer_add_ntstring(buffer, packet->r.response.body.ping.data);

      break;

    case COMMAND_SHELL:
      if(packet->is_request)
        buffer_add_ntstring(buffer, packet->r.request.body.shell.name);
      else
        buffer_add_int16(buffer, packet->r.response.body.shell.session_id);
      break;

    case COMMAND_EXEC:
      if(packet->is_request)
      {
        buffer_add_ntstring(buffer, packet->r.request.body.exec.name);
        buffer_add_ntstring(buffer, packet->r.request.body.exec.command);
      }
      else
      {
        buffer_add_int16(buffer, packet->r.response.body.exec.session_id);
      }
      break;

    case COMMAND_DOWNLOAD:
      if(packet->is_request)
      {
        buffer_add_ntstring(buffer, packet->r.request.body.download.filename);
      }
      else
      {
        buffer_add_bytes(buffer, packet->r.response.body.download.data, packet->r.response.body.download.length);
      }
      break;

    case COMMAND_UPLOAD:
      if(packet->is_request)
      {
        buffer_add_ntstring(buffer, packet->r.request.body.upload.filename);
        buffer_add_bytes(buffer, packet->r.request.body.upload.data, packet->r.request.body.upload.length);
      }
      else
      {
      }
      break;

    case COMMAND_SHUTDOWN:
      break;

    case TUNNEL_CONNECT:
      if(packet->is_request)
      {
        buffer_add_int32(buffer, packet->r.request.body.tunnel_connect.options);
        buffer_add_ntstring(buffer, packet->r.request.body.tunnel_connect.host);
        buffer_add_int16(buffer, packet->r.request.body.tunnel_connect.port);
      }
      else
      {
        buffer_add_int32(buffer, packet->r.response.body.tunnel_connect.tunnel_id);
      }
      break;

    case TUNNEL_DATA:
      if(packet->is_request)
      {
        buffer_add_int32(buffer, packet->r.request.body.tunnel_data.tunnel_id);
        buffer_add_bytes(buffer, packet->r.request.body.tunnel_data.data, packet->r.request.body.tunnel_data.length);
      }
      else
      {
      }
      break;

    case TUNNEL_CLOSE:
      if(packet->is_request)
      {
        buffer_add_int32(buffer, packet->r.request.body.tunnel_close.tunnel_id);
        buffer_add_ntstring(buffer, packet->r.request.body.tunnel_close.reason);
      }
      else
      {
      }
      break;

    case COMMAND_ERROR:
      if(packet->is_request)
      {
        buffer_add_int16(buffer, packet->r.request.body.error.status);
        buffer_add_ntstring(buffer, packet->r.request.body.error.reason);
      }
      else
      {
        buffer_add_int16(buffer, packet->r.response.body.error.status);
        buffer_add_ntstring(buffer, packet->r.response.body.error.reason);
      }
      break;


    default:
      LOG_FATAL("Unknown command_id: 0x%04x", packet->command_id);
      exit(1);
  }

  buffer_add_int32(buffer_with_size, buffer_get_length(buffer));
  buffer_add_buffer(buffer_with_size, buffer);
  buffer_destroy(buffer);

  return buffer_create_string_and_destroy(buffer_with_size, length);
}