📄 mod_privacy.c
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, * Ryan Eatmon, Robert Norris * * 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., 59 Temple Place, Suite 330, Boston, MA02111-1307USA */#include "sm.h"/** @file sm/mod_privacy.c * @brief privacy lists * @author Robert Norris * $Date: 2004/11/13 16:08:33 $ * $Revision: 1.19.2.10 $ */typedef struct zebra_st *zebra_t;typedef struct zebra_list_st *zebra_list_t;typedef struct zebra_item_st *zebra_item_t;typedef enum { zebra_NONE, zebra_JID, zebra_GROUP, zebra_S10N} zebra_item_type_t;typedef enum { block_NONE = 0x00, block_MESSAGE = 0x01, block_PRES_IN = 0x02, block_PRES_OUT = 0x04, block_IQ = 0x08} zebra_block_type_t;/** zebra data for a single user */struct zebra_st { xht lists; zebra_list_t def;};struct zebra_list_st { pool p; char *name; zebra_item_t items, last;};struct zebra_item_st { zebra_item_type_t type; jid_t jid; char *group; int to; int from; int deny; /* 0 = allow, 1 = deny */ int order; zebra_block_type_t block; zebra_item_t next, prev;};static void _privacy_free(zebra_t z) { zebra_list_t zlist; log_debug(ZONE, "freeing zebra ctx"); if(xhash_iter_first(z->lists)) do { xhash_iter_get(z->lists, NULL, (void **) &zlist); pool_free(zlist->p); } while(xhash_iter_next(z->lists)); xhash_free(z->lists); free(z);}static void _privacy_user_free(zebra_t *z) { if(*z != NULL) _privacy_free(*z);}static int _privacy_user_load(mod_instance_t mi, user_t user) { module_t mod = mi->mod; zebra_t z; os_t os; os_object_t o; os_type_t ot; zebra_list_t zlist; pool p; zebra_item_t zitem, scan; char *str; log_debug(ZONE, "loading privacy lists for %s", jid_user(user->jid)); /* free if necessary */ z = user->module_data[mod->index]; if(z != NULL) _privacy_free(z); z = (zebra_t) malloc(sizeof(struct zebra_st)); memset(z, 0, sizeof(struct zebra_st)); z->lists = xhash_new(101); user->module_data[mod->index] = z; pool_cleanup(user->p, (void (*))(void *) _privacy_user_free, &(user->module_data[mod->index])); /* pull the whole lot */ if(storage_get(user->sm->st, "privacy-items", jid_user(user->jid), NULL, &os) == st_SUCCESS) { if(os_iter_first(os)) do { o = os_iter_object(os); /* list name */ if(!os_object_get(os, o, "list", (void **) &str, os_type_STRING, &ot)) { log_debug(ZONE, "item with no list field, skipping"); continue; } log_debug(ZONE, "got item for list %s", str); zlist = xhash_get(z->lists, str); /* new list */ if(zlist == NULL) { log_debug(ZONE, "creating list %s", str); p = pool_new(); zlist = (zebra_list_t) pmalloco(p, sizeof(struct zebra_list_st)); zlist->p = p; zlist->name = pstrdup(p, str); xhash_put(z->lists, zlist->name, (void *) zlist); } /* new item */ zitem = (zebra_item_t) pmalloco(zlist->p, sizeof(struct zebra_item_st)); /* item type */ if(os_object_get(os, o, "type", (void **) &str, os_type_STRING, &ot)) switch(str[0]) { case 'j': zitem->type = zebra_JID; break; case 'g': zitem->type = zebra_GROUP; break; case 's': zitem->type = zebra_S10N; break; } /* item value, according to type */ if(zitem->type != zebra_NONE) { if(!os_object_get(os, o, "value", (void **) &str, os_type_STRING, &ot)) { log_debug(ZONE, "no value on non-fall-through item, dropping this item"); free(zitem); continue; } switch(zitem->type) { case zebra_JID: zitem->jid = jid_new(user->sm->pc, str, strlen(str)); if(zitem->jid == NULL) { log_debug(ZONE, "invalid jid '%s' on item, dropping this item", str); free(zitem); continue; } pool_cleanup(zlist->p, free, zitem->jid); log_debug(ZONE, "jid item with value '%s'", jid_full(zitem->jid)); break; case zebra_GROUP: zitem->group = pstrdup(zlist->p, str); log_debug(ZONE, "group item with value '%s'", zitem->group); break; case zebra_S10N: if(strcmp(str, "to") == 0) zitem->to = 1; else if(strcmp(str, "from") == 0) zitem->from = 1; else if(strcmp(str, "both") == 0) zitem->to = zitem->from = 1; else if(strcmp(str, "none") != 0) { log_debug(ZONE, "invalid value '%s' on s10n item, dropping this item", str); free(zitem); continue; } log_debug(ZONE, "s10n item with value '%s' (to %d from %d)", str, zitem->to, zitem->from); break; case zebra_NONE: /* can't get here */ break; } } /* action */ os_object_get(os, o, "deny", (void **) &zitem->deny, os_type_BOOLEAN, &ot); if(zitem->deny) { log_debug(ZONE, "deny rule"); } else { log_debug(ZONE, "accept rule"); } os_object_get(os, o, "order", (void **) &(zitem->order), os_type_INTEGER, &ot); log_debug(ZONE, "order %d", zitem->order); os_object_get(os, o, "block", (void **) &(zitem->block), os_type_INTEGER, &ot); log_debug(ZONE, "block 0x%x", zitem->block); /* insert it */ for(scan = zlist->items; scan != NULL; scan = scan->next) if(zitem->order < scan->order) break; /* we're >= everyone, add us to the end */ if(scan == NULL) { if(zlist->last == NULL) zlist->items = zlist->last = zitem; else { zlist->last->next = zitem; zitem->prev = zlist->last; zlist->last = zitem; } } /* insert just before scan */ else { if(zlist->items == scan) { zitem->next = zlist->items; zlist->items = zitem; scan->prev = zitem; } else { zitem->next = scan; zitem->prev = scan->prev; scan->prev->next = zitem; scan->prev = zitem; } } } while(os_iter_next(os)); os_free(os); } /* default list */ if(storage_get(user->sm->st, "privacy-default", jid_user(user->jid), NULL, &os) == st_SUCCESS) { if(os_iter_first(os)) do { o = os_iter_object(os); if(os_object_get(os, o, "default", (void **) &str, os_type_STRING, &ot)) { z->def = (zebra_list_t) xhash_get(z->lists, str); if(z->def == NULL) { log_debug(ZONE, "storage says the default list for %s is %s, but it doesn't exist!", jid_user(user->jid), str); } else { log_debug(ZONE, "user %s has default list %s", jid_user(user->jid), str); } } } while(os_iter_next(os)); os_free(os); } return 0;}/** returns 0 if the packet should be allowed, otherwise 1 */static int _privacy_action(user_t user, zebra_list_t zlist, jid_t jid, pkt_type_t ptype, int in) { zebra_item_t scan; int match, i; item_t ritem; unsigned char domres[2048]; log_debug(ZONE, "running match on list %s for %s (packet type 0x%x) (%s)", zlist->name, jid_full(jid), ptype, in ? "incoming" : "outgoing"); /* loop over the list, trying to find a match */ for(scan = zlist->items; scan != NULL; scan = scan->next) { match = 0; switch(scan->type) { case zebra_NONE: /* fall through, all packets match this */ match = 1; break; case zebra_JID: sprintf(domres, "%s/%s", jid->domain, jid->resource); /* jid check - match node@dom/res, then node@dom, then dom/resource, then dom */ if(jid_compare_full(scan->jid, jid) == 0 || strcmp(jid_full(scan->jid), jid_user(jid)) == 0 || strcmp(jid_full(scan->jid), domres) == 0 || strcmp(jid_full(scan->jid), jid->domain) == 0) match = 1; break; case zebra_GROUP: /* roster group check - get the roster item, node@dom/res, then node@dom, then dom */ ritem = xhash_get(user->roster, jid_full(jid)); if(ritem == NULL) ritem = xhash_get(user->roster, jid_user(jid)); if(ritem == NULL) ritem = xhash_get(user->roster, jid->domain); /* got it, do the check */ if(ritem != NULL) for(i = 0; i < ritem->ngroups; i++) if(strcmp(scan->group, ritem->groups[i]) == 0) match = 1; break; case zebra_S10N:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -