/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* policy.c  Bus security policy
 *
 * Copyright (C) 2003, 2004  Red Hat, Inc.
 *
 * Licensed under the Academic Free License version 2.1
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "policy.h"
#include "services.h"
#include "test.h"
#include "utils.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include <dbus/dbus-internals.h>

BusPolicyRule*
bus_policy_rule_new (BusPolicyRuleType type,
                     dbus_bool_t       allow)
{
  BusPolicyRule *rule;

  rule = dbus_new0 (BusPolicyRule, 1);
  if (rule == NULL)
    return NULL;

  rule->type = type;
  rule->refcount = 1;
  rule->allow = allow;

  switch (rule->type)
    {
    case BUS_POLICY_RULE_USER:
      rule->d.user.uid = DBUS_UID_UNSET;
      break;
    case BUS_POLICY_RULE_GROUP:
      rule->d.group.gid = DBUS_GID_UNSET;
      break;
    case BUS_POLICY_RULE_SEND:
      rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;

      /* allow rules default to TRUE (only requested replies allowed)
       * deny rules default to FALSE (only unrequested replies denied)
       */
      rule->d.send.requested_reply = rule->allow;
      break;
    case BUS_POLICY_RULE_RECEIVE:
      rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
      /* allow rules default to TRUE (only requested replies allowed)
       * deny rules default to FALSE (only unrequested replies denied)
       */
      rule->d.receive.requested_reply = rule->allow;
      break;
    case BUS_POLICY_RULE_OWN:
      break;
    }
  
  return rule;
}

BusPolicyRule *
bus_policy_rule_ref (BusPolicyRule *rule)
{
  _dbus_assert (rule->refcount > 0);

  rule->refcount += 1;

  return rule;
}

void
bus_policy_rule_unref (BusPolicyRule *rule)
{
  _dbus_assert (rule->refcount > 0);

  rule->refcount -= 1;
  
  if (rule->refcount == 0)
    {
      switch (rule->type)
        {
        case BUS_POLICY_RULE_SEND:
          dbus_free (rule->d.send.path);
          dbus_free (rule->d.send.interface);
          dbus_free (rule->d.send.member);
          dbus_free (rule->d.send.error);
          dbus_free (rule->d.send.destination);
          break;
        case BUS_POLICY_RULE_RECEIVE:
          dbus_free (rule->d.receive.path);
          dbus_free (rule->d.receive.interface);
          dbus_free (rule->d.receive.member);
          dbus_free (rule->d.receive.error);
          dbus_free (rule->d.receive.origin);
          break;
        case BUS_POLICY_RULE_OWN:
          dbus_free (rule->d.own.service_name);
          break;
        case BUS_POLICY_RULE_USER:
          break;
        case BUS_POLICY_RULE_GROUP:
          break;
        }
      
      dbus_free (rule);
    }
}

struct BusPolicy
{
  int refcount;

  DBusList *default_rules;         /**< Default policy rules */
  DBusList *mandatory_rules;       /**< Mandatory policy rules */
  DBusHashTable *rules_by_uid;     /**< per-UID policy rules */
  DBusHashTable *rules_by_gid;     /**< per-GID policy rules */
  DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/
  DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/
};

static void
free_rule_func (void *data,
                void *user_data)
{
  BusPolicyRule *rule = data;

  bus_policy_rule_unref (rule);
}

static void
free_rule_list_func (void *data)
{
  DBusList **list = data;

  if (list == NULL) /* DBusHashTable is on crack */
    return;
  
  _dbus_list_foreach (list, free_rule_func, NULL);
  
  _dbus_list_clear (list);

  dbus_free (list);
}

BusPolicy*
bus_policy_new (void)
{
  BusPolicy *policy;

  policy = dbus_new0 (BusPolicy, 1);
  if (policy == NULL)
    return NULL;

  policy->refcount = 1;
  
  policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
                                               NULL,
                                               free_rule_list_func);
  if (policy->rules_by_uid == NULL)
    goto failed;

  policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
                                               NULL,
                                               free_rule_list_func);
  if (policy->rules_by_gid == NULL)
    goto failed;

  return policy;
  
 failed:
  bus_policy_unref (policy);
  return NULL;
}

BusPolicy *
bus_policy_ref (BusPolicy *policy)
{
  _dbus_assert (policy->refcount > 0);

  policy->refcount += 1;

  return policy;
}

void
bus_policy_unref (BusPolicy *policy)
{
  _dbus_assert (policy->refcount > 0);

  policy->refcount -= 1;

  if (policy->refcount == 0)
    {
      _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
      _dbus_list_clear (&policy->default_rules);

      _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
      _dbus_list_clear (&policy->mandatory_rules);

      _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL);
      _dbus_list_clear (&policy->at_console_true_rules);

      _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL);
      _dbus_list_clear (&policy->at_console_false_rules);

      if (policy->rules_by_uid)
        {
          _dbus_hash_table_unref (policy->rules_by_uid);
          policy->rules_by_uid = NULL;
        }

      if (policy->rules_by_gid)
        {
          _dbus_hash_table_unref (policy->rules_by_gid);
          policy->rules_by_gid = NULL;
        }
      
      dbus_free (policy);
    }
}

static dbus_bool_t
add_list_to_client (DBusList        **list,
                    BusClientPolicy  *client)
{
  DBusList *link;

  link = _dbus_list_get_first_link (list);
  while (link != NULL)
    {
      BusPolicyRule *rule = link->data;
      link = _dbus_list_get_next_link (list, link);

      switch (rule->type)
        {
        case BUS_POLICY_RULE_USER:
        case BUS_POLICY_RULE_GROUP:
          /* These aren't per-connection policies */
          break;

        case BUS_POLICY_RULE_OWN:
        case BUS_POLICY_RULE_SEND:
        case BUS_POLICY_RULE_RECEIVE:
          /* These are per-connection */
          if (!bus_client_policy_append_rule (client, rule))
            return FALSE;
          break;
        }
    }
  
  return TRUE;
}

BusClientPolicy*
bus_policy_create_client_policy (BusPolicy      *policy,
                                 DBusConnection *connection,
                                 DBusError      *error)
{
  BusClientPolicy *client;
  dbus_uid_t uid;
  dbus_bool_t at_console;

  _dbus_assert (dbus_connection_get_is_authenticated (connection));
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  client = bus_client_policy_new ();
  if (client == NULL)
    goto nomem;

  if (!add_list_to_client (&policy->default_rules,
                           client))
    goto nomem;

  /* we avoid the overhead of looking up user's groups
   * if we don't have any group rules anyway
   */
  if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
    {
      unsigned long *groups;
      int n_groups;
      int i;
      
      if (!bus_connection_get_unix_groups (connection, &groups, &n_groups, error))
        goto failed;
      
      i = 0;
      while (i < n_groups)
        {
          DBusList **list;
          
          list = _dbus_hash_table_lookup_uintptr (policy->rules_by_gid,
                                                groups[i]);
          
          if (list != NULL)
            {
              if (!add_list_to_client (list, client))
                {
                  dbus_free (groups);
                  goto nomem;
                }
            }
          
          ++i;
        }

      dbus_free (groups);
    }
  
  if (dbus_connection_get_unix_user (connection, &uid))
    {
      if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
        {
          DBusList **list;
          
          list = _dbus_hash_table_lookup_uintptr (policy->rules_by_uid,
                                                uid);
          
          if (list != NULL)
            {
              if (!add_list_to_client (list, client))
                goto nomem;
            }
        }

      /* Add console rules */
      at_console = _dbus_unix_user_is_at_console (uid, error);
      
      if (at_console)
        {
          if (!add_list_to_client (&policy->at_console_true_rules, client))
            goto nomem;
        }
      else if (dbus_error_is_set (error) == TRUE)
        {
          goto failed;
        }
      else if (!add_list_to_client (&policy->at_console_false_rules, client))
        {
          goto nomem;
        }
    }

  if (!add_list_to_client (&policy->mandatory_rules,
                           client))
    goto nomem;

  bus_client_policy_optimize (client);
  
  return client;

 nomem:
  BUS_SET_OOM (error);
 failed:
  _DBUS_ASSERT_ERROR_IS_SET (error);
  if (client)
    bus_client_policy_unref (client);
  return NULL;
}

static dbus_bool_t
list_allows_user (dbus_bool_t           def,
                  DBusList            **list,
                  unsigned long         uid,
                  const unsigned long  *group_ids,
                  int                   n_group_ids)
{
  DBusList *link;
  dbus_bool_t allowed;
  
  allowed = def;

  link = _dbus_list_get_first_link (list);
  while (link != NULL)
    {
      BusPolicyRule *rule = link->data;
      link = _dbus_list_get_next_link (list, link);

      if (rule->type == BUS_POLICY_RULE_USER)
        {
          _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
                         list, rule->d.user.uid);
          
          if (rule->d.user.uid == DBUS_UID_UNSET)
            ; /* '*' wildcard */
          else if (rule->d.user.uid != uid)
            continue;
        }
      else if (rule->type == BUS_POLICY_RULE_GROUP)
        {
          _dbus_verbose ("List %p group rule gid="DBUS_GID_FORMAT"\n",
                         list, rule->d.group.gid);
          
          if (rule->d.group.gid == DBUS_GID_UNSET)
            ;  /* '*' wildcard */
          else
            {
              int i;
              
              i = 0;
              while (i < n_group_ids)
                {
                  if (rule->d.group.gid == group_ids[i])
                    break;
                  ++i;
                }
              
              if (i == n_group_ids)
                continue;
            }
        }
      else
        continue;

      allowed = rule->allow;
    }
  
  return allowed;
}

dbus_bool_t
bus_policy_allow_unix_user (BusPolicy        *policy,
                            unsigned long     uid)
{
  dbus_bool_t allowed;
  unsigned long *group_ids;
  int n_group_ids;

  /* On OOM or error we always reject the user */
  if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids))
    {
      _dbus_verbose ("Did not get any groups for UID %lu\n",
                     uid);
      return FALSE;
    }

  /* Default to "user owning bus" can connect */
  allowed = _dbus_unix_user_is_process_owner (uid);

  allowed = list_allows_user (allowed,
                              &policy->default_rules,
                              uid,
                              group_ids, n_group_ids);

  allowed = list_allows_user (allowed,
                              &policy->mandatory_rules,
                              uid,
                              group_ids, n_group_ids);

  dbus_free (group_ids);

  _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
  
  return allowed;
}

/* For now this is never actually called because the default
 * DBusConnection behavior of 'same user that owns the bus can
 * connect' is all it would do. Set the windows user function in
 * connection.c if the config file ever supports doing something
 * interesting here.
 */
dbus_bool_t
bus_policy_allow_windows_user (BusPolicy        *policy,
                               const char       *windows_sid)
{
  /* Windows has no policies here since only the session bus
   * is really used for now, so just checking that the
   * connecting person is the same as the bus owner is fine.
   */
  return _dbus_windows_user_is_process_owner (windows_sid);
}

dbus_bool_t
bus_policy_append_default_rule (BusPolicy      *policy,
                                BusPolicyRule  *rule)
{
  if (!_dbus_list_append (&policy->default_rules, rule))
    return FALSE;

  bus_policy_rule_ref (rule);

  return TRUE;
}

dbus_bool_t
bus_policy_append_mandatory_rule (BusPolicy      *policy,
                                  BusPolicyRule  *rule)
{
  if (!_dbus_list_append (&policy->mandatory_rules, rule))
    return FALSE;

  bus_policy_rule_ref (rule);

  return TRUE;
}



static DBusList**
get_list (DBusHashTable *hash,
          unsigned long  key)
{
  DBusList **list;

  list = _dbus_hash_table_lookup_uintptr (hash, key);

  if (list == NULL)
    {
      list = dbus_new0 (DBusList*, 1);
      if (list == NULL)
        return NULL;

      if (!_dbus_hash_table_insert_uintptr (hash, key, list))
        {
          dbus_free (list);
          return NULL;
        }
    }

  return list;
}

dbus_bool_t
bus_policy_append_user_rule (BusPolicy      *policy,
                             dbus_uid_t      uid,
                             BusPolicyRule  *rule)
{
  DBusList **list;

  list = get_list (policy->rules_by_uid, uid);

  if (list == NULL)
    return FALSE;

  if (!_dbus_list_append (list, rule))
    return FALSE;

  bus_policy_rule_ref (rule);

  return TRUE;
}

dbus_bool_t
bus_policy_append_group_rule (BusPolicy      *policy,
                              dbus_gid_t      gid,
                              BusPolicyRule  *rule)
{
  DBusList **list;

  list = get_list (policy->rules_by_gid, gid);

  if (list == NULL)
    return FALSE;

  if (!_dbus_list_append (list, rule))
    return FALSE;

  bus_policy_rule_ref (rule);

  return TRUE;
}

dbus_bool_t
bus_policy_append_console_rule (BusPolicy      *policy,
                                dbus_bool_t     at_console,
                                BusPolicyRule  *rule)
{
  if (at_console)
    {
      if (!_dbus_list_append (&policy->at_console_true_rules, rule))
        return FALSE;
    }
    else
    {
      if (!_dbus_list_append (&policy->at_console_false_rules, rule))
        return FALSE;
    }

  bus_policy_rule_ref (rule);

  return TRUE;

}

static dbus_bool_t
append_copy_of_policy_list (DBusList **list,
                            DBusList **to_append)
{
  DBusList *link;
  DBusList *tmp_list;

  tmp_list = NULL;

  /* Preallocate all our links */
  link = _dbus_list_get_first_link (to_append);
  while (link != NULL)
    {
      if (!_dbus_list_append (&tmp_list, link->data))
        {
          _dbus_list_clear (&tmp_list);
          return FALSE;
        }
      
      link = _dbus_list_get_next_link (to_append, link);
    }

  /* Now append them */
  while ((link = _dbus_list_pop_first_link (&tmp_list)))
    {
      bus_policy_rule_ref (link->data);
      _dbus_list_append_link (list, link);
    }

  return TRUE;
}

static dbus_bool_t
merge_id_hash (DBusHashTable *dest,
               DBusHashTable *to_absorb)
{
  DBusHashIter iter;
  
  _dbus_hash_iter_init (to_absorb, &iter);
  while (_dbus_hash_iter_next (&iter))
    {
      unsigned long id = _dbus_hash_iter_get_uintptr_key (&iter);
      DBusList **list = _dbus_hash_iter_get_value (&iter);
      DBusList **target = get_list (dest, id);

      if (target == NULL)
        return FALSE;

      if (!append_copy_of_policy_list (target, list))
        return FALSE;
    }

  return TRUE;
}

dbus_bool_t
bus_policy_merge (BusPolicy *policy,
                  BusPolicy *to_absorb)
{
  /* FIXME Not properly atomic, but as used for configuration files we
   * don't rely on it quite so much.
   */
  
  if (!append_copy_of_policy_list (&policy->default_rules,
                                   &to_absorb->default_rules))
    return FALSE;
  
  if (!append_copy_of_policy_list (&policy->mandatory_rules,
                                   &to_absorb->mandatory_rules))
    return FALSE;

  if (!append_copy_of_policy_list (&policy->at_console_true_rules,
                                   &to_absorb->at_console_true_rules))
    return FALSE;

  if (!append_copy_of_policy_list (&policy->at_console_false_rules,
                                   &to_absorb->at_console_false_rules))
    return FALSE;

  if (!merge_id_hash (policy->rules_by_uid,
                      to_absorb->rules_by_uid))
    return FALSE;
  
  if (!merge_id_hash (policy->rules_by_gid,
                      to_absorb->rules_by_gid))
    return FALSE;

  return TRUE;
}

struct BusClientPolicy
{
  int refcount;

  DBusList *rules;
};

BusClientPolicy*
bus_client_policy_new (void)
{
  BusClientPolicy *policy;

  policy = dbus_new0 (BusClientPolicy, 1);
  if (policy == NULL)
    return NULL;

  policy->refcount = 1;

  return policy;
}

BusClientPolicy *
bus_client_policy_ref (BusClientPolicy *policy)
{
  _dbus_assert (policy->refcount > 0);

  policy->refcount += 1;

  return policy;
}

static void
rule_unref_foreach (void *data,
                    void *user_data)
{
  BusPolicyRule *rule = data;

  bus_policy_rule_unref (rule);
}

void
bus_client_policy_unref (BusClientPolicy *policy)
{
  _dbus_assert (policy->refcount > 0);

  policy->refcount -= 1;

  if (policy->refcount == 0)
    {
      _dbus_list_foreach (&policy->rules,
                          rule_unref_foreach,
                          NULL);

      _dbus_list_clear (&policy->rules);

      dbus_free (policy);
    }
}

static void
remove_rules_by_type_up_to (BusClientPolicy   *policy,
                            BusPolicyRuleType  type,
                            DBusList          *up_to)
{
  DBusList *link;

  link = _dbus_list_get_first_link (&policy->rules);
  while (link != up_to)
    {
      BusPolicyRule *rule = link->data;
      DBusList *next = _dbus_list_get_next_link (&policy->rules, link);

      if (rule->type == type)
        {
          _dbus_list_remove_link (&policy->rules, link);
          bus_policy_rule_unref (rule);
        }
      
      link = next;
    }
}

void
bus_client_policy_optimize (BusClientPolicy *policy)
{
  DBusList *link;

  /* The idea here is that if we have:
   * 
   * <allow send_interface="foo.bar"/>
   * <deny send_interface="*"/>
   *
   * (for example) the deny will always override the allow.  So we
   * delete the allow. Ditto for deny followed by allow, etc. This is
   * a dumb thing to put in a config file, but the <include> feature
   * of files allows for an "inheritance and override" pattern where
   * it could make sense. If an included file wants to "start over"
   * with a blanket deny, no point keeping the rules from the parent
   * file.
   */

  _dbus_verbose ("Optimizing policy with %d rules\n",
                 _dbus_list_get_length (&policy->rules));
  
  link = _dbus_list_get_first_link (&policy->rules);
  while (link != NULL)
    {
      BusPolicyRule *rule;
      DBusList *next;
      dbus_bool_t remove_preceding;

      next = _dbus_list_get_next_link (&policy->rules, link);
      rule = link->data;
      
      remove_preceding = FALSE;

      _dbus_assert (rule != NULL);
      
      switch (rule->type)
        {
        case BUS_POLICY_RULE_SEND:
          remove_preceding =
            rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &&
            rule->d.send.path == NULL &&
            rule->d.send.interface == NULL &&
            rule->d.send.member == NULL &&
            rule->d.send.error == NULL &&
            rule->d.send.destination == NULL;
          break;
        case BUS_POLICY_RULE_RECEIVE:
          remove_preceding =
            rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &&
            rule->d.receive.path == NULL &&
            rule->d.receive.interface == NULL &&
            rule->d.receive.member == NULL &&
            rule->d.receive.error == NULL &&
            rule->d.receive.origin == NULL;
          break;
        case BUS_POLICY_RULE_OWN:
          remove_preceding =
            rule->d.own.service_name == NULL;
          break;
        case BUS_POLICY_RULE_USER:
        case BUS_POLICY_RULE_GROUP:
          _dbus_assert_not_reached ("invalid rule");
          break;
        }

      if (remove_preceding)
        remove_rules_by_type_up_to (policy, rule->type,
                                    link);
      
      link = next;
    }

  _dbus_verbose ("After optimization, policy has %d rules\n",
                 _dbus_list_get_length (&policy->rules));
}

dbus_bool_t
bus_client_policy_append_rule (BusClientPolicy *policy,
                               BusPolicyRule   *rule)
{
  _dbus_verbose ("Appending rule %p with type %d to policy %p\n",
                 rule, rule->type, policy);
  
  if (!_dbus_list_append (&policy->rules, rule))
    return FALSE;

  bus_policy_rule_ref (rule);

  return TRUE;
}

dbus_bool_t
bus_client_policy_check_can_send (BusClientPolicy *policy,
                                  BusRegistry     *registry,
                                  dbus_bool_t      requested_reply,
                                  DBusConnection  *receiver,
                                  DBusMessage     *message,
                                  dbus_int32_t    *toggles,
                                  dbus_bool_t     *log)
{
  DBusList *link;
  dbus_bool_t allowed;
  
  /* policy->rules is in the order the rules appeared
   * in the config file, i.e. last rule that applies wins
   */

  _dbus_verbose ("  (policy) checking send rules\n");
  *toggles = 0;
  
  allowed = FALSE;
  link = _dbus_list_get_first_link (&policy->rules);
  while (link != NULL)
    {
      BusPolicyRule *rule = link->data;

      link = _dbus_list_get_next_link (&policy->rules, link);
      
      /* Rule is skipped if it specifies a different
       * message name from the message, or a different
       * destination from the message
       */
      
      if (rule->type != BUS_POLICY_RULE_SEND)
        {
          _dbus_verbose ("  (policy) skipping non-send rule\n");
          continue;
        }

      if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
        {
          if (dbus_message_get_type (message) != rule->d.send.message_type)
            {
              _dbus_verbose ("  (policy) skipping rule for different message type\n");
              continue;
            }
        }

      /* If it's a reply, the requested_reply flag kicks in */
      if (dbus_message_get_reply_serial (message) != 0)
        {
          /* for allow, requested_reply=true means the rule applies
           * only when reply was requested. requested_reply=false means
           * always allow.
           */
          if (!requested_reply && rule->allow && rule->d.send.requested_reply && !rule->d.send.eavesdrop)
            {
              _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n");
              continue;
            }

          /* for deny, requested_reply=false means the rule applies only
           * when the reply was not requested. requested_reply=true means the
           * rule always applies.
           */
          if (requested_reply && !rule->allow && !rule->d.send.requested_reply)
            {
              _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
              continue;
            }
        }
      
      if (rule->d.send.path != NULL)
        {
          if (dbus_message_get_path (message) != NULL &&
              strcmp (dbus_message_get_path (message),
                      rule->d.send.path) != 0)
            {
              _dbus_verbose ("  (policy) skipping rule for different path\n");
              continue;
            }
        }
      
      if (rule->d.send.interface != NULL)
        {
          /* The interface is optional in messages. For allow rules, if the message
           * has no interface we want to skip the rule (and thus not allow);
           * for deny rules, if the message has no interface we want to use the
           * rule (and thus deny).
           */
          dbus_bool_t no_interface;

          no_interface = dbus_message_get_interface (message) == NULL;
          
          if ((no_interface && rule->allow) ||
              (!no_interface && 
               strcmp (dbus_message_get_interface (message),
                       rule->d.send.interface) != 0))
            {
              _dbus_verbose ("  (policy) skipping rule for different interface\n");
              continue;
            }
        }

      if (rule->d.send.member != NULL)
        {
          if (dbus_message_get_member (message) != NULL &&
              strcmp (dbus_message_get_member (message),
                      rule->d.send.member) != 0)
            {
              _dbus_verbose ("  (policy) skipping rule for different member\n");
              continue;
            }
        }

      if (rule->d.send.error != NULL)
        {
          if (dbus_message_get_error_name (message) != NULL &&
              strcmp (dbus_message_get_error_name (message),
                      rule->d.send.error) != 0)
            {
              _dbus_verbose ("  (policy) skipping rule for different error name\n");
              continue;
            }
        }
      
      if (rule->d.send.destination != NULL)
        {
          /* receiver can be NULL for messages that are sent to the
           * message bus itself, we check the strings in that case as
           * built-in services don't have a DBusConnection but messages
           * to them have a destination service name.
           */
          if (receiver == NULL)
            {
              if (!dbus_message_has_destination (message,
                                                 rule->d.send.destination))
                {
                  _dbus_verbose ("  (policy) skipping rule because message dest is not %s\n",
                                 rule->d.send.destination);
                  continue;
                }
            }
          else
            {
              DBusString str;
              BusService *service;
              
              _dbus_string_init_const (&str, rule->d.send.destination);
              
              service = bus_registry_lookup (registry, &str);
              if (service == NULL)
                {
                  _dbus_verbose ("  (policy) skipping rule because dest %s doesn't exist\n",
                                 rule->d.send.destination);
                  continue;
                }

              if (!bus_service_has_owner (service, receiver))
                {
                  _dbus_verbose ("  (policy) skipping rule because dest %s isn't owned by receiver\n",
                                 rule->d.send.destination);
                  continue;
                }
            }
        }

      /* Use this rule */
      allowed = rule->allow;
      *log = rule->d.send.log;
      (*toggles)++;

      _dbus_verbose ("  (policy) used rule, allow now = %d\n",
                     allowed);
    }

  return allowed;
}

/* See docs on what the args mean on bus_context_check_security_policy()
 * comment
 */
dbus_bool_t
bus_client_policy_check_can_receive (BusClientPolicy *policy,
                                     BusRegistry     *registry,
                                     dbus_bool_t      requested_reply,
                                     DBusConnection  *sender,
                                     DBusConnection  *addressed_recipient,
                                     DBusConnection  *proposed_recipient,
                                     DBusMessage     *message,
                                     dbus_int32_t    *toggles)
{
  DBusList *link;
  dbus_bool_t allowed;
  dbus_bool_t eavesdropping;

  eavesdropping =
    addressed_recipient != proposed_recipient &&
    dbus_message_get_destination (message) != NULL;
  
  /* policy->rules is in the order the rules appeared
   * in the config file, i.e. last rule that applies wins
   */

  _dbus_verbose ("  (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
  *toggles = 0;
  
  allowed = FALSE;
  link = _dbus_list_get_first_link (&policy->rules);
  while (link != NULL)
    {
      BusPolicyRule *rule = link->data;

      link = _dbus_list_get_next_link (&policy->rules, link);      
      
      if (rule->type != BUS_POLICY_RULE_RECEIVE)
        {
          _dbus_verbose ("  (policy) skipping non-receive rule\n");
          continue;
        }

      if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
        {
          if (dbus_message_get_type (message) != rule->d.receive.message_type)
            {
              _dbus_verbose ("  (policy) skipping rule for different message type\n");
              continue;
            }
        }

      /* for allow, eavesdrop=false means the rule doesn't apply when
       * eavesdropping. eavesdrop=true means always allow.
       */
      if (eavesdropping && rule->allow && !rule->d.receive.eavesdrop)
        {
          _dbus_verbose ("  (policy) skipping allow rule since it doesn't apply to eavesdropping\n");
          continue;
        }

      /* for deny, eavesdrop=true means the rule applies only when
       * eavesdropping; eavesdrop=false means always deny.
       */
      if (!eavesdropping && !rule->allow && rule->d.receive.eavesdrop)
        {
          _dbus_verbose ("  (policy) skipping deny rule since it only applies to eavesdropping\n");
          continue;
        }

      /* If it's a reply, the requested_reply flag kicks in */
      if (dbus_message_get_reply_serial (message) != 0)
        {
          /* for allow, requested_reply=true means the rule applies
           * only when reply was requested. requested_reply=false means
           * always allow.
           */
          if (!requested_reply && rule->allow && rule->d.receive.requested_reply && !rule->d.receive.eavesdrop)
            {
              _dbus_verbose ("  (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n");
              continue;
            }

          /* for deny, requested_reply=false means the rule applies only
           * when the reply was not requested. requested_reply=true means the
           * rule always applies.
           */
          if (requested_reply && !rule->allow && !rule->d.receive.requested_reply)
            {
              _dbus_verbose ("  (policy) skipping deny rule since it only applies to unrequested replies\n");
              continue;
            }
        }
      
      if (rule->d.receive.path != NULL)
        {
          if (dbus_message_get_path (message) != NULL &&
              strcmp (dbus_message_get_path (message),
                      rule->d.receive.path) != 0)
            {
              _dbus_verbose ("  (policy) skipping rule for different path\n");
              continue;
            }
        }
      
      if (rule->d.receive.interface != NULL)
        {
          /* The interface is optional in messages. For allow rules, if the message
           * has no interface we want to skip the rule (and thus not allow);
           * for deny rules, if the message has no interface we want to use the
           * rule (and thus deny).
           */
          dbus_bool_t no_interface;

          no_interface = dbus_message_get_interface (message) == NULL;
          
          if ((no_interface && rule->allow) ||
              (!no_interface &&
               strcmp (dbus_message_get_interface (message),
                       rule->d.receive.interface) != 0))
            {
              _dbus_verbose ("  (policy) skipping rule for different interface\n");
              continue;
            }
        }      

      if (rule->d.receive.member != NULL)
        {
          if (dbus_message_get_member (message) != NULL &&
              strcmp (dbus_message_get_member (message),
                      rule->d.receive.member) != 0)
            {
              _dbus_verbose ("  (policy) skipping rule for different member\n");
              continue;
            }
        }

      if (rule->d.receive.error != NULL)
        {
          if (dbus_message_get_error_name (message) != NULL &&
              strcmp (dbus_message_get_error_name (message),
                      rule->d.receive.error) != 0)
            {
              _dbus_verbose ("  (policy) skipping rule for different error name\n");
              continue;
            }
        }
      
      if (rule->d.receive.origin != NULL)
        {          
          /* sender can be NULL for messages that originate from the
           * message bus itself, we check the strings in that case as
           * built-in services don't have a DBusConnection but will
           * still set the sender on their messages.
           */
          if (sender == NULL)
            {
              if (!dbus_message_has_sender (message,
                                            rule->d.receive.origin))
                {
                  _dbus_verbose ("  (policy) skipping rule because message sender is not %s\n",
                                 rule->d.receive.origin);
                  continue;
                }
            }
          else
            {
              BusService *service;
              DBusString str;

              _dbus_string_init_const (&str, rule->d.receive.origin);
              
              service = bus_registry_lookup (registry, &str);
              
              if (service == NULL)
                {
                  _dbus_verbose ("  (policy) skipping rule because origin %s doesn't exist\n",
                                 rule->d.receive.origin);
                  continue;
                }

              if (!bus_service_has_owner (service, sender))
                {
                  _dbus_verbose ("  (policy) skipping rule because origin %s isn't owned by sender\n",
                                 rule->d.receive.origin);
                  continue;
                }
            }
        }
      
      /* Use this rule */
      allowed = rule->allow;
      (*toggles)++;

      _dbus_verbose ("  (policy) used rule, allow now = %d\n",
                     allowed);
    }

  return allowed;
}



static dbus_bool_t
bus_rules_check_can_own (DBusList *rules,
                         const DBusString *service_name)
{
  DBusList *link;
  dbus_bool_t allowed;
  
  /* rules is in the order the rules appeared
   * in the config file, i.e. last rule that applies wins
   */

  allowed = FALSE;
  link = _dbus_list_get_first_link (&rules);
  while (link != NULL)
    {
      BusPolicyRule *rule = link->data;

      link = _dbus_list_get_next_link (&rules, link);
      
      /* Rule is skipped if it specifies a different service name from
       * the desired one.
       */
      
      if (rule->type != BUS_POLICY_RULE_OWN)
        continue;

      if (!rule->d.own.prefix && rule->d.own.service_name != NULL)
        {
          if (!_dbus_string_equal_c_str (service_name,
                                         rule->d.own.service_name))
            continue;
        }
      else if (rule->d.own.prefix)
        {
          const char *data;
          char next_char;
          if (!_dbus_string_starts_with_c_str (service_name,
                                               rule->d.own.service_name))
            continue;

          data = _dbus_string_get_const_data (service_name);
          next_char = data[strlen (rule->d.own.service_name)];
          if (next_char != '\0' && next_char != '.')
            continue;
        }

      /* Use this rule */
      allowed = rule->allow;
    }

  return allowed;
}

dbus_bool_t
bus_client_policy_check_can_own (BusClientPolicy  *policy,
                                 const DBusString *service_name)
{
  return bus_rules_check_can_own (policy->rules, service_name);
}

#ifdef DBUS_BUILD_TESTS
dbus_bool_t
bus_policy_check_can_own (BusPolicy  *policy,
                          const DBusString *service_name)
{
  return bus_rules_check_can_own (policy->default_rules, service_name);
}
#endif /* DBUS_BUILD_TESTS */

