Persistent Passwords on Self Hosted Rooms

Hi!

Cannot get the snippet working, the ‘success’ is always nil. Please could you help out?

-- /usr/lib/prosody/modules/
module:hook("muc-room-created", function (event)
    local room = event.room;
    module:log("debug", "hooked room create for %s", tostring(room));

    local pass = randPW(8);
    local success = room:set_password(pass);

    if not success then
        module:log("warn", "Failed to set password '%s' for %s.", pass, tostring(room));
    end
    
    module:log("debug", "Set password '%s' for %s.", pass, tostring(room));
    return nil;
end, 0);

-- https://rosettacode.org/wiki/Password_generator#Lua
function randPW (length)
    local index, pw, rnd = 0, ""
    local chars = {
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
        "abcdefghijklmnopqrstuvwxyz",
        "0123456789"
    }
    repeat
        index = index + 1
        rnd = math.random(chars[index]:len())
        if math.random(2) == 1 then
            pw = pw .. chars[index]:sub(rnd, rnd)
        else
            pw = chars[index]:sub(rnd, rnd) .. pw
        end
        index = index % #chars
    until pw:len() >= length
    return pw
end


Prosody 0.9.10

# Prosody directories
Data directory:         /var/lib/prosody
Plugin directory:       /usr/share/jitsi-meet/prosody-plugins/;/usr/lib/prosody/modules/
Config directory:       /etc/prosody
Source directory:       /usr/lib/prosody

# Lua environment
Lua version:                    Lua 5.1

Lua module search paths:
  /usr/lib/prosody/?.lua
  /usr/local/share/lua/5.1/?.lua
  /usr/local/share/lua/5.1/?/init.lua
  /usr/local/lib/lua/5.1/?.lua
  /usr/local/lib/lua/5.1/?/init.lua
  /usr/share/lua/5.1/?.lua
  /usr/share/lua/5.1/?/init.lua

Lua C module search paths:
  /usr/lib/prosody/?.so
  /usr/local/lib/lua/5.1/?.so
  /usr/lib/x86_64-linux-gnu/lua/5.1/?.so
  /usr/lib/lua/5.1/?.so
  /usr/local/lib/lua/5.1/loadall.so

LuaRocks:               Not installed

# Lua module versions
lfs:            LuaFileSystem 1.6.3
lxp:            LuaExpat 1.3.0
pposix:         0.3.6
socket:         LuaSocket 3.0-rc1
ssl:            0.5.1
1 Like

That method never returns in prosody 0.9 https://github.com/bjc/prosody/blob/0.9.14/plugins/muc/muc.lib.lua#L296
While in 0.11 it returns https://github.com/bjc/prosody/blob/0.11/plugins/muc/password.lib.lua#L16

1 Like

@damencho Thanks, Damian!

module:hook("muc-room-created", function (event)
    local room = event.room;
    module:log("debug", "hooked room create for %s", tostring(room));
    local pass = tostring(randPW(8));
    local res = room:set_password(pass);
    module:log("info", "Set password '%s' for %s.", pass, tostring(room));
    return res;
end, 0);

However the hook is constantly repeated, the password is not set and in the logs I can see multiple set password events.
Please could you give a hint on what Im doing wrong?
Thanks, very much appreciated.

I believe I had some trouble when returning anything else but nil, so your return res; statement could be a problem. However, as mentioned before, I do not really know Lua, nor the prosody API.

Still the same…

-- For Prosody 0.9 /usr/lib/prosody/modules/
module:hook("muc-room-created", function (event)
    local room = event.room;
    module:log("debug", "hooked room create for %s", tostring(room));
    local pass = tostring(randPW(8));
    local res = room:set_password(pass);
    module:log("info", "Set password '%s' for %s.", pass, tostring(room));
    return nil;
end, 0);

@damencho Damian, maybe you can help?

Did you try the muc-room-pre-create hook? Did not work for me on prosody 0.11 because jicofo failed to join the room but this may be different when using prosody 0.9.

Well, you need to let jicofo in the room, as jicofo is the first one to join normally.

Well, you need to let jicofo in the room, as jicofo is the first one to join normally.

Yes, thats why I switched to using the muc-room-created hook, to set the password only after jicofo joined.

@osys Another idea: have you tried to lower the priority of your hook to some negative value instead of 0?

Merging my discussion into this as I’m now in the same situation.

1 Like

Using the muc_room_default_persistent = true method I now have a different error: connection.GET_SESSION_ID_ERROR
I just closed the browser and joined in a private tab.

Folks, I’ve finally made it working by updating to the freshest version of Prosody

Prosody 0.11.5

# Lua environment
Lua version:                    Lua 5.2
LuaRocks:               Not installed

# Network

Backend: select

# Lua module versions
DBI:            0.7
lfs:            LuaFileSystem 1.6.3
lxp:            LuaExpat 1.3.0
socket:         LuaSocket 3.0-rc1
ssl:            0.6
1 Like

You can try to adjust the module posted above to fit your needs, that is do not allow to delete the password and don’t let rooms go stale (perhaps just remove the muc-room-destroyed hook.
Restart prosody to enable the module.

Now create a room, set a password and leave the room. Check that a plaintext file has been created in prosody’s data folder in a folder called <your-muc-component>/persistent_muc_passwords/<urlencoded_muc_name>.dat

Then also enable the prosody module described here: https://modules.prosody.im/mod_muc_config_restrict.html and add the muc#roomconfig_roomsecret option. Restart prosody again. For each room you want to setup, create a file similar to the file you checked in the last step. Make sure these are only readable by the prosody user.

This is still just a workaround, as anybody who joins a room first (i.e. the moderator) will see the Remove Password button. However, clicking this button shows an error message stating that passwords were not supported.

Hope this helps!

3 Likes

I am using docker as well and would to have this setup. Is it possible for you to layout in a more detailed guide? I am struggling on where the modules locations are and if we need to turn that on in the docker-compose.yml file (via .env).

I am using docker too in a test system.

If you do not change CONFIG in .env, file location in a standard configuration are
~/.jitsi-meet-cfg/prosody/conf.d/jitsi-meet.cfg.lua
~/.jitsi-meet-cfg/prosody-plugins-custom/mod_persist_muc_passwords.lua

In docker-compose.yml you have a add a line for a prosody module

prosody:
    image: jitsi/prosody
    expose:
        - '5222'
        - '5347'
        - '5280'
    volumes:
        - ${CONFIG}/prosody:/config
        - ${CONFIG}/prosody-plugins-custom:/prosody-plugins-custom

And you have to create the directory ~/.jitsi-meet-cfg/prosody-plugins-custom/

1 Like

Alternatively, if you don’t want to change the docker-compose.yml, just change the plugin_paths option in ~/.jitsi-meet-cfg/prosody/conf.d/jitsi-meet.cfg.lua to include "/config/prosody-plugins-custom". Then put the module in ~/.jitsi-meet-cfg/prosody/prosody-plugins-custom/mod_persist_muc_passwords.lua

1 Like

Thanks a lot for your script! I managed to install it and it works - half-way:

  • It still asks for the operator’s password. Am I supposed to turn the restrict_create_room(?) off again?
  • It’s still possible to delete the password.

Sorry if I misunderstood any of the above instructions. I came from a “quick install” and didn’t expect to deep dive into the system just to set up a password.

(edit: found some details I have to re-read)

To prevent the password from being deleted, you can enable the mod_muc_config_restrict.lua module mentioned above.

You are asked to provide the operator’s password because you setup a secure domain - if everybody should be able to create a room try to undo the respective configuration. Note that in this case whoever joins the room first will be the room’s moderator which is likely not what you want.

Thanks for everyone that’s helped as well, and I think it is working as intended.

  • I have authentication turned on (internal)
  • When I “create” a room and set the password, that password carries over from session to session (i.e. I close out the window completely and go back in), so that is working as intended
  • However, because I have authentication on, when a room does not have a participant anymore (everyone left) and then join back in, it requires someone to authenticate first, and then the room password kicks in; is there a way to not have authentication on a room that had been created?
2 Likes

I’m stuck on the very same problem right now.
I wonder if it makes sense to remove the authentication and just use the room’s password. Using any unknown room would require a password nobody knows.
As soon as I figured out why my settings don’t apply, I’ll start tinkering with the script @plokta provided.

My concern is that I have this running on a public-facing VPS and I don’t want anyone and everyone to use up my bandwidth. With my scenario, ideally I would like to only let authenticated users create persistent rooms that require passwords.

That being said, I think @plokta solution is the best workaround. I have authentication so not everyone can just create a room, and passwords are persistent.