예제 #1
0
파일: socket.c 프로젝트: codinn/libssh
/**
 * \internal
 * \brief creates a new Socket object
 */
ssh_socket ssh_socket_new(ssh_session session) {
  ssh_socket s;

  s = malloc(sizeof(struct ssh_socket_struct));
  if (s == NULL) {
    ssh_set_error_oom(session);
    return NULL;
  }
  s->fd_in = SSH_INVALID_SOCKET;
  s->fd_out= SSH_INVALID_SOCKET;
  s->last_errno = -1;
  s->fd_is_socket = 1;
  s->session = session;
  s->in_buffer = ssh_buffer_new();
  if (s->in_buffer == NULL) {
    ssh_set_error_oom(session);
    SAFE_FREE(s);
    return NULL;
  }
  s->out_buffer=ssh_buffer_new();
  if (s->out_buffer == NULL) {
    ssh_set_error_oom(session);
    ssh_buffer_free(s->in_buffer);
    SAFE_FREE(s);
    return NULL;
  }
  s->read_wontblock = 0;
  s->write_wontblock = 0;
  s->data_except = 0;
  s->poll_in=s->poll_out=NULL;
  s->state=SSH_SOCKET_NONE;
  return s;
}
예제 #2
0
파일: gssapi.c 프로젝트: Distrotech/libssh
static ssh_buffer ssh_gssapi_build_mic(ssh_session session){
    ssh_buffer mic_buffer;
    int rc;

    mic_buffer = ssh_buffer_new();
    if (mic_buffer == NULL) {
        ssh_set_error_oom(session);
        return NULL;
    }

    rc = ssh_buffer_pack(mic_buffer,
                         "dPbsss",
                         session->current_crypto->digest_len,
                         (size_t)session->current_crypto->digest_len, session->current_crypto->session_id,
                         SSH2_MSG_USERAUTH_REQUEST,
                         session->gssapi->user,
                         "ssh-connection",
                         "gssapi-with-mic");
    if (rc != SSH_OK) {
        ssh_set_error_oom(session);
        ssh_buffer_free(mic_buffer);
        return NULL;
    }

    return mic_buffer;
}
예제 #3
0
static int crypt_set_algorithms1(ssh_session session) {
  int i = 0;
  struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();

  /* right now, we force 3des-cbc to be taken */
  while (ssh_ciphertab[i].name && strcmp(ssh_ciphertab[i].name,
        "3des-cbc-ssh1")) {
    i++;
  }

  if (ssh_ciphertab[i].name == NULL) {
    ssh_set_error(session, SSH_FATAL, "cipher 3des-cbc-ssh1 not found!");
    return SSH_ERROR;
  }

  session->next_crypto->out_cipher = cipher_new(i);
  if (session->next_crypto->out_cipher == NULL) {
    ssh_set_error_oom(session);
    return SSH_ERROR;
  }

  session->next_crypto->in_cipher = cipher_new(i);
  if (session->next_crypto->in_cipher == NULL) {
    ssh_set_error_oom(session);
    return SSH_ERROR;
  }

  return SSH_OK;
}
예제 #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;
}
예제 #5
0
파일: kex.c 프로젝트: simonsj/libssh
/**
 * @brief sets the key exchange parameters to be sent to the server,
 *        in function of the options and available methods.
 */
int ssh_set_client_kex(ssh_session session)
{
    struct ssh_kex_struct *client= &session->next_crypto->client_kex;
    const char *wanted;
    char *kex = NULL;
    char *kex_tmp = NULL;
    int ok;
    int i;
    size_t kex_len, len;

    ok = ssh_get_random(client->cookie, 16, 0);
    if (!ok) {
        ssh_set_error(session, SSH_FATAL, "PRNG error");
        return SSH_ERROR;
    }

    memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **));
    /* first check if we have specific host key methods */
    if (session->opts.wanted_methods[SSH_HOSTKEYS] == NULL) {
    	/* Only if no override */
    	session->opts.wanted_methods[SSH_HOSTKEYS] =
            ssh_client_select_hostkeys(session);
    }

    for (i = 0; i < KEX_METHODS_SIZE; i++) {
        wanted = session->opts.wanted_methods[i];
        if (wanted == NULL)
            wanted = default_methods[i];
        client->methods[i] = strdup(wanted);
        if (client->methods[i] == NULL) {
            ssh_set_error_oom(session);
            return SSH_ERROR;
        }
    }

    /* For rekeying, skip the extension negotiation */
    if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) {
        return SSH_OK;
    }

    /* Here we append  ext-info-c  to the list of kex algorithms */
    kex = client->methods[SSH_KEX];
    len = strlen(kex);
    if (len + strlen(KEX_EXTENSION_CLIENT) + 2 < len) {
        /* Overflow */
        return SSH_ERROR;
    }
    kex_len = len + strlen(KEX_EXTENSION_CLIENT) + 2; /* comma, NULL */
    kex_tmp = realloc(kex, kex_len);
    if (kex_tmp == NULL) {
        free(kex);
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }
    snprintf(kex_tmp + len, kex_len - len, ",%s", KEX_EXTENSION_CLIENT);
    client->methods[SSH_KEX] = kex_tmp;

    return SSH_OK;
}
예제 #6
0
int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
    int i;

    if (session == NULL){
        ssh_set_error(sshbind, SSH_FATAL,"session is null");
        return SSH_ERROR;
    }

    session->server = 1;
    session->version = 2;

    /* copy options */
    for (i = 0; i < 10; ++i) {
      if (sshbind->wanted_methods[i]) {
        session->wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
        if (session->wanted_methods[i] == NULL) {
          return SSH_ERROR;
        }
      }
    }

    if (sshbind->bindaddr == NULL)
      session->bindaddr = NULL;
    else {
      SAFE_FREE(session->bindaddr);
      session->bindaddr = strdup(sshbind->bindaddr);
      if (session->bindaddr == NULL) {
        return SSH_ERROR;
      }
    }

    session->common.log_verbosity = sshbind->common.log_verbosity;

    ssh_socket_free(session->socket);
    session->socket = ssh_socket_new(session);
    if (session->socket == NULL) {
      /* perhaps it may be better to copy the error from session to sshbind */
      ssh_set_error_oom(sshbind);
      return SSH_ERROR;
    }
    ssh_socket_set_fd(session->socket, fd);
    ssh_socket_get_poll_handle_out(session->socket);

    if (sshbind->dsa) {
        session->srv.dsa_key = ssh_key_dup(sshbind->dsa);
        if (session->srv.dsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    if (sshbind->rsa) {
        session->srv.rsa_key = ssh_key_dup(sshbind->rsa);
        if (session->srv.rsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    return SSH_OK;
}
예제 #7
0
파일: server.c 프로젝트: alejom200/tmate
int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_port) {
    int rc;

    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) {
            rc = ssh_buffer_pack(msg->session->out_buffer, "d", bound_port);
            if (rc != SSH_ERROR) {
                ssh_set_error_oom(msg->session);
                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;
}
예제 #8
0
파일: kex1.c 프로젝트: caidongyun/libssh
static int build_session_id1(ssh_session session, ssh_string servern,
    ssh_string hostn) {
  MD5CTX md5 = NULL;

  md5 = md5_init();
  if (md5 == NULL) {
    return -1;
  }

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("host modulus",ssh_string_data(hostn),ssh_string_len(hostn));
  ssh_print_hexa("server modulus",ssh_string_data(servern),ssh_string_len(servern));
#endif
  md5_update(md5,ssh_string_data(hostn),ssh_string_len(hostn));
  md5_update(md5,ssh_string_data(servern),ssh_string_len(servern));
  md5_update(md5,session->next_crypto->server_kex.cookie,8);
  if(session->next_crypto->session_id != NULL)
      SAFE_FREE(session->next_crypto->session_id);
  session->next_crypto->session_id = malloc(MD5_DIGEST_LEN);
  if(session->next_crypto->session_id == NULL){
      ssh_set_error_oom(session);
      return SSH_ERROR;
  }
  md5_final(session->next_crypto->session_id,md5);
#ifdef DEBUG_CRYPTO
  ssh_print_hexa("session_id",session->next_crypto->session_id,MD5_DIGEST_LEN);
#endif

  return 0;
}
예제 #9
0
파일: callbacks.c 프로젝트: cedral/libssh
static int ssh_add_set_channel_callbacks(ssh_channel channel,
                                         ssh_channel_callbacks cb,
                                         int prepend)
{
    ssh_session session = NULL;
    int rc;

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

    if (is_callback_valid(session, cb)) {
        ssh_set_error(session,
                      SSH_FATAL,
                      "Invalid callback passed in (badly initialized)");
        return SSH_ERROR;
    };
    if (channel->callbacks == NULL) {
        channel->callbacks = ssh_list_new();
        if (channel->callbacks == NULL){
            ssh_set_error_oom(session);
            return SSH_ERROR;
        }
    }
    if (prepend) {
        rc = ssh_list_prepend(channel->callbacks, cb);
    } else {
        rc = ssh_list_append(channel->callbacks, cb);
    }

    return rc;
}
예제 #10
0
파일: gssapi.c 프로젝트: Distrotech/libssh
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
    int rc;
    int i;

    rc = ssh_buffer_pack(session->out_buffer,
                         "bsssd",
                         SSH2_MSG_USERAUTH_REQUEST,
                         session->opts.username,
                         "ssh-connection",
                         "gssapi-with-mic",
                         n_oid);

    if (rc != SSH_OK) {
        ssh_set_error_oom(session);
        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:
    ssh_buffer_reinit(session->out_buffer);
    return SSH_ERROR;
}
예제 #11
0
파일: server.c 프로젝트: alejom200/tmate
static int ssh_message_channel_request_reply_default(ssh_message msg) {
  uint32_t channel;
  int rc;

  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);

    rc = ssh_buffer_pack(msg->session->out_buffer,
                         "bd",
                         SSH2_MSG_CHANNEL_FAILURE,
                         channel);
    if (rc != SSH_OK){
        ssh_set_error_oom(msg->session);
        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;
}
예제 #12
0
파일: server.c 프로젝트: alejom200/tmate
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;
}
예제 #13
0
파일: gssapi.c 프로젝트: alexislitool/tmate
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);
}
예제 #14
0
파일: pcap.c 프로젝트: AsylumCorp/dsploit
ssh_pcap_context ssh_pcap_context_new(ssh_session session){
	ssh_pcap_context ctx = (struct ssh_pcap_context_struct *) malloc(sizeof(struct ssh_pcap_context_struct));
	if(ctx==NULL){
		ssh_set_error_oom(session);
		return NULL;
	}
	ZERO_STRUCTP(ctx);
	ctx->session=session;
	return ctx;
}
예제 #15
0
파일: socket.c 프로젝트: codinn/libssh
/** \internal
 * \brief buffered write of data
 * \returns SSH_OK, or SSH_ERROR
 * \warning has no effect on socket before a flush
 */
int ssh_socket_write(ssh_socket s, const void *buffer, int len) {
  if(len > 0) {
    if (ssh_buffer_add_data(s->out_buffer, buffer, len) < 0) {
      ssh_set_error_oom(s->session);
      return SSH_ERROR;
    }
    ssh_socket_nonblocking_flush(s);
  }

  return SSH_OK;
}
예제 #16
0
파일: gssapi.c 프로젝트: Distrotech/libssh
/** @internal
 * @brief sends a SSH_MSG_USERAUTH_GSSAPI_RESPONSE packet
 * @param[in] oid the OID that was selected for authentication
 */
static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){
    if (buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) < 0 ||
            buffer_add_ssh_string(session->out_buffer,oid) < 0) {
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }

    packet_send(session);
    SSH_LOG(SSH_LOG_PACKET,
            "Sent SSH_MSG_USERAUTH_GSSAPI_RESPONSE");
    return SSH_OK;
}
예제 #17
0
파일: pcap.c 프로젝트: AsylumCorp/dsploit
/** @brief sets the pcap file used to trace the session
 * @param current session
 * @param pcap an handler to a pcap file. A pcap file may be used in several
 * sessions.
 * @returns SSH_ERROR in case of error, SSH_OK otherwise.
 */
int ssh_set_pcap_file(ssh_session session, ssh_pcap_file pcap){
	ssh_pcap_context ctx=ssh_pcap_context_new(session);
	if(ctx==NULL){
		ssh_set_error_oom(session);
		return SSH_ERROR;
	}
	ctx->file=pcap;
	if(session->pcap_ctx)
		ssh_pcap_context_free(session->pcap_ctx);
	session->pcap_ctx=ctx;
	return SSH_OK;
}
예제 #18
0
파일: server.c 프로젝트: simonsj/libssh
int ssh_get_key_params(ssh_session session, ssh_key *privkey){
    ssh_key pubkey;
    ssh_string pubkey_blob;
    int rc;

    switch(session->srv.hostkey) {
      case SSH_KEYTYPE_DSS:
        *privkey = session->srv.dsa_key;
        break;
      case SSH_KEYTYPE_RSA:
        *privkey = session->srv.rsa_key;
        break;
      case SSH_KEYTYPE_ECDSA_P256:
      case SSH_KEYTYPE_ECDSA_P384:
      case SSH_KEYTYPE_ECDSA_P521:
        *privkey = session->srv.ecdsa_key;
        break;
      case SSH_KEYTYPE_ED25519:
        *privkey = session->srv.ed25519_key;
        break;
      case SSH_KEYTYPE_RSA1:
      case SSH_KEYTYPE_UNKNOWN:
      default:
        *privkey = NULL;
    }

    rc = ssh_pki_export_privkey_to_pubkey(*privkey, &pubkey);
    if (rc < 0) {
      ssh_set_error(session, SSH_FATAL,
          "Could not get the public key from the private key");

      return -1;
    }

    rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob);
    ssh_key_free(pubkey);
    if (rc < 0) {
      ssh_set_error_oom(session);
      return -1;
    }

    rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
    ssh_string_free(pubkey_blob);
    if (rc != 0) {
        ssh_set_error(session,
                      SSH_FATAL,
                      "Could not import server public key");
        return -1;
    }

    return SSH_OK;
}
예제 #19
0
파일: server.c 프로젝트: alejom200/tmate
/** @internal
 * replies to an SSH_AUTH packet with a default (denied) response.
 */
int ssh_auth_reply_default(ssh_session session,int partial) {
  char methods_c[128] = {0};
  int rc = SSH_ERROR;


  if (session->auth_methods == 0) {
    session->auth_methods = SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_PASSWORD;
  }
  if (session->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
    strncat(methods_c, "publickey,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC){
	  strncat(methods_c,"gssapi-with-mic,",
			  sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
    strncat(methods_c, "keyboard-interactive,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_PASSWORD) {
    strncat(methods_c, "password,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }
  if (session->auth_methods & SSH_AUTH_METHOD_HOSTBASED) {
    strncat(methods_c, "hostbased,",
            sizeof(methods_c) - strlen(methods_c) - 1);
  }

  if (methods_c[0] == '\0' || methods_c[strlen(methods_c)-1] != ',') {
      return SSH_ERROR;
  }

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

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

  rc = ssh_buffer_pack(session->out_buffer,
                       "bsb",
                       SSH2_MSG_USERAUTH_FAILURE,
                       methods_c,
                       partial ? 1 : 0);
  if (rc != SSH_OK){
      ssh_set_error_oom(session);
      return SSH_ERROR;
  }
  rc = packet_send(session);
  return rc;
}
예제 #20
0
파일: gssapi.c 프로젝트: Distrotech/libssh
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(SSH_LOG_PROTOCOL, "generating MIC", maj_stat);
        return SSH_ERROR;
    }

    rc = ssh_buffer_pack(session->out_buffer,
                         "bdP",
                         SSH2_MSG_USERAUTH_GSSAPI_MIC,
                         mic_token_buf.length,
                         (size_t)mic_token_buf.length, mic_token_buf.value);
    if (rc != SSH_OK) {
        ssh_buffer_free(mic_buffer);
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }

    return packet_send(session);
}
예제 #21
0
/** @internal
 * @initializes a gssapi context for authentication
 */
static int ssh_gssapi_init(ssh_session session){
    if (session->gssapi != NULL)
        return SSH_OK;
    session->gssapi = malloc(sizeof(struct ssh_gssapi_struct));
    if(!session->gssapi){
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }
    ZERO_STRUCTP(session->gssapi);
    session->gssapi->server_creds = GSS_C_NO_CREDENTIAL;
    session->gssapi->client_creds = GSS_C_NO_CREDENTIAL;
    session->gssapi->ctx = GSS_C_NO_CONTEXT;
    session->gssapi->state = SSH_GSSAPI_STATE_NONE;
    return SSH_OK;
}
예제 #22
0
파일: packet.c 프로젝트: Paxxi/libssh
/** @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 rc;

    rc = ssh_buffer_pack(session->out_buffer,
                         "bd",
                         SSH2_MSG_UNIMPLEMENTED,
                         seqnum);
    if (rc != SSH_OK) {
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }
    rc = ssh_packet_send(session);

    return rc;
}
예제 #23
0
파일: client.c 프로젝트: kedazo/libssh
/**
 * @internal
 *
 * @brief Request a service from the SSH server.
 *
 * Service requests are for example: ssh-userauth, ssh-connection, etc.
 *
 * @param  session      The session to use to ask for a service request.
 * @param  service      The service request.
 *
 * @return SSH_OK on success
 * @return SSH_ERROR on error
 * @return SSH_AGAIN No response received yet
 * @bug actually only works with ssh-userauth
 */
int ssh_service_request(ssh_session session, const char *service) {
  int rc=SSH_ERROR;

  if(session->auth_service_state != SSH_AUTH_SERVICE_NONE)
    goto pending;

  rc = ssh_buffer_pack(session->out_buffer,
                       "bs",
                       SSH2_MSG_SERVICE_REQUEST,
                       service);
  if (rc != SSH_OK){
      ssh_set_error_oom(session);
      return SSH_ERROR;
  }
  session->auth_service_state=SSH_AUTH_SERVICE_SENT;
  if (ssh_packet_send(session) == SSH_ERROR) {
    ssh_set_error(session, SSH_FATAL,
        "Sending SSH2_MSG_SERVICE_REQUEST failed.");
      return SSH_ERROR;
  }

  SSH_LOG(SSH_LOG_PACKET,
      "Sent SSH_MSG_SERVICE_REQUEST (service %s)", service);
pending:
  rc=ssh_handle_packets_termination(session,SSH_TIMEOUT_USER,
      ssh_service_request_termination, session);
  if (rc == SSH_ERROR) {
      return SSH_ERROR;
  }
  switch(session->auth_service_state){
  case SSH_AUTH_SERVICE_DENIED:
    ssh_set_error(session,SSH_FATAL,"ssh_auth_service request denied");
    break;
  case SSH_AUTH_SERVICE_ACCEPTED:
    rc=SSH_OK;
    break;
  case SSH_AUTH_SERVICE_SENT:
    rc=SSH_AGAIN;
    break;
  case SSH_AUTH_SERVICE_NONE:
  case SSH_AUTH_SERVICE_USER_SENT:
    /* Invalid state, SSH1 specific */
    rc=SSH_ERROR;
    break;
  }

  return rc;
}
예제 #24
0
파일: server.c 프로젝트: alejom200/tmate
/* Answer OK to a pubkey auth request */
int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pubkey) {
    int rc;
    if (msg == NULL) {
        return SSH_ERROR;
    }

    rc = ssh_buffer_pack(msg->session->out_buffer,
                         "bSS",
                         SSH2_MSG_USERAUTH_PK_OK,
                         algo,
                         pubkey);
    if(rc != SSH_OK){
        ssh_set_error_oom(msg->session);
        return SSH_ERROR;
    }

    rc = packet_send(msg->session);
    return rc;
}
예제 #25
0
파일: server.c 프로젝트: alejom200/tmate
static int ssh_message_channel_request_open_reply_default(ssh_message msg) {
    int rc;

    SSH_LOG(SSH_LOG_FUNCTIONS, "Refusing a channel");

    rc = ssh_buffer_pack(msg->session->out_buffer,
                         "bdddd",
                         SSH2_MSG_CHANNEL_OPEN_FAILURE,
                         msg->channel_request_open.sender,
                         SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
                         0,    /* reason is empty string */
                         0);   /* language string */
    if (rc != SSH_OK){
        ssh_set_error_oom(msg->session);
        return SSH_ERROR;
    }

    rc = packet_send(msg->session);
    return rc;
}
예제 #26
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;
}
예제 #27
0
파일: server.c 프로젝트: alejom200/tmate
int ssh_message_service_reply_success(ssh_message msg) {
    ssh_session session;
    int rc;

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

    SSH_LOG(SSH_LOG_PACKET,
            "Sending a SERVICE_ACCEPT for service %s", msg->service_request.service);

    rc = ssh_buffer_pack(session->out_buffer,
                         "bs",
                         SSH2_MSG_SERVICE_ACCEPT,
                         msg->service_request.service);
    if (rc != SSH_OK){
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }
    rc = packet_send(msg->session);
    return rc;
}
예제 #28
0
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;
}
예제 #29
0
파일: bind.c 프로젝트: Alexey-T/SynFTP
int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
    int i, rc;

    if (session == NULL){
        ssh_set_error(sshbind, SSH_FATAL,"session is null");
        return SSH_ERROR;
    }

    session->server = 1;
    session->version = 2;

    /* copy options */
    for (i = 0; i < 10; i++) {
      if (sshbind->wanted_methods[i]) {
        session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
        if (session->opts.wanted_methods[i] == NULL) {
          return SSH_ERROR;
        }
      }
    }

    if (sshbind->bindaddr == NULL)
      session->opts.bindaddr = NULL;
    else {
      SAFE_FREE(session->opts.bindaddr);
      session->opts.bindaddr = strdup(sshbind->bindaddr);
      if (session->opts.bindaddr == NULL) {
        return SSH_ERROR;
      }
    }

    session->common.log_verbosity = sshbind->common.log_verbosity;
    if(sshbind->banner != NULL)
    	session->opts.custombanner = strdup(sshbind->banner);
    ssh_socket_free(session->socket);
    session->socket = ssh_socket_new(session);
    if (session->socket == NULL) {
      /* perhaps it may be better to copy the error from session to sshbind */
      ssh_set_error_oom(sshbind);
      return SSH_ERROR;
    }
    ssh_socket_set_fd(session->socket, fd);
    ssh_socket_get_poll_handle_out(session->socket);

    /* We must try to import any keys that could be imported in case
     * we are not using ssh_bind_listen (which is the other place
     * where keys can be imported) on this ssh_bind and are instead
     * only using ssh_bind_accept_fd to manage sockets ourselves.
     */
    rc = ssh_bind_import_keys(sshbind);
    if (rc != SSH_OK) {
      return SSH_ERROR;
    }

#ifdef HAVE_ECC
    if (sshbind->ecdsa) {
        session->srv.ecdsa_key = ssh_key_dup(sshbind->ecdsa);
        if (session->srv.ecdsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
#endif
    if (sshbind->dsa) {
        session->srv.dsa_key = ssh_key_dup(sshbind->dsa);
        if (session->srv.dsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    if (sshbind->rsa) {
        session->srv.rsa_key = ssh_key_dup(sshbind->rsa);
        if (session->srv.rsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    if (sshbind->ed25519 != NULL) {
        session->srv.ed25519_key = ssh_key_dup(sshbind->ed25519);
        if (session->srv.ed25519_key == NULL){
            ssh_set_error_oom(sshbind);
            return SSH_ERROR;
        }
    }

    /* force PRNG to change state in case we fork after ssh_bind_accept */
    ssh_reseed();
    return SSH_OK;
}
예제 #30
0
파일: server.c 프로젝트: alejom200/tmate
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 rc;
  unsigned int i = 0;

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

  rc = ssh_buffer_pack(msg->session->out_buffer,
                       "bsssd",
                       SSH2_MSG_USERAUTH_INFO_REQUEST,
                       name,
                       instruction,
                       "",           /* language tag */
                       num_prompts);
  if (rc != SSH_OK){
    ssh_set_error_oom(msg->session);
    return SSH_ERROR;
  }

  for(i = 0; i < num_prompts; i++) {
    rc = ssh_buffer_pack(msg->session->out_buffer,
                         "sb",
                         prompts[i],
                         echo[1] ? 1 : 0);
    if (rc != SSH_OK){
        ssh_set_error_oom(msg->session);
        return SSH_ERROR;
    }
  }

  rc = 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 rc;
}