Sympa Logo
Translations of this page:

Authorization scenarios

An authorization scenario is a small configuration language to describe who can perform an operation and which authentication method is requested for it. An authorization scenario is an ordered set of rules. The goal is to provide a simple and flexible way to configure authorization and required authentication method for each operation.

The function to evaluate scenario is described in section internals.

Location of scenario file

List parameters controlling the behavior of commands are linked to different authorization scenarios. For example: the send private parameter is related to the send.private scenario.

There are four possible locations for an authorization scenario. When Sympa seeks to apply an authorization scenario:

  • it first looks in the related list directory /home/sympa/list_data/<list>/scenari or /home/sympa/my.domain.org/list_data/<list>/scenari if you use virtual hosts
  • If it does not find the file there, it scans the current robot configuration directory /home/sympa/etc/my.domain.org/scenari,
  • then the site's configuration directory /home/sympa/etc/scenari,
  • and finally /home/sympa/default/scenari, which is the directory installed by the Makefile.

When customizing scenario for your own site, robot or list, don't modify .../sympa/bin/scenari content or the next Sympa update will overwrite it (you must never modify anything in .../sympa/bin/ unless you are patching Sympa). You can modify Sympa behavior if you are creating a new scenario with the same name as one of the scenario already included in the distribution but with a location related to the target site, robot or list. You can also add a new scenario ; it will automatically add an accepted value for the related parameter.

When modifying a existing scenario you need to restart Sympa or touch list config file before Sympa use it.

Scenario structure

Basically, a scenario file is composed of a title on the first line and a set of rules on the following lines.

Scenario title

The first line of a scenario file can contain its title. This is the text that will later appear in the drop-down menu of your administration web interface. This title can be just plain text:

title Restricted to subscribers

It can also be set to be internationalized:

title.gettext Restricted to subscribers

That way, the character string following title.gettext can be handled by Sympa internationalization process.

Rules overview

Each authorization scenario rule contains:

  • a condition: the condition is evaluated by Sympa. It can use variables such as sender for the sender's email, list for the list name, etc.
  • an authentication method. The authentication method can be smtp, md5 or smime. The rule is applied by Sympa if both the condition and authentication method match the runtime context.
    • smtp is used if Sympa uses the SMTP From: header ,
    • md5 is used if a unique MD5 key as been returned by the requestor to validate the message,
    • smime is used for signed messages (see configuration to recognize S/MIME signatures);
  • a returned atomic action that will be executed by Sympa if the rule matches.

Example:

  del.auth

  title.fr suppression r\'eserv\'ee au propri\'etaire avec authentification
  title.en-US deletion performed only by list owners, need authentication
  title.es eliminacin reservada slo para el propietario, necesita autentificacin

    is_owner([listname],[sender])  smtp       -> request_auth
    is_listmaster([sender])        smtp       -> request_auth
    true()                         md5,smime  -> do_it

Rules definition

An authorization scenario consists of rules, evaluated in order beginning with the first.

Conditions

custom_vars allows you to introduce custom parameters in your scenario.

verify_netmask allows the user to configure their local network to only be accessible to those that are members of it. For more information refer to intranet restrictions

perl_regexp can contain the string [host] (interpreted at run time as the list or robot domain). The variable notation [msg_header-><smtp_key_word>] is interpreted as the SMTP header value only when evaluating the authorization scenario for sending messages. It can be used, for example, to require editor validation for multipart messages. [msg_part->type] and [msg_part->body] are the MIME part content-types and bodies; the body is available for MIME parts in text/xxx format only.

Refer to Tasks for date format definition

A bunch of authorization scenarios are provided with the Sympa distribution; they provide a large set of configuration that allows the creation of lists for most purposes. But you will probably create authorization scenarios for your own needs. In this case, do not forget to restart Sympa and WWSympa, because authorization scenarios are not reloaded dynamically.

These standard authorization scenarios are located in the /home/sympa/bin/etc/scenari/ directory. Default scenarios are named <command>.default.

You may also define and name your own authorization scenarios. Store them in the /home/sympa/etc/scenari directory. They will not be overwritten by newer Sympa releases. Scenarios can also be defined for a particular virtual host (using directory /home/sympa/etc/<robot>/scenari) or for a list (/home/sympa/list_data/<robot>/<list>/scenari ). Sympa will not dynamically detect that a list configuration should be reloaded after a scenario has been changed on disk.

Example: copy the previous scenario to scenari/subscribe.rennes1:

  equal([sender], 'userxxx@univ-rennes1.fr') smtp,smime -> reject
  match([sender], /univ-rennes1\.fr$/) smtp,smime -> do_it
  true()                               smtp,smime -> owner

You may now refer to this authorization scenario in any list configuration file, for example:

  subscribe rennes1

Authentification methods

Yous can specify three different authentication methods to base your rules on: smtp, smime and md5.

these methods take a different meaning if you consider them in a web or mail context.

Indeed if you consider, for example, the scenario send: it will be evaluated when people try to send a message to a list.

  • If the message is sent through the web interface, Sympa will verify the identity of the sender based on its web authentication informations (login/password, certificate, etc.)
  • If it is sent by the mail client, the authentication is based on whatever authentication method the user's email client associated with the SMTP message (S/MIME signature, From field, etc.).

But the same scenario file will be used in both cases. That means that the same authentication method will be used, whichever context we're in. It is consequently important to understand what interpretation to give to each authentication method according to the context.

Here is a description of what is evaluated to authenticate the user depending of the context: web or mail.

Method Mail context Web context
smtp the “From:” field of the message Nothing - unused in web context
smime the S/MIME X509 signature of the email An X509 certificate installed in the user's browser
md5 the MD5 hash in the subject of the message the authentication informations provided to Sympa (login/password)
dkim the DKIM signature of the message Nothing - unused in web context

Note that md5 will be used, in a mail context, when users answer to an authentication request, or when editors moderate a message by replying to a moderation request mail.

In most cases, smtp or dkim will be used for mails, and md5 for the web.

Actions

The difference between editor and editorkey is that, with editor, the message is simply forwarded to moderators, who can then forward it to the list if they like. editorkey assigns a key to the message and sends it to moderators together with the message. So moderators can just send back the key to distribute the message. Please note that moderation from the web interface is only possible when using editorkey, because otherwise there is no copy of the message saved on the server.

The quiet can be part of the scenario action result. When using this option, no notification is sent to the message sender. For example, if a scenario rule is applied and result in editorkey,quiet the sender of the message will not receive the automatic information message telling him that his message has been forwarded to the list editor. This is an important issue to prevent backscatter messages. backscatter messages are messages you receive as an automatic answer to a message you never sent. The following web page give you more details :

Sympa version 6.0 and later of Sympa provide a better mechanism to prevent backscatter. See https://www.sympa.org/manual/antispam

Formal specification of the rules

Rules are defined as follows:

  <rule> ::= <condition> <auth_list> -> <action>

  <condition> ::= [!] <condition
                  | true ()
                  | equal (<var>, <var>)
                  | less_than (<var>, <var>)
                  | match (<var>, /perl_regexp/)
          | search (<named_filter_file>)
                  | is_subscriber (<listname>, <var>)
                  | is_owner (<listname>, <var>)
                  | is_editor (<listname>, <var>)
                  | is_listmaster (<var>)
                  | older (<date>, <date>)    # true if first date is anterior to the second date
                  | newer (<date>, <date>)    # true if first date is posterior to the second date
                  | CustomCondition::<package_name> (<var>*)


  <var> ::= [email] | [sender] | [user-><user_key_word>] | [previous_email]
                    | [user_attributes-><user_attributes_keyword>]
             | [subscriber-><subscriber_key_word>] | [list-><list_key_word>] | [env-><env_var>]
            | [conf-><conf_key_word>] | [msg_header-><smtp_key_word>] | [msg_body]
             | [msg_part->type] | [msg_part->body] | [msg_encrypted] | [is_bcc] | [current_date]
            | [topic-auto] | [topic-sender,] | [topic-editor] | [topic] | [topic-needed]
            | [custom_vars-><custom_var_name>] | <string>

  [is_bcc] ::= set to 1 if the list is neither in To: nor Cc:

  [sender] ::= email address of the current user (used on web or mail interface). Default value is 'nobody'

  [previous_email] ::= old email when changing subscription email in preference page.

  [msg_encrypted] ::= set to 'smime' if the message was S/MIME encrypted

  [topic-auto] ::= topic of the message if it has been automatically tagged

  [topic-sender] ::= topic of the message if it has been tagged by sender

  [topic-editor] ::= topic of the message if it has been tagged by editor

  [topic]  ::= topic of the message (this variable has a value if any of the previous [topic-*] variable has a value.

  [topic-needed] ::= the message has not got any topic and message topic are required for the list

  /perl_regexp/ ::= a perl regular expression. Don't forget to escape special characters (^, $, \{, \(, ...)
  Check http://perldoc.perl.org/perlre.html for regular expression syntax.

  <date> ::= '<date_element> [ +|- <date_element>]'

  <date_element> ::= <epoch_date> | <var> | <date_expr>

  <epoch_date> ::= <integer>

  <date_expr> ::= <integer>y<integer>m<integer>d<integer>h<integer>min<integer>sec

  <custom_var_name> ::= name of the custom parameter you want to use.

  <listname> ::= [listname] | '<listname_string>' | '<listname_string>@>domain_string>'

  <auth_list> ::= <auth>,<auth_list> | <auth>

  <auth> ::= smtp|md5|smime

  <action> ::=   do_it [,notify]
               | do_it [,quiet]
           | reject(reason=<reason_key>) [,quiet]
           | reject(tt2=<tpl_name>) [,quiet]
               | request_auth
               | owner
           | editor
           | editorkey[,quiet]
           | listmaster

  <reason_key> ::= match a key in mail_tt2/authorization_reject.tt2 template corresponding to
                   an information message about the reason of the reject of the user

  notify ::= sends a notification to list owner

  <tpl_name> ::= corresponding template (<tpl_name>.tt2) is send to the sender

  <user_key_word> ::= email | gecos | lang | password | cookie_delay_user
                  | <additional_user_fields>

  <user_attributes_key_word> ::= one of the user attributes provided by the SSO system via environment variables. The [user_attributes] structure is available only if user authenticated with a generic_sso.

  <subscriber_key_word> ::= email | gecos | bounce | reception
                        | visibility | date | update_date
                | <additional_subscriber_fields>

  <list_key_word> ::= name | host | address | lang | max_size | priority | reply_to |
              status | subject | account | total

  <env_var> ::= name of environment variable CGI of HTTP server sets.  Note that it is case-sensitive.

  <conf_key_word> ::= domain | email | listmaster | default_list_priority |
                sympa_priority | request_priority | lang | max_size

  <named_filter_file> ::= filename ending with .ldap , .sql or .txt.

  <package_name> ::= name of a perl package in /etc/custom_conditions/ (small letters)

Named Filters

At the moment, Named Filters are only used in authorization scenarios. They enable to select a category of people who will be authorized or not to realize some actions.

As a consequence, you can grant privileges in a list to people belonging to an LDAP directory, an SQL database or a flat text file, thanks to an authorization scenario.

Note that only a subset of variables available in the scenario context are available here (including [sender] and [listname]).

LDAP Named Filters Definition

People are selected through an LDAP filter defined in a configuration file. This file must have the extension '.ldap'. It is stored in /home/sympa/etc/search_filters/.

You must give a few information in order to create a LDAP Named Filter:

  • host
    A list of host:port LDAP directories (replicates) entries.
  • suffix
    Defines the naming space covered by the search (optional, depending on the LDAP server).
  • filter
    Defines the LDAP search filter (RFC 2254 compliant). But you must absolutely take into account the first part of the filter which is: (mail_attribute = [sender]), as shown in the example. You will have to replace mail_attribute by the name of the attribute for the email. Sympa checks whether the user belongs to the category of people defined in the filter.
  • scope
    By default, the search is performed on the whole tree below the specified base object. This may be changed by specifying a scope:
    • base: search only the base object.
    • one: search the entries immediately below the base object.
    • sub: search the whole tree below the base object. This is the default option.
  • bind_dn
    If anonymous bind is not allowed on the LDAP server, a DN and password can be used.
  • bind_password
    This password is used, combined with the bind_dn above.

example.ldap: we want to select the teachers of mathematics in the University of Rennes 1 in France:

      host        ldap.univ-rennes1.fr:389,ldap2.univ-rennes1.fr:390
      suffix        dc=univ-rennes1.fr,dc=fr
      filter        (&(canonic_mail = [sender])(EmployeeType = prof)(subject = math))
      scope        sub

SQL Named Filters Definition

People are selected through an SQL filter defined in a configuration file. This file must have the extension '.sql'. It is stored in /home/sympa/etc/search_filters/.

To create an SQL Named Filter, you have to configure SQL host, database and options, the same way you did it for the main Sympa database in sympa.conf. Of course, you can use different database and options. Sympa will open a new Database connection to execute your statement.

Please refer to section Database related for a detailed explanation of each parameter.

Here, all database parameters have to be grouped in one sql_named_filter_query paragraph.

  • db_type
    Format: db_type mysql|SQLite|Pg|Oracle|Sybase; Database management system used. Mandatory and case sensitive.
  • db_host
    Database host name. Mandatory.
  • db_name
    Name of database to query. Mandatory.
  • statement
    Mandatory. The SQL statement to execute to verify authorization. This statement must returns 0 to refuse the action, or anything else to grant privileges. The SELECT COUNT(*)... statement is the perfect query for this parameter. The keyword in the SQL query will be replaced by the sender's email.
  • Optional parameters
    Please refer to main sympa.conf section for description.
    • db_user
    • db_password
    • db_options
    • db_env
    • db_port
    • db_timeout

example.sql: we want to select the teachers of mathematics in the University of Rennes 1 in France:

         sql_named_filter_query
         db_type         mysql
         db_name         people
         db_host         dbserver.rennes1.fr
         db_user         sympa
         db_passwd       pw_sympa_mysqluser
         statement       SELECT count(*) as c FROM users WHERE mail=[sender] AND EmployeeType='PROFESSOR' AND department='mathematics'

Search condition

The search condition is used in authorization scenarios.

The syntax of this rule is:

      search(example.ldap)      smtp,smime,md5    -> do_it
      search(blacklist.txt)     smtp,smime,md5    -> do_it

The variable used by search is the name of the LDAP configuration file or a txt matching enumeration.

Note that Sympa processes maintain a cache of processed search conditions to limit access to the LDAP directory or SQL server; each entry has a lifetime of one hour in the cache.

When using the '.txt' file extension, each line is used to try to match the sender email address. You can use the “*” character as a joker to replace any string.

Here is an example of such a file:

david.verdin@renater.fr
*salaun*

With such a file, the rule would be true for the following email addresses:

  • david.verdin@renater.fr
  • salaun@renater.fr
  • O.salaun@renater.fr

It would be false for the following email addresses :

  • verdin@renater.fr
  • olivier.sala@renater.fr

This feature is used by the blacklist implicit scenario rule (see Blacklist).

The method of authentication does not change.

Scenario inclusion

Scenarios can also contain includes:

        include commonreject
        match([sender], /cru\.fr$/)          smtp,smime -> do_it
      true()                               smtp,smime -> owner

In this case, Sympa applies recursively the scenario named include.commonreject before introducing the other rules. This possibility was introduced in order to facilitate the administration of common rules.

Scenario implicit inclusion

You can define a set of common scenario rules, used by all lists. include.<action>.header is automatically added to evaluated scenarios. Note that you will need to restart Sympa processes to force reloading of list config files.

Blacklist implicit rule

For each service listed in parameter use_blacklist (see use_blacklist), the following implicit scenario rule is added at the beginning of the scenario:

  search(blacklist.txt)  smtp,md5,pgp,smime -> reject,quiet

The goal is to block messages or other service requests from unwanted users. The blacklist can be defined for the robot or for the list. At the list level, the blacklist is to be managed by list owner or list editor via the web interface.

Custom Perl package conditions

You can use a Perl package of your own to evaluate a custom condition. It can be useful if you have very complex tasks to carry out to evaluate your condition (web services queries...). In this case, you should write a Perl module, place it in the CustomCondition namespace, with one verify fonction that has to return 1 to grant access, undef to warn of an error, or anything else to refuse the authorization.

This Perl module:

  • must be placed in a subdirectoy custom_conditions of the etc directory of your Sympa installation, or of a robot;
  • its filename must be lowercase;
  • must be placed in the CustomCondition namespace;
  • must contain one verify static fonction;
  • will receive all condition arguments as parameters.

For example, lets write the smallest custom condition that always returns 1.

/home/sympa/etc/custom_conditions/yes.pm :

        #!/usr/bin/perl
        package CustomCondition::yes;
        use strict;
        use Log; # optional : we log parameters
        sub verify {
          my @args = @_;
          foreach my $arg (@args) {
            do_log ('debug3', 'arg: ', $arg);
          }
          # I always say 'yes'
          return 1;
        }
        ## Packages must return true.
        1;

We can use this custom condition that way:

  CustomCondition::yes(,,)      smtp,smime,md5    -> do_it
  true()                               smtp,smime -> reject

Note that the ,, are optional, but it is the way you can pass information to your package. Our yes.pm will print the values in the logs.

Remember that the package name has to be lowercase, but the CustomCondition namespace is case sensitive. If your package returns undef, the sender will receive an 'internal error' mail. If it returns anything else but 1, the sender will receive a 'forbidden' error.

How to use message related variables within scenario rule conditions.

this tuto was also submitted by Thomas Berry, JPL, NASA. Thanks to him!

Scenario condition, message vars include:

[msg_body]
[msg_part->body]

When creating scenario rules that evaluate message content, two rules must be created when passing the contents of a message to a condition: one rule for plain text messages (msg_body) and a second rule for multi-part MIME messages (msg_part).

For example, I wrote a CustomCondition module that parses the URLs in a message and compares them with a list of approved URLs:

(send.url_eval)

title Moderated with URL verification
CustomCondition::urlreview([listname],[sender],[msg_body]) smtp,smime,md5 -> reject()
CustomCondition::urlreview([listname],[sender],[msg_part->body]) smtp,smime,md5 -> reject()
true() smtp,smime,md5 -> editorkey

The CustomCondition module returns undef if the message contents are not provided by the rule. If the message contents are multi-part MIME, then the [msg_body] passed by the first rule is undefined, and the CustomCondition module returns undef causing the scenario to move on to the next rule which passes the parts of the multi-part MIME message to the module.

As for the CustomCondition module, it was written to evaluate both plain text (SCALAR) and multi-part MIME (ARRAY reference) being passed to the condition:

(urlreview.pm)

package CustomCondition::urlreview;
...
sub verify {
   my $listname = shift or return;
   my $sender   = shift or return;
   my $body;
   foreach my $part (@_) {
      $body .= ref $part eq "ARRAY" ? join " ", @{$part} : $part;
   }
   return unless defined $body;
...
}
...
1;

this will work in included scenario if the include contains two rules: one with msg_body and with msg_part→body.

Hiding scenario files

Because Sympa is distributed with many default scenario files, you may want to hide some of them to list owners (to make list administration menus shorter and readable). To hide a scenario file, you should create an empty file with the :ignore suffix. Depending on where this file has been created, it will make it be ignored at either a global, robot or list level.

Example:

/home/sympa/etc/my.domain.org/scenari/send.intranetorprivate:ignore

The intranetorprivate send scenario will be hidden (on the web admin interface), at the my.domain.org robot level only.

manual/authorization-scenarios.txt · Last modified: 2016/03/30 17:16 by david.verdin@renater.fr

The Sympa software is provided by RENATER
Faq | News | Contact | Legal Notices