Example #1
0
/** @internal
 * @brief dispatch the call of packet handlers callbacks for a received packet
 * @param type type of packet
 */
void ssh_packet_process(ssh_session session, uint8_t type){
	struct ssh_iterator *i;
	int r=SSH_PACKET_NOT_USED;
	ssh_packet_callbacks cb;
	enter_function();
	ssh_log(session,SSH_LOG_PACKET, "Dispatching handler for packet type %d",type);
	if(session->packet_callbacks == NULL){
		ssh_log(session,SSH_LOG_RARE,"Packet callback is not initialized !");
		goto error;
	}
	i=ssh_list_get_iterator(session->packet_callbacks);
	while(i != NULL){
		cb=ssh_iterator_value(ssh_packet_callbacks,i);
		i=i->next;
		if(!cb)
			continue;
		if(cb->start > type)
			continue;
		if(cb->start + cb->n_callbacks <= type)
			continue;
		if(cb->callbacks[type - cb->start]==NULL)
			continue;
		r=cb->callbacks[type - cb->start](session,type,session->in_buffer,cb->user);
		if(r==SSH_PACKET_USED)
			break;
	}
	if(r==SSH_PACKET_NOT_USED){
		ssh_log(session,SSH_LOG_RARE,"Couldn't do anything with packet type %d",type);
		ssh_packet_send_unimplemented(session, session->recv_seq-1);
	}
error:
	leave_function();
}
Example #2
0
int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_port) {
    ssh_log(msg->session, 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(msg->session, SSH_LOG_PACKET,
                "The client doesn't want to know the remote port!");
    }

    return SSH_OK;
error:
    return SSH_ERROR;
}
Example #3
0
static void channel_rcv_change_window(SSH_SESSION *session) {
  CHANNEL *channel;
  u32 bytes;
  int rc;

  enter_function();

  channel = channel_from_msg(session);
  if (channel == NULL) {
    ssh_log(session, SSH_LOG_FUNCTIONS, ssh_get_error(session));
  }

  rc = buffer_get_u32(session->in_buffer, &bytes);
  if (channel == NULL || rc != sizeof(u32)) {
    ssh_log(session, SSH_LOG_PACKET,
        "Error getting a window adjust message: invalid packet");
    leave_function();
    return;
  }

  bytes = ntohl(bytes);
  ssh_log(session, SSH_LOG_PROTOCOL,
      "Adding %d bytes to channel (%d:%d) (from %d bytes)",
      bytes,
      channel->local_channel,
      channel->remote_channel,
      channel->remote_window);

  channel->remote_window += bytes;

  leave_function();
}
Example #4
0
/*
 * channel_handle() is called by packet_wait(), for example when there is
 * channel informations to handle.
 */
void channel_handle(SSH_SESSION *session, int type){
  enter_function();

  ssh_log(session, SSH_LOG_PROTOCOL, "Channel_handle(%d)", type);

  switch(type) {
    case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
      channel_rcv_change_window(session);
      break;
    case SSH2_MSG_CHANNEL_DATA:
      channel_rcv_data(session,0);
      break;
    case SSH2_MSG_CHANNEL_EXTENDED_DATA:
      channel_rcv_data(session,1);
      break;
    case SSH2_MSG_CHANNEL_EOF:
      channel_rcv_eof(session);
      break;
    case SSH2_MSG_CHANNEL_CLOSE:
      channel_rcv_close(session);
      break;
    case SSH2_MSG_CHANNEL_REQUEST:
      channel_rcv_request(session);
      break;
    default:
      ssh_log(session, SSH_LOG_FUNCTIONS,
          "Unexpected message %d", type);
  }

  leave_function();
}
Example #5
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(msg->session, 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(msg->session, SSH_LOG_PACKET,
      "The client doesn't want to know the request succeeded");

  return SSH_OK;
}
Example #6
0
int ssh_message_auth_reply_success(ssh_message msg, int partial) {
  int r;

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

  if (partial) {
    return ssh_message_auth_reply_default(msg, partial);
  }

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

  r = packet_send(msg->session);
  if(msg->session->current_crypto && msg->session->current_crypto->delayed_compress_out){
  	ssh_log(msg->session,SSH_LOG_PROTOCOL,"Enabling delayed compression OUT");
  	msg->session->current_crypto->do_compress_out=1;
  }
  if(msg->session->current_crypto && msg->session->current_crypto->delayed_compress_in){
  	ssh_log(msg->session,SSH_LOG_PROTOCOL,"Enabling delayed compression IN");
  	msg->session->current_crypto->do_compress_in=1;
  }
  return r;
}
Example #7
0
static int crypt_set_algorithms2(SSH_SESSION *session){
  const char *wanted;
  int i = 0;

  /* we must scan the kex entries to find crypto algorithms and set their appropriate structure */
  /* out */
  wanted = session->client_kex.methods[SSH_CRYPT_C_S];
  while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
    i++;
  }

  if (ssh_ciphertab[i].name == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Crypt_set_algorithms2: no crypto algorithm function found for %s",
        wanted);
    return SSH_ERROR;
  }
  ssh_log(session, SSH_LOG_PACKET, "Set output algorithm to %s", wanted);

  session->next_crypto->out_cipher = cipher_new(i);
  if (session->next_crypto->out_cipher == NULL) {
    ssh_set_error(session, SSH_FATAL, "No space left");
    return SSH_ERROR;
  }
  i = 0;

  /* in */
  wanted = session->client_kex.methods[SSH_CRYPT_S_C];
  while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
    i++;
  }

  if (ssh_ciphertab[i].name == NULL) {
    ssh_set_error(session, SSH_FATAL,
        "Crypt_set_algorithms: no crypto algorithm function found for %s",
        wanted);
    return SSH_ERROR;
  }
  ssh_log(session, SSH_LOG_PACKET, "Set input algorithm to %s", wanted);

  session->next_crypto->in_cipher = cipher_new(i);
  if (session->next_crypto->in_cipher == NULL) {
    ssh_set_error(session, SSH_FATAL, "Not enough space");
    return SSH_ERROR;
  }

  /* compression */
  if (strstr(session->client_kex.methods[SSH_COMP_C_S], "zlib")) {
    session->next_crypto->do_compress_out = 1;
  }
  if (strstr(session->client_kex.methods[SSH_COMP_S_C], "zlib")) {
    session->next_crypto->do_compress_in = 1;
  }

  return SSH_OK;
}
Example #8
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;
}
Example #9
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;
}
Example #10
0
void ssh_list_kex(ssh_session session, KEX *kex) {
  int i = 0;

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("session cookie", kex->cookie, 16);
#endif
  if(kex->methods==NULL){
    ssh_log(session, SSH_LOG_RARE,"kex->methods is NULL");
    return;
  }
  for(i = 0; i < 10; i++) {
    ssh_log(session, SSH_LOG_FUNCTIONS, "%s: %s",
        ssh_kex_nums[i], kex->methods[i]);
  }
}
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;

}
Example #12
0
int packet_decrypt(SSH_SESSION *session, void *data,u32 len) {
  struct crypto_struct *crypto = session->current_crypto->in_cipher;
  char *out = NULL;

  out = malloc(len);
  if (out == NULL) {
    return -1;
  }

  ssh_log(session,SSH_LOG_PACKET, "Decrypting %d bytes", len);

#ifdef HAVE_LIBGCRYPT
  if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey,
        session->current_crypto->decryptIV) < 0) {
    SAFE_FREE(out);
    return -1;
  }
  crypto->cbc_decrypt(crypto,data,out,len);
#elif defined HAVE_LIBCRYPTO
  if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey) < 0) {
    SAFE_FREE(out);
    return -1;
  }
  crypto->cbc_decrypt(crypto,data,out,len,session->current_crypto->decryptIV);
#endif

  memcpy(data,out,len);
  memset(out,0,len);

  SAFE_FREE(out);
  return 0;
}
Example #13
0
static int grow_window(SSH_SESSION *session, CHANNEL *channel, int minimumsize) {
  u32 new_window = minimumsize > WINDOWBASE ? minimumsize : WINDOWBASE;

  enter_function();

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

  if (packet_send(session) != SSH_OK) {
    /* FIXME should we fail here or not? */
    leave_function();
    return 1;
  }

  ssh_log(session, SSH_LOG_PROTOCOL,
      "growing window (channel %d:%d) to %d bytes",
      channel->local_channel,
      channel->remote_channel,
      channel->local_window + new_window);

  channel->local_window += new_window;

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

  leave_function();
  return -1;
}
Example #14
0
static STRING *encrypt_session_key(SSH_SESSION *session, PUBLIC_KEY *srvkey,
    PUBLIC_KEY *hostkey, int slen, int hlen) {
  unsigned char buffer[32] = {0};
  int i;
  STRING *data1 = NULL;
  STRING *data2 = NULL;

  /* first, generate a session key */
  ssh_get_random(session->next_crypto->encryptkey, 32, 1);
  memcpy(buffer, session->next_crypto->encryptkey, 32);
  memcpy(session->next_crypto->decryptkey, session->next_crypto->encryptkey, 32);

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("session key",buffer,32);
#endif

  /* xor session key with session_id */
  for (i = 0; i < 16; i++) {
    buffer[i] ^= session->next_crypto->session_id[i];
  }
  data1 = string_new(32);
  if (data1 == NULL) {
    return NULL;
  }
  string_fill(data1, buffer, 32);
  if (ABS(hlen - slen) < 128){
    ssh_log(session, SSH_LOG_FUNCTIONS,
        "Difference between server modulus and host modulus is only %d. "
        "It's illegal and may not work",
        ABS(hlen - slen));
  }

  if (modulus_smaller(srvkey, hostkey)) {
    data2 = ssh_encrypt_rsa1(session, data1, srvkey);
    string_free(data1);
    data1 = NULL;
    if (data2 == NULL) {
      return NULL;
    }
    data1 = ssh_encrypt_rsa1(session, data2, hostkey);
    string_free(data2);
    if (data1 == NULL) {
      return NULL;
    }
  } else {
    data2 = ssh_encrypt_rsa1(session, data1, hostkey);
    string_free(data1);
    data1 = NULL;
    if (data2 == NULL) {
      return NULL;
    }
    data1 = ssh_encrypt_rsa1(session, data2, srvkey);
    string_free(data2);
    if (data1 == NULL) {
      return NULL;
    }
  }

  return data1;
}
Example #15
0
/** @brief waits for a response of the scp server
 * @internal
 * @param response pointer where the response message must be
 * copied if any. This pointer must then be free'd.
 * @returns the return code.
 * @returns SSH_ERROR a error occured
 */
int ssh_scp_response(ssh_scp scp, char **response){
	unsigned char code;
	int r;
	char msg[128];
	r=channel_read(scp->channel,&code,1,0);
	if(r == SSH_ERROR)
		return SSH_ERROR;
	if(code == 0)
		return 0;
	if(code > 2){
		ssh_set_error(scp->session,SSH_FATAL, "SCP: invalid status code %ud received", code);
		scp->state=SSH_SCP_ERROR;
		return SSH_ERROR;
	}
	r=ssh_scp_read_string(scp,msg,sizeof(msg));
	if(r==SSH_ERROR)
		return r;
	/* Warning */
	if(code == 1){
		ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Warning: status code 1 received: %s", msg);
		ssh_log(scp->session,SSH_LOG_RARE,"SCP: Warning: status code 1 received: %s", msg);
		if(response)
			*response=strdup(msg);
		return 1;
	}
	if(code == 2){
		ssh_set_error(scp->session,SSH_FATAL, "SCP: Error: status code 2 received: %s", msg);
		if(response)
			*response=strdup(msg);
		return 2;
	}
	/* Not reached */
	return SSH_ERROR;
}
Example #16
0
/** \internal
 * \brief writes len bytes from buffer to socket
 */
static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer,
    uint32_t len) {
  int w = -1;

  if (s->data_except) {
    return -1;
  }
  if (s->fd_is_socket)
    w = send(s->fd_out,buffer, len, 0);
  else
    w = write(s->fd_out, buffer, len);
#ifdef _WIN32
  s->last_errno = WSAGetLastError();
#else
  s->last_errno = errno;
#endif
  s->write_wontblock = 0;
  /* Reactive the POLLOUT detector in the poll multiplexer system */
  if(s->poll_out){
  	ssh_log(s->session, SSH_LOG_PACKET, "Enabling POLLOUT for socket");
  	ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT);
  }
  if (w < 0) {
    s->data_except = 1;
  }

  return w;
}
Example #17
0
/**
 * @brief Send an end of file on the channel.
 *
 * This doesn't close the channel. You may still read from it but not write.
 *
 * @param channel       The channel to send the eof to.
 *
 * @return SSH_SUCCESS on success\n
 *         SSH_ERROR on error\n
 *
 * @see channel_close()
 * @see channel_free()
 */
int channel_send_eof(CHANNEL *channel){
  SSH_SESSION *session = channel->session;
  int rc = SSH_ERROR;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_EOF) < 0) {
    goto error;
  }
  if (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 EOF on client channel (%d:%d)",
      channel->local_channel,
      channel->remote_channel);

  channel->local_eof = 1;

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

  leave_function();
  return rc;
}
Example #18
0
File: keys.c Project: rofl0r/libssh
void signature_free(SIGNATURE *sign) {
    if (sign == NULL) {
        return;
    }

    switch(sign->type) {
    case SSH_KEYTYPE_DSS:
#ifdef HAVE_LIBGCRYPT
        gcry_sexp_release(sign->dsa_sign);
#elif defined HAVE_LIBCRYPTO
        DSA_SIG_free(sign->dsa_sign);
#endif
        break;
    case SSH_KEYTYPE_RSA:
    case SSH_KEYTYPE_RSA1:
#ifdef HAVE_LIBGCRYPT
        gcry_sexp_release(sign->rsa_sign);
#elif defined HAVE_LIBCRYPTO
        SAFE_FREE(sign->rsa_sign);
#endif
        break;
    default:
        /* FIXME Passing NULL segfaults */
#if 0
        ssh_log(NULL, SSH_LOG_RARE, "Freeing a signature with no type!\n");
        */
#endif
        break;
    }
    SAFE_FREE(sign);
}
Example #19
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;
}
Example #20
0
static int pem_get_password(char *buf, int size, int rwflag, void *userdata) {
    ssh_session session = userdata;

    (void) rwflag; /* unused */

    if (buf == NULL) {
        return 0;
    }

    ssh_log(session, SSH_LOG_RARE,
            "Trying to call external authentication function");

    memset(buf, '\0', size);
    if (session &&
        session->common.callbacks &&
        session->common.callbacks->auth_function) {
        int rc;

        rc = session->common.callbacks->auth_function("Passphrase for private key:",
                                                      buf, size, 0, 0,
                                                      session->common.callbacks->userdata);
        if (rc == 0) {
            return strlen(buf);
        }
    }

    return 0;
}
int channel_request_exec1(ssh_channel channel, const char *cmd) {
  ssh_session session;
  ssh_string command = NULL;

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

  command = ssh_string_from_char(cmd);
  if (command == NULL) {
    return -1;
  }

  if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0 ||
      buffer_add_ssh_string(session->out_buffer, command) < 0) {
    ssh_string_free(command);
    return -1;
  }
  ssh_string_free(command);

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

  ssh_log(session, SSH_LOG_RARE, "Executing %s ...", cmd);

  return 0;
}
Example #22
0
/** @brief initializes the sending of a file to a scp in sink mode
 * @param scp the scp handle.
 * @param filename Name of the file being sent. It should not contain any path indicator
 * @param size Exact size in bytes of the file being sent.
 * @param mode Unix permissions for the new file, e.g. 0644
 * @returns SSH_OK if the file is ready to be sent.
 * @returns SSH_ERROR if an error happened.
 */
int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){
  char buffer[1024];
  int r;
  uint8_t code;
  char *file;
  char *perms;
  if(scp->state != SSH_SCP_WRITE_INITED){
    ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_file called under invalid state");
    return SSH_ERROR;
  }
  file=ssh_basename(filename);
  perms=ssh_scp_string_mode(mode);
  ssh_log(scp->session,SSH_LOG_PROTOCOL,"SCP pushing file %s, size %" PRIdS " with permissions '%s'",file,size,perms);
  snprintf(buffer, sizeof(buffer), "C%s %" PRIdS " %s\n", perms, size, file);
  SAFE_FREE(file);
  SAFE_FREE(perms);
  r=channel_write(scp->channel,buffer,strlen(buffer));
  if(r==SSH_ERROR){
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  r=channel_read(scp->channel,&code,1,0);
  if(code != 0){
    ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
    scp->state=SSH_SCP_ERROR;
    return SSH_ERROR;
  }
  scp->filelen = size;
  scp->processed = 0;
  scp->state=SSH_SCP_WRITE_WRITING;
  return SSH_OK;
}
Example #23
0
int ssh_message_reply_default(ssh_message msg) {
  if (msg == NULL) {
    return -1;
  }

  switch(msg->type) {
    case SSH_REQUEST_AUTH:
      return ssh_message_auth_reply_default(msg, 0);
    case SSH_REQUEST_CHANNEL_OPEN:
      return ssh_message_channel_request_open_reply_default(msg);
    case SSH_REQUEST_CHANNEL:
      return ssh_message_channel_request_reply_default(msg);
    case SSH_REQUEST_SERVICE:
      return ssh_message_service_request_reply_default(msg);
    case SSH_REQUEST_GLOBAL:
      return ssh_message_global_request_reply_default(msg);
    default:
      ssh_log(msg->session, SSH_LOG_PACKET,
          "Don't know what to default reply to %d type",
          msg->type);
      break;
  }

  return -1;
}
Example #24
0
File: pki.c Project: rofl0r/libssh
/** @brief import a base64 formated key from a memory c-string
 *
 * @param   key     The key to fill, created with ssh_key_new()
 * @param   session The ssh session
 * @param   b64_key The c-string holding the base64 encoded key
 * @param   passphrase  The passphrase to decrypt the key, or NULL
 *
 * @return  SSH_ERROR in case of error, SSH_OK otherwise
 */
int ssh_pki_import_privkey_base64(ssh_session session,
                                  const char *b64_key,
                                  const char *passphrase,
                                  ssh_key *pkey) {
    ssh_key key;

    if (pkey == NULL || session == NULL) {
        return SSH_ERROR;
    }

    if (b64_key == NULL || !*b64_key) {
        return SSH_ERROR;
    }

    ssh_log(session, SSH_LOG_RARE, "Trying to decode privkey passphrase=%s",
            passphrase ? "true" : "false");

    key = pki_private_key_from_base64(session, b64_key, passphrase);
    if (key == NULL) {
        return SSH_ERROR;
    }

    *pkey = key;

    return SSH_OK;
}
Example #25
0
int ssh_message_service_reply_success(ssh_message msg) {
  struct ssh_string_struct *service;
  ssh_session session;

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

  ssh_log(session, SSH_LOG_PACKET,
      "Sending a SERVICE_ACCEPT for service %s", msg->service_request.service);
  if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_ACCEPT) < 0) {
    return -1;
  }
  service=ssh_string_from_char(msg->service_request.service);
  if (service == NULL) {
      return -1;
  }

  if (buffer_add_ssh_string(session->out_buffer, service) < 0) {
    ssh_string_free(service);
    return -1;
  }
  ssh_string_free(service);
  return packet_send(msg->session);
}
Example #26
0
static int ssh_message_channel_request_open_reply_default(ssh_message msg) {
  ssh_log(msg->session, SSH_LOG_FUNCTIONS, "Refusing a channel");

  if (buffer_add_u8(msg->session->out_buffer
        , SSH2_MSG_CHANNEL_OPEN_FAILURE) < 0) {
    goto error;
  }
  if (buffer_add_u32(msg->session->out_buffer,
        htonl(msg->channel_request_open.sender)) < 0) {
    goto error;
  }
  if (buffer_add_u32(msg->session->out_buffer,
        htonl(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) < 0) {
    goto error;
  }
  /* reason is an empty string */
  if (buffer_add_u32(msg->session->out_buffer, 0) < 0) {
    goto error;
  }
  /* language too */
  if (buffer_add_u32(msg->session->out_buffer, 0) < 0) {
    goto error;
  }

  return packet_send(msg->session);
error:
  return SSH_ERROR;
}
int channel_open_session1(ssh_channel chan) {
  ssh_session session;

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

  /*
   * We guess we are requesting an *exec* channel. It can only have one exec
   * channel. So we abort with an error if we need more than one.
   */
  if (session->exec_channel_opened) {
    ssh_set_error(session, SSH_REQUEST_DENIED,
        "SSH1 supports only one execution channel. "
        "One has already been opened");
    return -1;
  }
  session->exec_channel_opened = 1;
  chan->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED;
  chan->state = SSH_CHANNEL_STATE_OPEN;
  chan->local_maxpacket = 32000;
  chan->local_window = 64000;
  ssh_log(session, SSH_LOG_PACKET, "Opened a SSH1 channel session");

  return 0;
}
Example #28
0
int packet_decrypt(ssh_session session, void *data,uint32_t len) {
  struct crypto_struct *crypto = session->current_crypto->in_cipher;
  char *out = NULL;
  if(len % session->current_crypto->in_cipher->blocksize != 0){
    ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
    return SSH_ERROR;
  }
  out = malloc(len);
  if (out == NULL) {
    return -1;
  }

  ssh_log(session,SSH_LOG_PACKET, "Decrypting %d bytes", len);

#ifdef HAVE_LIBGCRYPT
  if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey,
        session->current_crypto->decryptIV) < 0) {
    SAFE_FREE(out);
    return -1;
  }
  crypto->cbc_decrypt(crypto,data,out,len);
#elif defined HAVE_LIBCRYPTO
  if (crypto->set_decrypt_key(crypto, session->current_crypto->decryptkey) < 0) {
    SAFE_FREE(out);
    return -1;
  }
  crypto->cbc_decrypt(crypto,data,out,len,session->current_crypto->decryptIV);
#endif

  memcpy(data,out,len);
  memset(out,0,len);

  SAFE_FREE(out);
  return 0;
}
Example #29
0
File: main.c Project: Paxxi/libssh
SSH_SESSION *connect_host(const char *hostname){
  SSH_SESSION *session;
  SSH_OPTIONS *options;
  int auth=0;
  int state;

  options=ssh_options_new();
  ssh_options_set_host(options,hostname);
  session=ssh_new();
  ssh_set_options(session,options);
  if(ssh_connect(session)){
    fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
    ssh_disconnect(session);
    return NULL;
  }

  state = ssh_session_is_known_server(session);
  switch(state){
    case SSH_SERVER_KNOWN_OK:
      break; /* ok */
    case SSH_SERVER_KNOWN_CHANGED:
      fprintf(stderr,"Host key for server changed : server's one is now :\n");
      fprintf(stderr,"For security reason, connection will be stopped\n");
      ssh_disconnect(session);
      ssh_finalize();
      return NULL;
    case SSH_SERVER_FOUND_OTHER:
      fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
      fprintf(stderr,"An attacker might change the default server key to confuse your client"
          "into thinking the key does not exist\n"
          "We advise you to rerun the client with -d or -r for more safety.\n");
      ssh_disconnect(session);
      ssh_finalize();
      return NULL;
    case SSH_SERVER_NOT_KNOWN:
      fprintf(stderr,"The server is unknown. Leaving now");
      ssh_disconnect(session);
      return NULL;
    case SSH_SERVER_ERROR:
      fprintf(stderr,"%s",ssh_get_error(session));
      ssh_disconnect(session);
      return NULL;
  }

  ssh_userauth_none(session, NULL);

  auth=ssh_userauth_autopubkey(session, NULL);
  if(auth==SSH_AUTH_ERROR){
    fprintf(stderr,"Authenticating with pubkey: %s\n",ssh_get_error(session));
    ssh_disconnect(session);
    return NULL;
  }
  if(auth!=SSH_AUTH_SUCCESS){
    fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
    ssh_disconnect(session);
    return NULL;
  }
  ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
  return session;
}
Example #30
0
static int ssh_message_auth_reply_default(ssh_message msg,int partial) {
  ssh_session session = msg->session;
  char methods_c[128] = {0};
  ssh_string methods = NULL;
  int rc = SSH_ERROR;

  enter_function();

  if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_FAILURE) < 0) {
    return rc;
  }

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

  /* Strip the comma. */
  methods_c[strlen(methods_c) - 1] = '\0'; // strip the comma. We are sure there is at

  ssh_log(session, SSH_LOG_PACKET,
      "Sending a auth failure. methods that can continue: %s", methods_c);

  methods = ssh_string_from_char(methods_c);
  if (methods == NULL) {
    goto error;
  }

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

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

  rc = packet_send(msg->session);
error:
  ssh_string_free(methods);

  leave_function();
  return rc;
}