Anonymous users support

Anonymous users support

ejabberd supports advanced and fine-grained anonymous login methods. This tutorial describe how to take advantage of those features, from ejabberd configuration to client integration.

Ejabberd supports several modes for anonymous login:

  • Anonymous login: This is a standard login, that use the classical login and password mechanisms, but where password is accepted or preconfigured for all anonymous users. This login is compliant with sasl authentication, password and digest non-sasl authentication.
  • SASL anonymous: This is a special SASL authentication mechanism that enables anonymous login (See: XEP-0175).

The main advantage of SASL anonymous is that the protocol has been design to give the user a login. This is useful to avoid in some case, where the server has many users already logged or registered and when it is hard to find a free username. The main disavantage is that you need a client that specifically supports SASL anonymous.

SASL anonymous and anonymous login are mainly intended to provide easy access Multi-Users Chat (MUC) rooms.

Configuration

This section describes how to configure anonymous access to ejabberd from ejabberd.cfg file.

The configuration of the anonymous mode can be done with three host_config parameters:

  • auth_method: This value is used for defining the authentication method: internal, odbc, ldap, external). You now have a special extra option to enable anonymous mode: anonymous.
  • allow_multiple_connections: This option can be either true or false and is only used when the anonymous mode is enabled. Setting it to true means that the same username will be able to be taken several time in anonymous login mode if different resource are used to connect. This option is only useful in very special cases. It defaults to false.
  • anonymous_protocol: This option can take three values: sasl_anon, login_anon or both. sasl_anon means that SASL anonymous mode is enabled. login_anon means that anonymous login mode is enabled. both means that SASL anonymous and login anonymous are enabled.

Anonymous login

In this scenario, we will configure two Jabber domains. The first domain, _private_, will support standard authenticated login only. The second domain, _public_, will support anonymous login only.

  1. You need to tell ejabberd that you will use two virtual hosts on the server:
    {hosts, ["private.example.org", "public.example.org"]}.
    
  2. You then need to define the global authentification method that you would like to use. The default is to authenticate against the internal ejabberd database:
    {auth_method, internal}.
    
  3. Then, you can override the host_config options for host that have to use anonymous login:
    {host_config, "public.example.org", [{auth_method, anonymous},
                                         {anonymous_protocol, login_anon}]}.
    
  4. Start ejabberd
  5. You can now connect with any login/password on public.example.org. You cannot do the same on private.example.org, where only valid user/password can login.

Authenticated login and anonymous login

You can mix both authenticated login and anonymous login on the same virtual host. In this scenario, we will configure two Jabber domains. The first domain, _private.example.org_, will support standard authenticated login only. The second domain, _public.example.org_, will support anonymous login and authenticated login.

  1. You need to tell ejabberd that you will use two virtual hosts on the server:
    {hosts, ["private.example.org", "public.example.org"]}.
    
  2. You then need to define the global authentification method that you would like to use. The default is to authenticate against the internal ejabberd database:
    {auth_method, internal}.
    
  3. Then, you can override the host_config options for host that have to use anonymous login and internal authentication:
    {host_config, "public.example.org", [{auth_method, [anonymous,internal]},
                                         {anonymous_protocol, login_anon}]}.
    
  4. Start ejabberd
  5. You can now connect with any login/password on public.example.org. You can register users on public.example.org. You cannot login with any password with the login that have been registered. You cannot do the same on private.example.org, where only valid user/password can login.

    You cannot register a new user when the login is already taken by an anonymously logged user.

SASL anonymous

SASL anonymous can be enabled by adding following the following steps. In this scenario, we will configure two Jabber domains. The first domain, _private.example.org_, will support standard authenticated login only. The second domain, _public.example.org_, will support SASL anonymous login only.

  1. You need to tell ejabberd that you will use two virtual hosts on the server:
    {hosts, ["private.example.org", "public.example.org"]}.
    
  2. You then need to define the global authentification method that you would like to use. The default is to authenticate against the internal ejabberd database:
    {auth_method, internal}.
    
  3. Then, you can override the host_config options for host that have to use SASL anonymous:
    {host_config, "public.example.org", [{auth_method, [anonymous]},
                                         {anonymous_protocol, sasl_anon}]}.
    
  4. Start ejabberd
  5. You can now connect with SASL anonymous on public.example.org. You cannot do the same on private.example.org, where only valid user/password can login.

    Note that you can enable internal login at the same time, by using two auth_method:
    {auth_method, [anonymous,internal]}
    . See section Authenticated login and anonymous login to find an usage example.

    Few clients do currently support SASL anonymous. To test this feature, you can follow the XML stream scenario in section Protocol:SASL Anonymoun

SASL anonymous and anonymous login

You can enable both anonymous login and SASL anonymous on the same virtual host, to support several kind of authentication mechanism. This can be done through the following steps. In this scenario, we will configure two Jabber domains. The first domain, _private.example.org_, will support standard authenticated login only. The second domain, _public.example.org_, will support SASL anonymous and anonymous login. No registered account can be used used on the public domain.

  1. You need to tell ejabberd that you will use two virtual hosts on the server:
    {hosts, ["private.example.org", "public.example.org"]}.
    
  2. You then need to define the global authentification method that you would like to use. The default is to authenticate against the internal ejabberd database:
    {auth_method, internal}.
    
  3. Then, you can override the host_config options for host that have to use both SASL anonymous and anonymous login:
    {host_config, "public.example.org", [{auth_method, [anonymous]},
                                         {anonymous_protocol, both}]}.
    
  4. Start ejabberd
  5. You can now connect with any login/password on public.example.org. You can register users on public.example.org. You cannot login with any password with the login that have been registered. You cannot do the same on private.example.org, where only valid user/password can login.

Protocol: How to use those features in your Jabber client ?

Anonymous login

Anonymous login can be used with non-sasl authentication mode. You have in this case to choose the username your anonymous authentication will use. On anonymous login enabled hosts, you can use any password to connect with the username you would like to use. Any password will be accepted, but your login will be rejected if the user exists or is already logged in.

Password authentication

Here is an example login anonymous session, using password authentication. It describes a standard authentication approach, except that the user used does not exist, but the host is using anonymous login, and as such has accepted the login:

  1. Client initiates stream to server.
    Example 1. Stream initiation
    <stream:stream
             xmlns:stream=3D'http://etherx.jabber.org/streams'
             xmlns=3D'jabber:client'
             to=3D'example.com'>
    
  2. Server replies with stream header.
    Example 2. Stream header reply
    <stream:stream
            xmlns:stream=3D'http://etherx.jabber.org/streams'
            xmlns=3D'jabber:client' to=3D'example.com'>
    
  3. Client requests authentication methods.
    Example 3. Authentication methods request
    <iq id=3D'0' type=3D'get'>
      <query xmlns=3D'jabber:iq:auth'>
        <username>test</username>
      </query>
    </iq>
    
  4. Server sends back authentication methods.requests authentication methods.
    Example 4. Authentication methods list
    <iq type=3D'result' id=3D'0'>
      <query xmlns=3D'jabber:iq:auth'>
        <username>test</username>
        <password/>
        <digest/>
        <resource/>
      </query>
    </iq>
    
  5. Client sends password authentication. The user 'test' does not exist on the server. The catuel password does not matter.
    Example 5. Anonymous login
    <iq id=3D'1' type=3D'set'>
      <query xmlns=3D'jabber:iq:auth'>
        <username>test</username>
        <password>anything</password>
        <resource>MyResource</resource>
      </query>
    </iq>
    
  6. Server accepts authentication.
    Example 6. Authentication result
    <iq type=3D'result' id=3D'1'/>
    

Digest authentication

Here is a sample anonymous login session, using digest authentication:

  1. Client initiates stream to server.
    Example 1. Stream initiation
    <stream:stream
             xmlns:stream=3D'http://etherx.jabber.org/streams'
             xmlns=3D'jabber:client'
             to=3D'example.com'>
    
  2. Server replies with stream header.
    Example 2. Stream header reply
    <stream:stream
            xmlns:stream=3D'http://etherx.jabber.org/streams'
            xmlns=3D'jabber:client' to=3D'example.com'>
    
  3. Client requests authentication methods.
    Example 3. Authentication methods request
    <iq id=3D'0' type=3D'get'>
      <query xmlns=3D'jabber:iq:auth'>
        <username>test</username>
      </query>
    </iq>
    
  4. Server sends back authentication methods.requests authentication methods.
    Example 4. Authentication methods list
    <iq type=3D'result' id=3D'0'>
      <query xmlns=3D'jabber:iq:auth'>
        <username>test</username>
        <password/>
        <digest/>
        <resource/>
      </query>
    </iq>
    
  5. Client sends digest authentication. The user 'test' does not exist on the server. The actual digest password does not matter.
    Example 5. Anonymous login
    <iq id=3D'1' type=3D'set'>
      <query xmlns=3D'jabber:iq:auth'>
        <username>test</username>
        <digest>1fa8943c3a8f5b049b91c534c6b69df57e86fae9</digest>
        <resource>MyResource</resource>
      </query>
    </iq>
    
  6. Server accepts authentication.
    Example 6. Authentication result
    <iq type=3D'result' id=3D'1'/>
    

SASL anonymous

Here is a sample SASL anonymous session, mostly inspired by XEP-0175: Best Practices for Use of SASL ANONYMOUS.

  1. Client initiates stream to server.
    Example 1. Stream initiation
    <stream:stream
            xmlns:stream=3D'http://etherx.jabber.org/streams'
            xmlns=3D'jabber:client'
            to=3D'example.com'
            version=3D'1.0'>
    
  2. Server replies with stream header.
    Example 2. Stream header reply
    <stream:stream
            xmlns:stream=3D'http://etherx.jabber.org/streams'
            xmlns=3D'jabber:client'
            id=3D'c2s_234'
            from=3D'example.com'
            version=3D'1.0'>
    
  3. Server advertises stream features.
    Example 3. Stream features advertisement
    <stream:features>
      <mechanisms xmlns=3D'urn:ietf:params:xml:ns:xmpp-sasl'>
        <mechanism>DIGEST-MD5<mechanism>
        <mechanism>ANONYMOUS<mechanism>
      </mechanisms>
    </stream:features>
    
  4. Client requests SASL ANONYMOUS mechanism.
    Example 4. Requesting SASL ANONYMOUS
    <auth xmlns=3D'urn:ietf:params:xml:ns:xmpp-sasl' mechanism=3D'ANONYMOUS'/>
    
  5. Server sends <success/>.
    Example 5. Sending success
    <success xmlns=3D'urn:ietf:params:xml:ns:xmpp-sasl'/>
    
  6. Client opens new stream.
    Example 6. Initiating a new stream
    <stream:stream
            xmlns:stream=3D'http://etherx.jabber.org/streams'
            xmlns=3D'jabber:client'
            to=3D'example.com'
            version=3D'1.0'>
    
  7. Server tells client that resource binding is required.
    Example 7. Stream header reply with features
    <stream:stream
            xmlns:stream=3D'http://etherx.jabber.org/streams'
            xmlns=3D'jabber:client'
            id=3D'c2s_345'
            from=3D'example.com'
            version=3D'1.0'>
    <stream:features>
      <bind xmlns=3D'urn:ietf:params:xml:ns:xmpp-bind'/>
    </stream:features>
    
  8. Client requests that server create a resource for it.
    Example 8. Requesting resource creation
    <iq type=3D'set' id=3D'bind_1'>
      <bind xmlns=3D'urn:ietf:params:xml:ns:xmpp-bind'/>
    </iq>
    
  9. Server replies with full JID.
    Example 9. Server informs client of full JID
    <iq type=3D'result' id=3D'bind_1'>
      <bind xmlns=3D'urn:ietf:params:xml:ns:xmpp-bind'>
        <jid>somenode@example.com/someresource</jid>
      </bind>
    </iq>
    
  10. Client opens session.
    Example 10. Opening session
    <iq type=3D'set' id=3D'session_1'>
      <session xmlns=3D'urn:ietf:params:xml:ns:xmpp-session'/>
    </iq>
    
  11. Server acknowledges session opening.
    Example 11. Session opening ack
    <iq type=3D'result' id=3D'session_1'>
      <session xmlns=3D'urn:ietf:params:xml:ns:xmpp-session'/>
    </iq>
    

After this sequence, you are connected on the ejabberd server and can start pushing usual XMPP packets.

Syndicate content