581
602
nad_set_attr(pkt->nad, list, -1, "name", zlist->name, 0);
605
/** remove jid deny ocurrences from the privacy list,
606
unblock all if no jid given to match,
607
then update unblocked contact with presence information */
608
static void _unblock_jid(user_t user, storage_t st, zebra_list_t zlist, jid_t jid) {
612
jid_t notify_jid = NULL;
614
for(scan = zlist->items; scan != NULL; scan = scan->next) {
615
if(scan->type == zebra_JID && scan->deny && (jid == NULL || jid_compare_full(scan->jid, jid) == 0)) {
616
if(zlist->items == scan) {
617
zlist->items = scan->next;
618
if(zlist->items != NULL)
619
zlist->items->prev = NULL;
621
assert(scan->prev != NULL);
622
scan->prev->next = scan->next;
623
if(scan->next != NULL)
624
scan->next->prev = scan->prev;
626
/* and from the storage */
627
sprintf(filter, "(&(type=3:jid)(value=%i:%s)(deny=1)", strlen(jid_full(scan->jid)), jid_full(scan->jid));
628
storage_delete(st, "privacy-items", jid_user(user->jid), filter);
630
/* set jid for notify */
631
notify_jid = scan->jid;
634
/* update unblocked contact with presence information of all sessions */
636
/* XXX NOTE !!! There is a possibility that we notify more than once
637
* if user edited the privacy list manually, not with XEP-0191.
638
* Well... We're going to live with it. ;-) */
639
if(notify_jid != NULL && pres_trust(user, notify_jid))
640
for(sscan = user->sessions; sscan != NULL; sscan = sscan->next) {
641
/* do not update if session is not available,
642
* we sent presence direct or got error bounce */
643
if(!sscan->available || jid_search(sscan->A, notify_jid) || jid_search(sscan->E, notify_jid))
646
log_debug(ZONE, "updating unblocked %s with presence from %s", jid_full(notify_jid), jid_full(sscan->jid));
647
pkt_router(pkt_dup(sscan->pres, jid_full(notify_jid), jid_full(sscan->jid)));
584
652
/** list management requests */
585
653
static mod_ret_t _privacy_in_sess(mod_instance_t mi, sess_t sess, pkt_t pkt) {
586
654
module_t mod = mi->mod;
587
int ns, query, list, name, active, def, item, type, value, action, order;
655
int ns, query, list, name, active, def, item, type, value, action, order, blocking, jid, push = 0;
588
656
char corder[14], str[256], filter[1024];
590
658
zebra_list_t zlist, old;
592
660
zebra_item_t zitem, scan;
599
/* we only want to play with iq:privacy packets */
600
if((pkt->type != pkt_IQ && pkt->type != pkt_IQ_SET) || pkt->ns != ns_PRIVACY)
668
/* we only want to play with iq:privacy and urn:xmpp:blocking packets */
669
if((pkt->type != pkt_IQ && pkt->type != pkt_IQ_SET) || (pkt->ns != ns_PRIVACY && pkt->ns != ns_BLOCKING))
603
672
/* if it has a to, throw it out */
604
673
if(pkt->to != NULL)
605
674
return -stanza_err_BAD_REQUEST;
677
z = (zebra_t) sess->user->module_data[mod->index];
679
/* create session privacy description */
680
if(sess->module_data[mod->index] == NULL)
681
sess->module_data[mod->index] = (void *) pmalloco(sess->p, sizeof(struct privacy_st));
683
/* handle XEP-0191: Simple Communications Blocking
684
* as simplified frontend to default privacy list */
685
if(pkt->ns == ns_BLOCKING) {
686
if(pkt->type == pkt_IQ_SET) {
687
/* find out what to do */
689
ns = nad_find_scoped_namespace(pkt->nad, urn_BLOCKING, NULL);
690
blocking = nad_find_elem(pkt->nad, 1, ns, "block", 1);
694
blocking = nad_find_elem(pkt->nad, 1, ns, "unblock", 1);
698
return -stanza_err_BAD_REQUEST;
701
/* if there is no default list, create one */
703
/* remove any previous one */
704
if((zlist = xhash_get(z->lists, urn_BLOCKING))) {
706
sprintf(filter, "(list=%i:%s)", strlen(urn_BLOCKING), urn_BLOCKING);
707
storage_delete(mod->mm->sm->st, "privacy-items", jid_user(sess->user->jid), filter);
710
/* create new zebra list with name 'urn:xmpp:blocking' */
712
zlist = (zebra_list_t) pmalloco(p, sizeof(struct zebra_list_st));
714
zlist->name = pstrdup(p, urn_BLOCKING);
715
xhash_put(z->lists, zlist->name, (void *) zlist);
717
/* make it default */
720
/* and in the storage */
722
o = os_object_new(os);
723
os_object_put(o, "default", zlist->name, os_type_STRING);
724
ret = storage_replace(mod->mm->sm->st, "privacy-default", jid_user(sess->user->jid), NULL, os);
726
if(ret != st_SUCCESS)
727
return -stanza_err_INTERNAL_SERVER_ERROR;
729
log_debug(ZONE, "blocking created '%s' privacy list and set it default", zlist->name);
731
/* use the default one */
734
/* activate this list */
735
((privacy_t) sess->module_data[mod->index])->active = zlist;
736
log_debug(ZONE, "session '%s' has now active list '%s'", jid_full(sess->jid), zlist->name);
738
item = nad_find_elem(pkt->nad, blocking, ns, "item", 1);
741
/* cannot block unknown */
742
return -stanza_err_BAD_REQUEST;
745
_unblock_jid(sess->user, mod->mm->sm->st, zlist, NULL);
747
/* mark to send blocklist push */
752
/* loop over the items */
755
jid = nad_find_attr(pkt->nad, item, -1, "jid", 0);
757
return -stanza_err_BAD_REQUEST;
759
jidt = jid_new(NAD_AVAL(pkt->nad, jid), NAD_AVAL_L(pkt->nad, jid));
761
return -stanza_err_BAD_REQUEST;
763
/* find blockitem in the list */
764
for(scan = zlist->items; scan != NULL; scan = scan->next)
765
if(scan->type == zebra_JID && jid_compare_full(scan->jid, jidt) == 0)
770
if(scan != NULL && scan->deny && scan->block == block_NONE) {
773
/* first make us unavailable if user is on roster */
774
if(pres_trust(sess->user, jidt))
775
for(sscan = sess->user->sessions; sscan != NULL; sscan = sscan->next) {
776
/* do not update if session is not available,
777
* we sent presence direct or got error bounce */
778
if(!sscan->available || jid_search(sscan->A, jidt) || jid_search(sscan->E, jidt))
781
log_debug(ZONE, "forcing unavailable to %s from %s after block", jid_full(jidt), jid_full(sscan->jid));
782
pkt_router(pkt_create(sess->user->sm, "presence", "unavailable", jid_full(jidt), jid_full(sscan->jid)));
786
zitem = (zebra_item_t) pmalloco(zlist->p, sizeof(struct zebra_item_st));
787
zitem->type = zebra_JID;
789
zitem->jid = jid_new(NAD_AVAL(pkt->nad, jid), NAD_AVAL_L(pkt->nad, jid));
790
pool_cleanup(zlist->p, (void *) jid_free, zitem->jid);
792
zitem->block = block_NONE;
794
/* insert it in front of list */
796
if(zlist->last == NULL) {
797
zlist->items = zlist->last = zitem;
799
zitem->next = zlist->items;
800
zlist->items->prev = zitem;
801
zlist->items = zitem;
804
/* and into the storage backend */
806
o = os_object_new(os);
807
os_object_put(o, "list", zlist->name, os_type_STRING);
808
os_object_put(o, "type", "jid", os_type_STRING);
809
os_object_put(o, "value", jid_full(zitem->jid), os_type_STRING);
810
os_object_put(o, "deny", &zitem->deny, os_type_BOOLEAN);
811
os_object_put(o, "order", &zitem->order, os_type_INTEGER);
812
os_object_put(o, "block", &zitem->block, os_type_INTEGER);
813
ret = storage_put(mod->mm->sm->st, "privacy-items", jid_user(sess->user->jid), os);
815
if(ret != st_SUCCESS) {
817
return -stanza_err_INTERNAL_SERVER_ERROR;
820
/* mark to send blocklist push */
825
if(scan != NULL && scan->deny) {
826
/* remove all jid deny ocurrences from the privacy list */
827
_unblock_jid(sess->user, mod->mm->sm->st, zlist, jidt);
829
/* mark to send blocklist push */
833
return -stanza_err_ITEM_NOT_FOUND;
840
item = nad_find_elem(pkt->nad, item, ns, "item", 0);
843
/* return empty result */
844
result = pkt_create(pkt->sm, "iq", "result", NULL, NULL);
846
pkt_sess(result, sess);
850
for(sscan = sess->user->sessions; sscan != NULL; sscan = sscan->next) {
851
/* don't push to us or to anyone who hasn't requested blocklist */
852
if(sscan == sess || sscan->module_data[mod->index] == NULL || ((privacy_t) sscan->module_data[mod->index])->blocklist == 0)
855
result = pkt_dup(pkt, jid_full(sscan->jid), NULL);
856
if(result->from != NULL) {
857
jid_free(result->from);
858
nad_set_attr(result->nad, 1, -1, "from", NULL, 0);
861
pkt_sess(result, sscan);
865
/* and done with request */
871
ns = nad_find_scoped_namespace(pkt->nad, urn_BLOCKING, NULL);
872
blocking = nad_find_elem(pkt->nad, 1, ns, "blocklist", 1);
874
return -stanza_err_BAD_REQUEST;
876
result = pkt_create(pkt->sm, "iq", "result", NULL, NULL);
878
ns = nad_add_namespace(result->nad, urn_BLOCKING, NULL);
879
blocking = nad_insert_elem(result->nad, 1, ns, "blocklist", NULL);
881
/* insert items only from the default list */
883
log_debug(ZONE, "blocking list is '%s'", z->def->name);
884
zlist = xhash_get(z->lists, z->def->name);
885
/* run through the items and build the nad */
886
for(zitem = zlist->items; zitem != NULL; zitem = zitem->next) {
887
/* we're interested in items type 'jid' with action 'deny' only */
888
if(zitem->type == zebra_JID && zitem->deny) {
889
item = nad_insert_elem(result->nad, blocking, -1, "item", NULL);
890
nad_set_attr(result->nad, item, -1, "jid", jid_full(zitem->jid), 0);
894
/* mark that the blocklist was requested */
895
((privacy_t) sess->module_data[mod->index])->blocklist = 1;
898
/* give it to the session */
899
pkt_sess(result, sess);
904
/* else handle XEP-0016: Privacy Lists */
607
906
/* find the query */
608
907
ns = nad_find_scoped_namespace(pkt->nad, uri_PRIVACY, NULL);
609
908
query = nad_find_elem(pkt->nad, 1, ns, "query", 1);
611
910
return -stanza_err_BAD_REQUEST;
614
z = (zebra_t) sess->user->module_data[mod->index];
616
912
/* update lists or set the active list */
617
913
if(pkt->type == pkt_IQ_SET) {
618
914
/* find out what we're doing */