Ejemplo n.º 1
0
int ssh_auth_reply_success(ssh_session session, int partial) {
  int r;

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

  if (partial) {
    return ssh_auth_reply_default(session, partial);
  }
  
  session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
  session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;

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

  r = packet_send(session);
  if(session->current_crypto && session->current_crypto->delayed_compress_out){
      SSH_LOG(SSH_LOG_PROTOCOL,"Enabling delayed compression OUT");
  	session->current_crypto->do_compress_out=1;
  }
  if(session->current_crypto && session->current_crypto->delayed_compress_in){
      SSH_LOG(SSH_LOG_PROTOCOL,"Enabling delayed compression IN");
  	session->current_crypto->do_compress_in=1;
  }
  return r;
}
Ejemplo n.º 2
0
int ssh_message_reply_default(ssh_message msg) {
  if (msg == NULL) {
    return -1;
  }

  switch(msg->type) {
    case SSH_REQUEST_AUTH:
      return ssh_auth_reply_default(msg->session, 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(SSH_LOG_PACKET,
          "Don't know what to default reply to %d type",
          msg->type);
      break;
  }

  return -1;
}
Ejemplo n.º 3
0
int ssh_auth_reply_success(ssh_session session, int partial)
{
    struct ssh_crypto_struct *crypto = NULL;
    int r;

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

    if (partial) {
        return ssh_auth_reply_default(session, partial);
    }

    r = ssh_buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_SUCCESS);
    if (r < 0) {
        return SSH_ERROR;
    }

    r = ssh_packet_send(session);

    /*
     * Consider the session as having been authenticated only after sending
     * the USERAUTH_SUCCESS message.  Setting these flags after ssh_packet_send
     * ensures that a rekey is not triggered prematurely, causing the message
     * to be queued.
     */
    session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
    session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;

    crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
    if (crypto != NULL && crypto->delayed_compress_out) {
        SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression OUT");
        crypto->do_compress_out = 1;
    }

    crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
    if (crypto != NULL && crypto->delayed_compress_in) {
        SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression IN");
        crypto->do_compress_in = 1;
    }
    return r;
}
Ejemplo n.º 4
0
/** @internal
 * @brief handles an user authentication using GSSAPI
 */
int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids){
    char service_name[]="host";
    gss_buffer_desc name_buf;
    gss_name_t server_name; /* local server fqdn */
    OM_uint32 maj_stat, min_stat;
    unsigned int i;
    char *ptr;
    gss_OID_set supported; /* oids supported by server */
    gss_OID_set both_supported; /* oids supported by both client and server */
    gss_OID_set selected; /* oid selected for authentication */
    int present=0;
    int oid_count=0;
    struct gss_OID_desc_struct oid;
    int rc;

    if (ssh_callbacks_exists(session->server_callbacks, gssapi_select_oid_function)){
        ssh_string oid_s = session->server_callbacks->gssapi_select_oid_function(session,
                user, n_oid, oids,
                session->server_callbacks->userdata);
        if (oid_s != NULL){
            if (ssh_gssapi_init(session) == SSH_ERROR)
                return SSH_ERROR;
            session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN;
            rc = ssh_gssapi_send_response(session, oid_s);
            ssh_string_free(oid_s);
            return rc;
        } else {
            return ssh_auth_reply_default(session,0);
        }
    }
    gss_create_empty_oid_set(&min_stat, &both_supported);

    maj_stat = gss_indicate_mechs(&min_stat, &supported);
    for (i=0; i < supported->count; ++i){
        ptr = ssh_get_hexa(supported->elements[i].elements, supported->elements[i].length);
        SSH_LOG(SSH_LOG_DEBUG, "Supported mech %d: %s\n", i, ptr);
        free(ptr);
    }

    for (i=0 ; i< n_oid ; ++i){
        unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]);
        size_t len = ssh_string_len(oids[i]);
        if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){
            SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID");
            continue;
        }
        oid.elements = &oid_s[2];
        oid.length = len - 2;
        gss_test_oid_set_member(&min_stat,&oid,supported,&present);
        if(present){
            gss_add_oid_set_member(&min_stat,&oid,&both_supported);
            oid_count++;
        }
    }
    gss_release_oid_set(&min_stat, &supported);
    if (oid_count == 0){
        SSH_LOG(SSH_LOG_PROTOCOL,"GSSAPI: no OID match");
        ssh_auth_reply_default(session, 0);
        gss_release_oid_set(&min_stat, &both_supported);
        return SSH_OK;
    }
    /* from now we have room for context */
    if (ssh_gssapi_init(session) == SSH_ERROR)
        return SSH_ERROR;

    name_buf.value = service_name;
    name_buf.length = strlen(name_buf.value) + 1;
    maj_stat = gss_import_name(&min_stat, &name_buf,
            (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
    if (maj_stat != GSS_S_COMPLETE) {
        SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
        ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat);
        return -1;
    }

    maj_stat = gss_acquire_cred(&min_stat, server_name, 0,
            both_supported, GSS_C_ACCEPT,
            &session->gssapi->server_creds, &selected, NULL);
    gss_release_name(&min_stat, &server_name);
    gss_release_oid_set(&min_stat, &both_supported);

    if (maj_stat != GSS_S_COMPLETE) {
        SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat);
        ssh_gssapi_log_error(SSH_LOG_WARNING, "acquiring creds", maj_stat);
        ssh_auth_reply_default(session,0);
        return SSH_ERROR;
    }

    SSH_LOG(SSH_LOG_PROTOCOL, "acquiring credentials %d, %d", maj_stat, min_stat);

    /* finding which OID from client we selected */
    for (i=0 ; i< n_oid ; ++i){
        unsigned char *oid_s = (unsigned char *) ssh_string_data(oids[i]);
        size_t len = ssh_string_len(oids[i]);
        if(len < 2 || oid_s[0] != SSH_OID_TAG || ((size_t)oid_s[1]) != len - 2){
            SSH_LOG(SSH_LOG_WARNING,"GSSAPI: received invalid OID");
            continue;
        }
        oid.elements = &oid_s[2];
        oid.length = len - 2;
        gss_test_oid_set_member(&min_stat,&oid,selected,&present);
        if(present){
            SSH_LOG(SSH_LOG_PACKET, "Selected oid %d", i);
            break;
        }
    }
    session->gssapi->mech.length = oid.length;
    session->gssapi->mech.elements = malloc(oid.length);
    if (session->gssapi->mech.elements == NULL){
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }
    memcpy(session->gssapi->mech.elements, oid.elements, oid.length);
    gss_release_oid_set(&min_stat, &selected);
    session->gssapi->user = strdup(user);
    session->gssapi->service = service_name;
    session->gssapi->state = SSH_GSSAPI_STATE_RCV_TOKEN;
    return ssh_gssapi_send_response(session, oids[i]);
}