2

I have certain users and they can chat anonymously. They are having one to one chat. Suppose I want to encrypt the username of sender. How can I achieve this.

What I have done so far :

start(_Host, _Opts) ->
   ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 0).

on_filter_packet({From, To, XML} = Packet) ->
        ?INFO_MSG("Packet From intercepted ~p", [From] ),
        Packet.

In this code it is returning Packet and I can change the packet in that function.

How can I change From, So that it is reflected on client side.

This is From in logs:

{jid,<<"username">>,<<"domain.com">>,<<"1960117812133817321731161">>,<<"username">>,<<"domain.com">>,<<"1960117812133817321731161">>}

Thanks in advance,

Mickaël Rémond
  • 9,035
  • 1
  • 24
  • 44
no one
  • 477
  • 6
  • 19

1 Answers1

2

First of all, your implementation has a major issue. You are attempting to transform all packets, not only message packets. The way you did it, you were going to break the routing by rewrite iq and presence packet as well

Here is a working module that basically replace the from of the message. I used hash to "encode" the from and make the username "permanent" so that all messages from the same person will appears in a single conversation. However, feel free to replace with the algorithm of your choice:

%% To add in ejabberd modules configuration section:
%%   mod_replace_from: {}
-module(mod_replace_from).

-behaviour(gen_mod).

-export([start/2, stop/1]).
-export([on_filter_packet/1]).
-include("jlib.hrl").
-include("logger.hrl").

start(_Host, _Opts) ->
    ejabberd_hooks:add(filter_packet, ?MODULE, on_filter_packet, 50),
    ok.

stop(_Host) ->
    ejabberd_hooks:delete(filter_packet, ?MODULE, on_filter_packet, 50),
    ok.

on_filter_packet({From, To, #xmlel{name = <<"message">>} = XML}) ->
    ?INFO_MSG("Packet From intercepted ~p ~p", [From, XML]),
    NewFrom = replace_jid_user(From),
    {NewFrom, To, XML};
on_filter_packet(Packet) ->
    Packet.

replace_jid_user(JID) ->
    {U, S, R} = split_jid(JID),
    Hash = integer_to_binary(erlang:phash2(U)),
    jlib:make_jid(Hash,S,R).

%% Will be added to jlib.erl
%% This is the reverse of make_jid/3
-spec split_jid(jid()) -> {binary(), binary(), binary()} | error.                              
split_jid(#jid{user = U, server = S, resource = R}) ->
    {U, S, R};
split_jid(_) ->
    error.

This is a basic implementation because, while it replies to the question, it is far from a complete solution for anonymous chatting. For example, you will need to handle algorithm to somewhat implement a routing of the packet to allow people to reply and make sure that the packet will reach the original anonymous sender. I am sure will will face more challenges down the road.

However, this addresses the question and illustrates From JID manipulation in ejabberd.

Mickaël Rémond
  • 9,035
  • 1
  • 24
  • 44