Logo Search packages:      
Sourcecode: jabberd14 version File versions  Download package

static int mod_privacy_activate_list ( jsmi  si,
session  s,
xmlnode  list 
) [static]

activates a privacy list

Parameters:
s the session for which the privacy list should be activated
list the list to activate
Returns:
if the given privacy list has been activated

Definition at line 560 of file mod_privacy.cc.

References session_struct::aux_data, session_struct::id, udata_struct::id, j_strcmp(), jpacket_new(), js_deliver(), js_session_to(), jutil_presnew(), mod_privacy_blocked_seen_jids(), mod_privacy_blocked_trustees(), mod_privacy_compile_list(), mod_privacy_free_current_list_definitions(), xmlnode_list_item_t::next, xmlnode_list_item_t::node, session_struct::p, mod_privacy_compiled_list_item::p, PACKET_PASS_FILTERS_MAGIC, pool_free(), session_struct::presence, pstrdup(), session_struct::si, jsmi_struct::std_namespace_prefixes, session_struct::u, jsmi_struct::xc, xdb_get(), xhash_get(), xhash_put(), xmlnode_dup(), xmlnode_free(), xmlnode_get_attrib_ns(), xmlnode_get_data(), xmlnode_get_tags(), xmlnode_hide(), xmlnode_insert_cdata(), and xmlnode_put_attrib_ns().

Referenced by mod_privacy_activate_named().

                                                                       {
    struct mod_privacy_compiled_list_item* new_list = NULL;
    const char* list_name = NULL;
    xmlnode roster = NULL;
    jid cur = NULL;
    pool p = NULL;
    jid blocked_trustees_before = NULL;
    jid blocked_trustees_after = NULL;
    jid blocked_seen_jids_before = NULL;
    jid blocked_seen_jids_after = NULL;
    xmlnode_list_item group = NULL;

    /* sanity check */
    if (s == NULL || list == NULL)
      return 0;

    /* get memory pool used inside this function */
    p = pool_new();

    /* remember blocked trustees */
    blocked_trustees_before = mod_privacy_blocked_trustees(p, s);

    /* remember blocked seen_jids */
    blocked_seen_jids_before = mod_privacy_blocked_seen_jids(p, s);

    /* get the list name */
    list_name = xmlnode_get_attrib_ns(list, "name", NULL);

    /* keep the name of the list (compare with previous value and do not pstrdup if it is the same)*/
    if (j_strcmp(list_name, static_cast<char*>(xhash_get(s->aux_data, "mod_privacy_active"))) != 0)
      xhash_put(s->aux_data, "mod_privacy_active", pstrdup(s->p, list_name));

    /* free the old compiled filter lists */
    mod_privacy_free_current_list_definitions(s);

    /* get the user's roster, we need it to compile the list */
    roster = xdb_get(s->si->xc, s->u->id, NS_ROSTER);

    /* normalize roster group names */
    for (group = xmlnode_get_tags(roster, "roster:item/roster:group", si->std_namespace_prefixes); group != NULL; group = group->next) {
      /* get normalized group name */
      const char* group_name = xmlnode_get_data(group->node);
      jid normal_group = jid_new(p, "invalid");
      jid_set(normal_group, group_name, JID_RESOURCE);

      log_debug2(ZONE, LOGT_EXECFLOW, "Checking normalization of roster group: %s", group_name);

      /* could the name be normalized? */
      if (normal_group == NULL || normal_group->resource == NULL) {
          log_debug2(ZONE, LOGT_EXECFLOW, "Could not normalize group name in roster: %s", group_name);
          xmlnode_hide(group->node);
          continue;
      }

      /* insert normalized data if necessary */
      if (j_strcmp(group_name, normal_group->resource) != 0) {
          xmlnode_list_item text_node = xmlnode_get_tags(group->node, "text()", si->std_namespace_prefixes);

          log_debug2(ZONE, LOGT_EXECFLOW, "Normalized '%s' to '%s'", group_name, normal_group->resource);

          if (text_node != NULL) {
            xmlnode_hide(text_node->node);
          }
          xmlnode_insert_cdata(group->node, normal_group->resource, -1);
      }
    }

    /* normalize group names in a privacy list */
    for (group = xmlnode_get_tags(list, "privacy:item[@type='group']", si->std_namespace_prefixes); group != NULL; group = group->next) {
      const char* group_name = xmlnode_get_attrib_ns(group->node, "value", NULL);
      jid normal_group = jid_new(p, "invalid");
      jid_set(normal_group, group_name, JID_RESOURCE);

      log_debug2(ZONE, LOGT_EXECFLOW, "Checking normalization of group on list: %s", group_name);

      /* could the name be normalized? */
      if (normal_group == NULL || normal_group->resource == NULL) {
          log_debug2(ZONE, LOGT_EXECFLOW, "Could not normalize group name on list: %s", group_name);
          xmlnode_hide(group->node);
          continue;
      }

      /* update value if necessary */
      if (j_strcmp(group_name, normal_group->resource) != 0) {
          log_debug2(ZONE, LOGT_EXECFLOW, "Normalized '%s' to '%s'", group_name, normal_group->resource);
          xmlnode_put_attrib_ns(group->node, "value", NULL, NULL, normal_group->resource);
      }
    }

    /* compile the new filter list */
    log_debug2(ZONE, LOGT_EXECFLOW, "Compiling list for 'message'");
    new_list = mod_privacy_compile_list(s->si, list, roster, "message");
    if (new_list)
      xhash_put(s->aux_data, "mod_privacy_list_message", new_list);

    log_debug2(ZONE, LOGT_EXECFLOW, "Compiling list for 'presence-out'");
    new_list = mod_privacy_compile_list(s->si, list, roster, "presence-out");
    if (new_list)
      xhash_put(s->aux_data, "mod_privacy_list_presence-out", new_list);

    log_debug2(ZONE, LOGT_EXECFLOW, "Compiling list for 'presence-in'");
    new_list = mod_privacy_compile_list(s->si, list, roster, "presence-in");
    if (new_list)
      xhash_put(s->aux_data, "mod_privacy_list_presence-in", new_list);

    log_debug2(ZONE, LOGT_EXECFLOW, "Compiling list for 'iq'");
    new_list = mod_privacy_compile_list(s->si, list, roster, "iq");
    if (new_list)
      xhash_put(s->aux_data, "mod_privacy_list_iq", new_list);

    /* free the roster */
    if (roster != NULL)
      xmlnode_free(roster);

    /* see which trustees are now blocked */
    blocked_trustees_after = mod_privacy_blocked_trustees(p, s);

    /* send presence updates to trustees not blocked anymore */
    for (cur = blocked_trustees_before; cur != NULL; cur=cur->next) {
      jid cur2 = NULL;
      xmlnode presence = NULL;

      log_debug2(ZONE, LOGT_EXECFLOW, "trustee blocked before: %s", jid_full(cur));

      /* no presence, if still denied */
      for (cur2 = blocked_trustees_after; cur2 != NULL; cur2=cur2->next) {
          if (jid_cmp(cur, cur2) == 0) {
            continue;
          }
      }

      log_debug2(ZONE, LOGT_EXECFLOW, "... not blocked anymore. Send current presence.");

      /* not blocked anymore. send current presence */
      presence = xmlnode_dup(s->presence);
      xmlnode_put_attrib_ns(presence, "to", NULL, NULL, jid_full(cur));
      js_deliver(si, jpacket_new(presence), s);
    }

    /* send presence unavailable to trustees now blocked */
    for (cur = blocked_trustees_after; cur != NULL; cur=cur->next) {
      jid cur2 = NULL;
      xmlnode presence = NULL;
      jpacket jp = NULL;

      log_debug2(ZONE, LOGT_EXECFLOW, "trustee now blocked: %s", jid_full(cur));

      /* no unavailable, if already blocked before */
      for (cur2 = blocked_trustees_before; cur2 != NULL; cur2=cur2->next) {
          if (jid_cmp(cur, cur2) == 0) {
            continue;
          }
      }

      log_debug2(ZONE, LOGT_EXECFLOW, "... not blocked before. Send presence unavailable.");

      /* new block, send unavailable */
      presence = jutil_presnew(JPACKET__UNAVAILABLE, jid_full(cur), NULL);
      xmlnode_put_attrib_ns(presence, "from", NULL, NULL, jid_full(s->id));
      jp = jpacket_new(presence);
      jp->flag = PACKET_PASS_FILTERS_MAGIC;
      js_deliver(si, jp, s);
    }

    /* see which seen JIDs are now blocked */
    blocked_seen_jids_after = mod_privacy_blocked_seen_jids(p, s);

    /* send presence probes to seen JIDs not blocked anymore */
    for (cur = blocked_seen_jids_before; cur != NULL; cur=cur->next) {
      jid cur2 = NULL;
      xmlnode probe = NULL;

      log_debug2(ZONE, LOGT_EXECFLOW, "seen JID blocked before: %s", jid_full(cur));

      /* no presence, if still denied */
      for (cur2 = blocked_seen_jids_after; cur2 != NULL; cur2=cur2->next) {
          if (jid_cmp(cur, cur2) == 0) {
            continue;
          }
      }

      log_debug2(ZONE, LOGT_EXECFLOW, "... not blocked anymore. Send presence probe.");

      /* not blocked anymore. send presence probe */
      probe = jutil_presnew(JPACKET__PROBE, jid_full(cur), NULL);
      xmlnode_put_attrib_ns(probe, "from", NULL, NULL, jid_full(s->u->id));
      js_deliver(si, jpacket_new(probe), s);
    }

    /* send presence unavailable for seen JIDs now blocked */
    for (cur = blocked_seen_jids_after; cur != NULL; cur=cur->next) {
      jid cur2 = NULL;
      xmlnode presence = NULL;
      jpacket jp = NULL;

      log_debug2(ZONE, LOGT_EXECFLOW, "seen JID now blocked: %s", jid_full(cur));

      /* no unavailable, if already blocked before */
      for (cur2 = blocked_seen_jids_before; cur2 != NULL; cur2=cur2->next) {
          if (jid_cmp(cur, cur2) == 0) {
            continue;
          }
      }

      log_debug2(ZONE, LOGT_EXECFLOW, "... not blocked before. Send presence unavailable.");

      /* new block, send unavailable */
      presence = jutil_presnew(JPACKET__UNAVAILABLE, jid_full(s->id), NULL);
      xmlnode_put_attrib_ns(presence, "from", NULL, NULL, jid_full(cur)); /* XXX: well actually we should send it from the resource, but we do not have it here */
      jp = jpacket_new(presence);
      jp->flag = PACKET_PASS_FILTERS_MAGIC;
      js_session_to(s, jp);
    }

    /* free local pool */
    pool_free(p);

    /* new list is active now */
    return 1;
}


Generated by  Doxygen 1.6.0   Back to index