*
* licence: CECILL http://www.cecill.info/licences/Licence_CeCILL_V2.1-fr.html
* license: CECILL http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html
* FRENCH | ENGLISH
* ------------------------------------+--------------------------------------
* Ce logiciel est un programme | This software is a computer program
* informatique servant à générer un | whose purpose is to generate an
* fichier d'autoconfiguration pour | XML autoconfiguration file for
* thunderbird en interrogeant un | thunderbird by querying an LDAP
* annuaire LDAP. | directory.
* |
* Ce logiciel est régi par la licence | This software is governed by the
* CeCILL soumise au droit français et | CeCILL license under French law and
* respectant les principes de | abiding by the rules of
* diffusion des logiciels libres. | distribution of free software. You
* Vous pouvez utiliser, modifier | can use, modify and/ or
* et/ou redistribuer ce programme | redistribute the software under the
* sous les conditions de la licence | terms of the CeCILL license as
* CeCILL telle que diffusée par le | circulated by CEA, CNRS and INRIA
* CEA, le CNRS et l'INRIA sur le site | at the following URL
* "http://www.cecill.info/". | "http://www.cecill.info/".
* |
* En contrepartie de l'accessibilité | As a counterpart to the access to
* au code source et des droits de | the source code and rights to
* copie, de modification et de | copy, modify and redistribute
* redistribution accordés par cette | granted by the license, users are
* licence, il n'est offert aux | provided only with a limited
* utilisateurs qu'une garantie | warranty and the software's
* limitée. Pour les mêmes raisons, | author, the holder of the economic
* seule une responsabilité restreinte | rights, and the successive
* pèse sur l'auteur du programme, le | licensors have only limited
* titulaire des droits patrimoniaux | liability.
* et les concédants successifs. |
* |
* A cet égard l'attention de | In this respect, the user's
* l'utilisateur est attirée sur les | attention is drawn to the risks
* risques associés au chargement, à | associated with loading, using,
* l'utilisation, à la modification | modifying and/or developing or
* et/ou au développement et à la | reproducing the software by the
* reproduction du logiciel par | user in light of its specific
* l'utilisateur étant donné sa | status of free software, that may
* spécificité de logiciel libre, qui | mean that it is complicated to
* peut le rendre complexe à manipuler | manipulate, and that also
* et qui le réserve donc à des | therefore means that it is
* développeurs et des professionnels | reserved for developers and
* avertis possédant des | experienced professionals having
* connaissances informatiques | in-depth computer knowledge. Users
* approfondies. Les utilisateurs | are therefore encouraged to load
* sont donc invités à charger et | and test the software's suitability
* tester l'adéquation du logiciel à | as regards their requirements in
* leurs besoins dans des conditions | conditions enabling the security of
* permettant d'assurer la sécurité de | their systems and/or data to be
* leurs systèmes et ou de leurs | ensured and, more generally, to
* données et, plus généralement, à | use and operate it in the same
* l'utiliser et l'exploiter dans les | conditions as regards security.
* mêmes conditions de sécurité. |
* |
* Le fait que vous puissiez accéder à | The fact that you are presently
* cet en-tête signifie que vous avez | reading this means that you have
* pris connaissance de la licence | had knowledge of the CeCILL license
* CeCILL, et que vous en avez accepté | and that you accept its terms.
* les termes. |
*/
$debug=false;
function meurs($s) {
global $debug;
if($debug) die($s); else die();
}
/*
* Define an array with our domains, and their respective imap and smtp servers
* Must be all lower case.
*/
$server=array(
'example.com' => array( 'imap' => 'imap.example.com',
'smtp' => 'submission.example.com',
'displayname' => 'La compagnie de France',
'displayshort' => 'compagnie',
// userhelpdoc is optional
'userhelpdoc' => 'https://example.com/docs/email/thunderbird',
),
// 'more.domains' => array( 'imap' etc...),
);
/*
* Check params, die if params are not what we expect
*/
if( ! isset( $_GET['emailaddress'] ))
meurs('No email address provided');
/*
* just make sure that we received less than 321 bytes, see RFC.
*/
if( 320 < strlen( $_GET['emailaddress'] ))
meurs('Email address too long');
$candidate=trim($_GET['emailaddress']);
list($local,$domain)=explode('@', $candidate, 2);
$domain=strtolower($domain);
$domaindc=str_replace('.', ',dc=', $domain);
/*
* Check domain is known.
*/
if( ! array_key_exists( $domain, $server ) )
meurs('Unknown domain : '.$domain);
/*
* check local part corresponds to OUR likings. Well... this is a minimalist
* test. Just make sure we only have only ASCII chars we use for email at our
* site and that the length is less than 65, as per RFC 3696.
*/
if( ! preg_match( '/^[a-z][-_.a-z0-9]{0,63}$/i', $local ) )
meurs('Weird chars in email or local part too long');
/*
* Now that we are certain that emailaddress
* - is shorter than 321 bytes
* - has a known domain part
* - has only valid chars in its local part
* - has a localpart shorter than 65 chars
* let's work !
*/
$email=$_GET['emailaddress'];
$fmtnodoc=<<<'EOFMT'
%s
%s
%s
%s
993
SSL
password-cleartext
%s
%s
587
STARTTLS
password-cleartext
%s
EOFMT;
$fmtdoc=<<<'EOFMT'
%s
%s
%s
%s
993
SSL
password-cleartext
%s
%s
587
STARTTLS
password-cleartext
%s
Thunderbird mail settings
Pramètres de courriel pour Thunderbird
EOFMT;
require_once 'Net/LDAP2.php';
$LDAPconfig = array (
'host' => 'annuaire.example.com',
'port' => 389,
'version' => 3,
'starttls' => false,
// 'binddn' => 'cn=admin,ou=people,dc=example.dc=com',
// 'bindpw' => 'password',
'basedn' => 'ou=people,dc='.$domaindc, // default basedn for queries
'options' => array(),
'filter' => '(objectclass=*)', //default search filter
'scope' => 'one', // default scope for search
);
// Connecting using the configuration:
$ldap = Net_LDAP2::connect($LDAPconfig);
// Testing for connection error
if (PEAR::isError($ldap)) {
meurs('Could not connect to LDAP-server: '.$ldap->getMessage());
}
$queryparam=array(
'scope' => 'one',
'sizelimit' => 0, // Number of entries returned at maximum
'timelimit' => 10, // Seconds to spent for searching
'attrsonly' => false, // If true, only attribute names are returned
'attributes' => array ( 'uid' ), // Array of attribute names, which the entry should contain.
);
$search = $ldap->search( null, "(mail=$email)", $queryparam );
// Test for search errors:
if (PEAR::isError($search)) {
meurs($search->getMessage() . "\n");
}
// if not exactly one entry, we can't tell user...
if( $search->count() !== 1 ) {
meurs('no answer or more than one answer. count : '.$search->count() );
}
$entry=$search->shiftEntry();
$uid = $entry->getValue('uid', 'single');
if(false === $uid) {
meurs('Weird ! Answer has no "uid" attribute');
}
header( 'Content-type: text/xml' );
if(array_key_exists('userhelpdoc', $server[$domain]) and ! empty($server[$domain]['userhelpdoc'])) {
printf($fmtdoc,
$domain,
$domain,
$server[$domain]['displayname'],
$server[$domain]['displayshort'],
$server[$domain]['imap'],
$uid,
$server[$domain]['smtp'],
$uid,
$server[$domain]['userhelpdoc']
);
}
else {
printf($fmtnodoc,
$domain,
$domain,
$server[$domain]['displayname'],
$server[$domain]['displayshort'],
$server[$domain]['imap'],
$uid,
$server[$domain]['smtp'],
$uid
);
}
// vim: se ts=4 sw=4 et ai mouse= :
==== Exemple de configuration apache ====
[automx]
provider = mondomaine.fr
domains = mondomaine.fr, subdomaine.mondomaine.fr
#debug = yes
logfile = /tmp/automx.log
# Protect against DoS
memcache = 127.0.0.1:11211
memcache_ttl = 600
client_error_limit = 5
rate_limit_exception_networks = 127.0.0.0/8, ::1/128
# The DEFAULT section is always merged into each other section. Each section
# can overwrite settings done here.
[DEFAULT]
account_type = email
account_name = mondomaine
account_name_short = mondomaine
[global]
action = settings
backend = ldap
host = ldap://ldap.mondomaine.fr
base = ou=people,dc=mondomaine,dc=fr
binddn = cn=comptemagique,ou=system,dc=mondomaine,dc=fr
bindpw = PASSWORD
result_attrs = mail, mailAlternateAddress, uid
scope = one
filter = (|(mailAlternateAddress=%s)(mail=%s))
pop = no
imap = yes
imap_server = imaps.mondomaine.fr
imap_port = 993
imap_encryption = ssl
imap_auth = plaintext
imap_refresh_ttl = 6
imap_auth_identity = ${uid}
smtp = yes
smtp_server = smtps.mondomaine.fr
smtp_port = 465
smtp_encryption = ssl
smtp_auth = plaintext
smtp_refresh_ttl = 6
smtp_auth_identity = ${uid}
smtp_default = yes
smtp_author = ${mail}
==== Configuration apache ====
Et une partie de la config Apache
ServerAdmin email-admin@MONDOMAINE.fr
CustomLog /var/log/apache2/access.log combined
ErrorLog /var/log/apache2/error.log
# Securite de base
ServerSignature Off
ServerTokens Prod
Require all denied
Require all denied
AllowOverride None
Options -Indexes
# Bloquer les acces directs sur adresse IP
ServerName a.b.c.d
ServerAlias a:b:cd::e
Redirect 403 /
ErrorDocument 403 "Forbidden
Direct IP access not
allowed.
"
# Redirection => https (Mobiles => formulaire autoconf)
ServerName mail-autoconf.MONDOMAINE.fr
Redirect "/" "https://mail-autoconf.MONDOMAINE.fr/";
# Redirection => https (Thunderbird personnels)
ServerName autoconfig.MONDOMAINE.fr
Redirect "/" "https://autoconfig.MONDOMAINE.fr/";
# Redirection => https (Thunderbird subdomaine)
ServerName autoconfig.subdomaine.MONDOMAINE.fr
Redirect "/" "https://autoconfig.subdomaine.MONDOMAINE.fr/";
# Thunderbird se connecter en HTTP, mais peut suivre une redirection HTTPS
# Les clients Microsoft se connectent toujours en HTTPS
#SSLStaplingCache shmcb:${APACHE_RUN_DIR}/ssl_stapling(128000)
ServerName mail-autoconf.MONDOMAINE.fr
ServerAlias autodiscover.MONDOMAINE.fr
ServerAlias autoconfig.MONDOMAINE.fr
ServerAlias autodiscover.subdomaine.MONDOMAINE.fr
ServerAlias autoconfig.subdomaine.MONDOMAINE.fr
WSGIScriptAliasMatch (?i)^/.+/config-v1.1.xml /usr/local/lib/automx/automx_wsgi.py
WSGIScriptAliasMatch (?i)^/.+/autodiscover.xml /usr/local/lib/automx/automx_wsgi.py
WSGIScriptAliasMatch (?i)^/.+/Autodiscover.xml /usr/local/lib/automx/automx_wsgi.py
WSGIScriptAliasMatch (?i)^/mobileconfig /usr/local/lib/automx/automx_wsgi.py
Require all granted
DocumentRoot /var/www/automx
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
SSLEngine On
SSLCertificateKeyFile /etc/apache2/ssl/mail-autoconf.MONDOMAINE.fr.key
SSLCertificateFile /etc/apache2/ssl/mail-autoconf.MONDOMAINE.fr.crt
SSLCertificateChainFile /etc/apache2/ssl/DigiCertCA.crt
SSLProtocol ALL -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
SSLCompression Off
#SSLUseStapling On
#SSLStaplingResponderTimeout 5
#SSLStaplingReturnResponderErrors off
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
===== autoconfig.pl =====
Une autre implémentation en perl, à installer en //cgibin//, proposée
par < sebastien • pose à ac-reunion • fr >.
Il faut adapter le nom du serveur dans le code, la base de recherche
et bien sûr le filtre, sans oublier les valeurs du document XML.
Et puis c'est tout. Simple, direct,
#!/usr/bin/perl -W
use strict;
use Net::LDAP;
#print "Content-type: text/html\n\n";
my ($mail,$uid);
if (defined $ENV{QUERY_STRING}) {
my @query = split(/=/, $ENV{QUERY_STRING});
if (defined $query[1]) {
$query[1] =~ s/%40/@/;
$mail = $query[1];
my $ldap = Net::LDAP->new( 'ldapserveur.mondomaine.fr' ) or die "$@";
my $mesg = $ldap->bind ;
$mesg = $ldap->search( base => "ou=personnels dc=mondomaine, dc=fr",
filter => "(|(mail=$mail)(mailalternateaddress=$mail)(mailequivalentaddress=$mail))",
attrs => ['uid']
);
if ($mesg->code) {
$uid = $mesg->error;
}
else {
if (defined $mesg->entry) {
$uid = $mesg->entry->get_value('uid');
}
else {
$uid='Verifiez votre adresse email';
}
}
$mesg = $ldap->unbind;
}
else { $uid = 'Verifiez votre adresse email'; }
}
print "Content-type: application/xml\n\n";
print '';
print '';
print ' ';
print ' mondomaine.fr ';
print ' Messagerie de Mon Domaine ';
print ' Mondomaine ';
print ' ';
print ' imaps.mondomaine.fr ';
print ' 993 ';
print ' SSL ';
print " $uid ";
print ' password-cleartext ';
print ' ';
print ' ';
print ' smtps.mondomaine.fr ';
print ' 465 ';
print ' SSL ';
print " $uid ";
print ' password-cleartext ';
print ' true ';
print ' true ';
print ' ';
print ' ';
print ' ';
----