Ochrona prywatności
Prolog
Czasem zdarzają się osobnicy z którymi nie mamy ochoty rozmawiać, oglądać ich statusu lub chcemy ukryć nasz status przed nimi. O ile filtrowanie wiadomości jest częstym ficzerem w klientach, to manipulowanie informacjami o obecności (bez zmieniania typu subskrypcji!) już nie (co zresztą jest dość skomplikowane do uzyskania). I tu z pomocą przychodzi privacy-list (o ile serwer je wspiera). Problem z tym, że mało który klient posiada jakąkolwiek opcję dotyczącą tej części standardu XMPP. Ale zaraz, zaraz Twój klient posiada dziwną pozycję w menu zatytułowaną „Konsola XML”? Spróbujmy ją ujarzmić ;)Pierwsze podejście
Sprawdźmy naszą listę reguł:<iq type="get" id="0"> <query xmlns="jabber:iq:privacy"/> </iq>
Na początku wynik zapewne nie będzie zbyt imponujący (czyste konto):
<iq type="result" id="0" > <query xmlns="jabber:iq:privacy"/> </iq>
Ustawiamy nową regułe (nazwy czarna_lista i Zablokowani można oczywiście zmienić na dowolną inną):
<iq type="set" id="1"> <query xmlns="jabber:iq:privacy"> <list name="czarna_lista"> <item type="group" value="Zablokowani" action="deny" order="1"/> <item action="allow" order="2"/> </list> </query> </iq>
Serwer odpowiada (zresztą w każdym kolejnym przypadku podobnie):
<iq type="result" id="1" />
Po tym można ustawić listę jako aktywną:
<iq type="set" id="2"> <query xmlns="jabber:iq:privacy"> <active name="czarna_lista"/> </query> </iq>
Pewnie chcemy ustawić też listę, jako domyślną:
<iq type="set" id="3"> <query xmlns="jabber:iq:privacy"> <default name="czarna_lista"/> </query> </iq>
Sprawdźmy na wszelki wypadek:
<iq type="get" id="4"> <query xmlns="jabber:iq:privacy"/> </iq>
Serwer odpowiada że jest jak miało być (aktywna == domyślna == „czarna_lista”):
<iq type="result" id="4"> <query xmlns="jabber:iq:privacy"> <default name="czarna_lista" /> <active name="czarna_lista" /> <list name="czarna_lista" /> </query> </iq>
Możemy czasowo wyłączyć „jabber:iq:privacy” wysyłając:
<iq type="set" id="5"> <query xmlns="jabber:iq:privacy"> <active/> </query> </iq>
Możemy wyłączyć domyślną listę wysyłając:
<iq type="set" id="6"> <query xmlns="jabber:iq:privacy"> <default/> </query> </iq>
W każdym momencie możemy sprawdzić reguły w wybranej liście:
<iq type="get" id="7"> <query xmlns="jabber:iq:privacy"> <list name="czarna_lista"/> </query> </iq>
Kiedy znudzi nam się zabawa w „jabber:iq:privacy” lub jakąś listę uważamy za zbędną możemy ją usunąć (wysłanie pustej listy równoznaczne jest z jej usunięciem):
<iq type="set" id="8"> <query xmlns="jabber:iq:privacy"> <list name="czarna_lista"/> </query> </iq>
Drugie podejście
Przyjrzyjmy się jeszcze raz pierwszemu (temu o id=”1”) <iq/>. Powoduje ono blokowanie całego ruchu od i do użytkowników którzy znajdują się w grupie o sugestywnej nazwie „Zablokowani” oraz zezwala dla pozostałych. Możemy to trochę zmodyfikować, blokując np. wychodzące <presence/> (użytkownicy z zablokowanej grupy nie zobaczą naszego statusu):<iq type="set" id="9"> <query xmlns="jabber:iq:privacy"> <list name="czarna_lista"> <item type="group" value="Zablokowani" action="deny" order="1"> <presence-out/> </item> <item action="allow" order="2"/> </list> </query> </iq>
Lista możliwości selektywnego blokowania:
- <message/> blokuje przychodzące wiadomości
- <iq/> blokuje przychodzące pakiety <iq/>
- <presence-in/> blokuje przychodzące pakiety <presence/>
- <presence-out/> blokuje wychodzące pakiety <presence/> (ps: to jest właśnie niewidzialność zgodna z RFC)
<iq type="set" id="10"> <query xmlns="jabber:iq:privacy"> <list name="czarna_lista"> <item type="group" value="Zablokowani" action="deny" order="1"> <message/> <presence-in/> <presence-out/> <iq/> </item> <item action="allow" order="2"/> </list> </query> </iq>
Teraz jeszcze raz wróćmy do pierwotnej wersji (żeby zbyt nie komplikować „kwerendy”) i przyjrzyjmy się atrybutowi type ze znacznika item. Atrybut ten może zawierać: jid, group, subscription.
We wszystkich przykładach powyżej zostało użyte group fitrowanie odbywało się na podstawie grupy, w której znajduje się użytkownik.
W przypadku typu jid value musi zawierać poprawny JID i stosowane są następujące reguły:
- gdy wpis pasuje do: użytkownik@domena/zasób blokowanie odbywa się tylko, gdy JID użytkownika (wraz z zasobem) pasuje do wzorca
- użytkownik@domena użytkownik blokowowany jest zawsze (niezależnie od zasobu)
- domena/zasób blokuje wszystkich użytkowników z określonej domeny o określonym zasobie (obejmuje również subdomeny dla przykładu chrome.pl/GG obejmie również użytkownika 333333@gg.chrome.pl/GG).
- domena blokuje wszystkich użytkowników z określonej domeny (uwaga jak wyżej)
<iq type="set" id="11"> <query xmlns="jabber:iq:privacy"> <list name="uczniowie"> <item type="jid" value="chrome.pl/szkoła" action="deny" order="1"/> <item action="allow" order="2"/> </list> </query> </iq>
W przypadku typu subscription atrybut value może mieć wartość: both, to, from lub none. Umożliwia to nam np. blokowanie wiadomości od użytkowników, których nie mamy na liście kontaktów (czyli z subskrypcją=”none”; chociaż oczywiście może się zdarzyć że i w rosterze mamy kogoś „z none”):
<iq type="set" id="12"> <query xmlns="jabber:iq:privacy"> <list name="obcy"> <item type="subscription" value="none" action="deny" order="1"/> <item action="allow" order="2"/> </list> </query> </iq>
Połączmy to ;)
Powyższe przykłady tworzą nowe listy jeśli chcemy ich użyć musimy je uaktywnić lub (lepiej bo przecież chcemy nadal blokować „Zablokowanych”) połączyć z naszą poprzednią:<iq type="set" id="13"> <query xmlns="jabber:iq:privacy"> <list name="wszystko-w-jednym"> <item type="group" value="Zablokowani" action="deny" order="1"> <message/> <presence-in/> <presence-out/> <iq/> </item> <item type="jid" value="chrome.pl/szkoła" action="deny" order="2"/> <item type="subscription" value="none" action="deny" order="3"/> <item action="allow" order="4"/> </list> </query> </iq>
Jak widać przykład się pokomplikował. Z dwóch elementów listy (<item/>) zrobiły się cztery. Jak to działa?
Kluczowe znaczenie ma tu atrybut order, od którego zależy kolejność sprawdzania reguł. Atrybuty te nie muszą być kolejnymi liczbami (mogą być luki), musi być nieujemny, a elementy nie muszą być posortowane zgodnie z tym atrybutem (dla ułatwienia analizy w przykładach powyżej są one posortowane i są kolejnymi liczbami). Reguły analizowane są w porządku rosnącym do momentu dopasowania (znalezienia pasującej reguły). W przypadku dopasowania „łańcuszek” zostaje przerwany i podejmowana jest akcja: allow lub deny (dla przypomnienia: zezwól lub zabroń). Jeśli jakiś element (<item/>) nie zawiera atrybutu type pasować będzie on do każdego użytkownika (jest więc to koniec łańcuszka, bez względu na to czy istnieją jeszcze jakieś elementy).
Epilog
Być może ten tekst nie jest zbyt odkrywczy, ale mam nadzieję, że się komuś przyda. Jeśli to wszystko mało pozostaje poszukać „brakującego ogniwa” w specyfikacji ;)Zobacz: komentarze
