Condivisione di una rubrica
attraverso un server LDAP
usando
Mozilla Thunderbird
Versioni 1,0 e 1,5
English Translation English Translation English Translation

Introduzione

Ci sono molte guide che spiegano come collegarsi ad un server di rubriche già predisposto, in modo da potete condividere con qualcuno il proprio elenco di indirizzi. Questa guida parte da un differente punto di vista: ti spiegherà come condividere la tua rubrica fra parecchi computer. Per fare questo, ti serve capire come

Ciò ci porterà ad esplorare il mondo di LDAP (Lightweight Directory Access Protocol) ed LDIF (LDAP Data Interchange Format) e di altri oscuri acronimi. Come programma di posta elettronica d'esempio, userò Mozilla Thunderbird, un software aperto e gratuito per leggere le email.

Lungo il cammino, descriverò alcuni dei problemi che Parte Ingannevole ho incontrato e le soluzioni (o i trucchi) corrispondenti, così come alcune delle scelte scelta fatta che possono essere fatte, e le note nota.

Server LDAP

Ciò che poco sopra ho chiamato server di rubriche è in effetti un oggetto più generale (e complicato) che in gergo viene chiamato server LDAP. Per saperne di più su LDAP, prova a cercare su Google (dove otterrai quasi 7 milione di risultati), o visita l'eccellente guida Open Source Guide - LDAP for Rocket Scientists.

Per cominciare

Segui questi passaggi per installare il tuo server LDAP:

  1. Scarica un server LDAP da qualche parte (ad esempio da OpenLDAP, ecc.) e installalo sul computer che ti farà  da server. Non entrerò nei particolari di come procedere su questo punto poichè ci sono tanti server e sistemi su cui installare il tuo software. Gli utenti di Windows possono ottenere una versione eseguibile da Lucas Bergman.

  2. Scarica uno schema per la rubrica che intendi usare. Uno schema è una descrizione degli elementi della tua rubrica quali il nome, il cognome, il numero di telefono di casa, ecc., in una disposizione comprensibile dal server LDAP.

    Gli utenti di Thunderbird possono provare ad ottenere uno schema per la loro rubrica dalla lista degli schemi citati in Bugzilla. Come puoi vedere da quel collegamento, il loro schema per la rubrica è ancora in evoluzione.

    Ci sono molte scelte per lo schema, e tutte necessitano di essere adattate, in alcuni casi sul fronte dello schema stesso, in altri dopo l'inserimento dei dati nel server, in altri ancora su entrambi. Questo documento suppone che tu non abbia scelto nessuno degli schemi accennati in Bugzilla e che, invece, abbia preso (tra quelli disponibili) quello obsoleto (per TB 1,0) o una versione sperimentale (per TB 1.5). Salva quello che preferisci come mozillaAbPerson.schema nella stessa cartella dove si trovano gli altri "preconfezionati" forniti con il server LDAP.

  3. Modifica il file di configurazione del server (che quasi sempre è chiamato slapd.conf per includere le seguenti linee:

    includa core.schema
    include cosine.schema
    include inetorgperson.schema
    include mozillaAbPerson.schema

    Le suddette linee sono necessarie per definire lo schema su cui la rubrica si baserà. Ogni schema si basa sugli altri schemi in una struttura ad albero, ecco perchè servono tre schemi supplementari oltre a quello per Thunderbird. I primi tre schemi quasi certamente sono forniti di base con il server LDAP.

    Alcuni server LDAP hanno gli schemi in una cartella separata, quindi fai attenzione al nome del percorso prima del nome dello schema.

    Il file di configurazione include le linee che cominciano con suffix e rootdn. Sostituisci quelle righe con quanto segue:

    suffix "dc=YourDomain, dc=com"
    rootdn "cn=Manager, dc=YourDomain, dc=com"

    Il valore della riga suffix è ciò che distingue una base di dati da un'altra. Anche se non tornerò su questo argomento, bisogna precisare che il compito di un server LDAP è di gestire basi di dati multiple. Sono definite in slapd.conf dove ogni gruppo di voci che forma una base di dati comincia con la riga database seguita, ad esempio, da suffix, rootdn, rootpw, directory, index ecc.

    Il valore nel campo suffix è il suffisso della Base DN (vedi sotto). Il valore nel campo rootdn definisce invece l'utente con tutti i privilegi d'accesso (root) alla base di dati.

    Sostituisci la riga dc=YourDomain, dc=com con qualcosa di adatto alla tua situazione. Dettagli a parte, le voci suffix e rootdn possono assumere molte forme differenti, quindi se pensi di sapere quello che stai facendo, sentiti pure libero di cambiare le suddette righe, ma attenzione al fatto che nel seguito farò riferimento a quelle che ho riportato qui sopra: apporta le modifiche di conseguenza nel resto del documento. Usa un nome di tuo gradimento al posto di Manager.

    Probabilmente, la linea successiva nel file di configurazione specifica la parola d'accesso dell'amministratore:

    rootpw secret

    La suddetta linea dovrebbe essere cambiata, usando una password univoca, che consenta un accesso riservato al server LDAP. Tuttavia, la descrizione che segue fa uso della password di default, quindi non dimenticare di cambiarla in accordo con la tua scelta. Inoltre, leggi i commenti riportati nel file slapd.conf su come rendere pił sicura la password con una autenticazione forte.

  4. Avvia il server LDAP (solitamente scrivendo a riga di comando slapd).

Inizializzare il server

  1. Inizializza il suffix sul server come segue (un esempio di init.ldif il file può essere trasferito da qui):

    Crea un file di testo (diciamo init.ldif) che inizia con le righe seguenti:

    dn: dc=YourDomain, dc=com
    objectClass: top
    objectClass: organization
    objectClass: dcObject
    description: Descrizione del tuo dominio
    o: Qualcos'altro circa il tuo dominio
    dc: YourDomain

    Gli argomenti di dc= e dc: sono derivati dal suffix definito in slapd.conf.

    Usa un qualsiasi valore per i campi o: e description: — non saranno più usati in seguito.

    Nell'aggiungere altre sezioni supplementari (che cominciano con dn:) a questo file, assicurati di separarle tra loro con una riga vuota, in modo che il server LDAP possa gestirle a parte.

  2. Per separare le rubriche con la propria gerarchia, aggiungi al file init.ldif qualcosa di simile a quanto segue:

    dn: ou=AddressBooks, dc=YourDomain, dc=com
    objectClass: top
    objectClass: organizationalUnit
    description: Le Rubriche
    ou: AddressBooks

    Per definire rubriche multiple (due nell'esempio qui sotto), aggiungi le seguenti sezioni:

    dn: o=Home,ou=AddressBooks,dc=YourDomain, dc=com
    objectClass: top
    objectClass: organization
    descrizione: Casa dolce casa
    o: Home

    dn: o=Work, ou=AddressBooks, dc=YourDomain, dc=com
    objectClass: top
    objectClass: organization
    description: Lavoro dolce lavoro
    o: Work

    Le specifiche BaseDN per la rubrica sono

    o=Home,ou=AddressBooks,dc=YourDomain, dc=com e
    o=Work, ou=AddressBooks, dc=YourDomain, dc=com

    Usa questi DN per identificare a quale rubrica desideri accedere. Se vuoi recuperare gli indirizzi di tutte le rubriche a cui hai accesso, usa

    ou=AddressBooks,dc=YourDomain,dc=com

  3. Per separare gli utenti in gerarchie, aggiungi al file init.ldif quanto segue:

    dn: ou=Users, dc=YourDomain, dc=com
    objectClass: top
    objectClass: organizationalUnit
    description: Utenti che hanno accesso almeno ad un rubrica
    ou: Users

    Per aggiungere i diversi utenti, aggiungi altrettante sezioni come quella che segue:

    dn: cn=me, ou=Users, dc=YourDomain, dc=com
    objectClass: top
    objectClass: person
    cn: me
    Sn: Smith
    description: Bob Smith
    userPassword: mysecret

    dn: cn=you, ou=Users, dc=YourDomain, dc=com
    objectClass: top
    objectClass: person
    cn: you
    Sn: Jones
    description: Stan Jones
    userPassword: yoursecret

    Le singole Bind DN degli utenti (anche denominate User DN) sono

    cn=me, ou=Users, dc=YourDomain, dc=com e
    cn=you, ou=Users, dc=YourDomain, dc=com

    Ogni utente presenta un DN come questo qui sopra (insieme con la parola d'accesso relativa) per autenticarsi sul server LDAP.

    A proposito, la password di ogni utente non deve essere mai vuota, o il server LDAP rifiuterà i tentativi di autenticazione, rispondendo con il messaggio criptico

    Errore 53: DSA is unwilling to perform

    Stranamente, il server LDAP accetta una parola d'accesso vuota per l'attributo userPassword — semplicemente non ti lacerà entrare, con questa configurazione.

    Non è necessario definire una riga per cn=Manager, dc=YourDomain, dc=com — basta che quel nome sia nel campo rootdn in slapd.conf (e con la parola d'accesso in rootpw) per permettere che sia usato come accesso senza restrizione al server LDAP.

  4. Per gestire i gruppi degli utenti, aggiungi al file init.ldif una sezione analoga a quella che segue:

    dn: ou=Groups, dc=YourDomain, dc=com
    objectClass: top
    objectClass: organizationalUnit
    description: Gruppi per ogni rubrica
    ou: Groups

    A questo punto, per raggruppare gli utenti in rubriche separate, aggiungi queste sezioni:

    dn: cn=Home, ou=Groups, dc=YourDomain, dc=com
    objectClass: top
    objectClass: groupOfNames
    description: Membri del gruppo della rubrica Home
    cn: Home
    member: cn=me, ou=Users, dc=YourDomain, dc=com
    member: cn=mine, ou=Users, dc=YourDomain, dc=com

    dn: cn=Work, ou=Groups, dc=YourDomain, dc=com
    objectClass: top
    objectClass: groupOfNames
    description: Membri del gruppo del rubrica Work
    cn: Work
    member: cn=me, ou=Users, dc=YourDomain, dc=com
    member: cn=you, ou=Users, dc=YourDomain, dc=com

    ed aggiungi altrettante dichiarazioni di member: (appartenenza al gruppo) secondo le tue necessità, ricordando di avere per ognuno una corrispondenza nella gerarchia ou=Users, dc=YourDomain, dc=com.

    I nomi gerarchici usati sopra quali Users e Groups li ho scelti arbitrariamente; sostituiscili in base alle tue preferenze. Anche la scelta delle classi strutturali quali ou è personale; scegli i tuoi come preferisci.

  5. Ora passiamo tutti i dati preparati qui sopra al server LDAP con un comando simile a questo:

    ldapadd -x -D "cn=Manager, dc=YourDomain, dc=com" -w secret -v -f init.ldif

    L'argomento del parametro -D è il Bind DN mentre l'argomento del parametro -w è la password, entrambe definite in slapd.conf. L'argomento di -f è il file (eventualmente preceduto da un percorso) su cui ldapadd deve lavorare. L'opzione -x dice al server di usare l'autenticazione semplice anziché SASL (per semplicità non useremo la crittografia forte in questo documento), mentre -v attiva il modo "verbose", in modo che se qualcosa va male, avrai maggiori informazioni su ciò che succede. Per visualizzare una lista di tutte le opzioni a riga di comando, scrivi ldapadd ?.

    Il programma ldapadd supporta la lettura della password da un file tramite l'opzione -y (per esempio, -y Manager.pass anziché una password esplicitamente dichiarata usando il -w. Se provi questa variante, e il file contiene un carattere INVIO (CR e/o LF) alla fine della linea con la password (come la maggior parte dei sistemi di editing fanno), il funzionamento potrà essere compromesso, con l'errore ldap_bind: Invalid credentials (49) — rimuovi il carattere CR e/o LF e tutto dovrebbe tornare a funzionare bene.

    Se le cose funzionano come previsto, dovresti ottenere una risposta simile a quanto segue:

    ldap_initialize( <DEFAULT> )
    add objectClass:
        top
        organization
        dcObject
    add description:
        Descrizione del tuo dominio
    add o:
        Qualcos'altro circa il tuo dominio
    add dc:
        YourDomain
    adding new entry "dc=YourDomain, dc=com"
    modify complete

    seguito da molte altre linee se aggiungi gli utenti, i gruppi e/o i gruppi degli utenti. Come detto precedentemente, un esempio di init.ldif può essere scaricato qui.

Considerazioni di Sicurezza

Il suggerimento nella sezione precedente, secondo cui potresti voler definire diversi utenti, necessita di una spiegazione supplementare. In particolare, non si tratta solo di definire le righe di utenti e gruppi (per esempio, dc: cn=me, ou=Users, dc=YourDomain, dc=com e dc: cn=Home, ou=Groups, dc=YourDomain, dc=com).

In particolare, serve per definire le politiche di controllo d'accesso (Access Control Policies, ACP) nel proprio file slapd.conf. Supponendo di voler limitare utenti diversi a specifiche rubriche (per esempio Home e Work), ci sono molti modi per ottenere questo risultato. Una possibile soluzione è la seguente:

# Permette agli utenti di definire la propria password; comunque
# l'uso principale di questa regola è di autenticare gli utenti.
access to attrs=userPassword
        by self write
        by anonymous auth

# Permette agli utenti identificati, per gruppo, l'accesso alla
# propria rubrica, e soltanto a quella.
access to dn.regex="o=(.+),ou=AddressBooks,dc=YourDomain,dc=com"
        by group.expand="cn=$1,ou=Groups,dc=YourDomain,dc=com" write

# Permette agli utenti identificati, di leggere le informazioni
# a cui hanno accesso autenticandosi con un Bind DN vuoto.
access to dn.base="ou=AddressBooks,dc=YourDomain,dc=com" by * read
access to dn.base="" by * read

# Permette agli utenti identificati di accedere ai sottoschemi a
# cui possono avere accesso in lettura
access to dn.base="cn=Subschema" by * read

# Disattiva le connessioni (bind) anonime.
# Con questa regola, gli utenti non identificati ricevono dal server l'errore
#   Error 48: Inappropriate authentication
# e non sono in grado di navigare tra le rubriche o al loro interno.
disallow bind_anon

Attivando le regole d'accesso, e riprendendo le definizioni della sezione precedente per gruppi ed utenti, gli utenti me e mine hanno accesso alla rubrica Home, mentre gli utenti me e you hanno accesso alla rubrica Work. Aggiungendo o cancellando righe da cn=Home,ou=Groups,dc=YourDomain,dc=com e da cn=Work,ou=Groups,dc=YourDomain,dc=com consente di controllare chi può accedere a quale rubrica. In questo modo le definizioni della base di dati, consentono di regolarne l'accesso ai dati in essa contenuti.

Dopo l'attivazione delle ACP definite qui sopra, e dopo aver riavviato il server LDAP, assicurati di effettuare un controllo provando a fare il login con credenziali differenti, per vedere quali regole "scattano" di conseguenza.

Esportare la rubrica

Per esportare la rubrica da Thunderbird, clicca sul pulsante corrispondente e seleziona Strumenti e poi Esporta. Salva il file (ad esempio come abook.ldif) in una cartella dove puoi farlo trovare alle utilità di LDAP come ldapadd.

Modificare la rubrica

È necessario modificare il file abook.ldif per cambiare le righe, in modo da renderle conformi a certe convenzioni. Sfortunatamente, sia per Thunderbird 1.0 che per 1.5, non esiste una versione pubblica dello schema che coincida con ciò che viene esportato, e con ciò che possa andar bene per il server LDAP, ecco perché serve cambiare qualcosa. Le future versioni di Thunderbird, probabilmente, introdurranno nuove modifiche allo schema, ed al formato del file effettivamente esportato, e di conseguenza cambieranno gli elementi da cambiare, quindi non affezionarti troppo alle modifiche che stai per fare. Se cerchi un modo automatico di effettuare le modifiche che stiamo per vedere, scarica ed esegui questo script PHP.

In effetti, usando lo script appena citato, puoi saltare del tutto questa sezione.

  1. In gergo informatico si parla di "escaping" quando alcuni simboli riservati ricorrono nel testo di una definizione. Allora è prassi comune farli precedere dal simbolo \ per far capire all'interprete che non si tratta di un simbolo riservato, ma proprio del carattere in questione. Nei Distinguished Names (le linee che iniziano con dn: oppure con member:), potrebbero capitare simboli riservati: falli precedere dal simbolo di escape. I sette simboli riservati sono la virgola, il segno più, i doppi apici, il backslash, il maggiore, il minore ed il punto e virgola: ,+"\<>;. Per esempio, la riga

    dn: cn=Stan Jones, Jr.,mail="Stan Jones, Jr." <stan@example.com>    deve essere modificata in
    dn: cn=Stan Jones\, Jr.,mail=\"Stan Jones\, Jr.\" \<stan@example.com\>

    La virgola prima di mail= non è preceduta dal simbolo di escape poichè è parte della sintassi del DN.

  2. Analogamente, bisogna effettuare l'escape dei caratteri non-ASCII nella codifica Base64 UTF-8-encoded Distinguished Names (le righe che iniziano con dn:: o member::). In altre parole, le occorrenze di caratteri sopra ASCII(127) vanno sostituite con il valore corrispondente nella codifica UTF-8 esadecimale, con ogni byte preceduto da un backslash. Per esempio, se hai inserito un Display Name nella rubrica di Thunderbird per Mary Gutiérrez, dovrebbe venir esportato come:

    dn:: Y249TWFyeSBHdXRpw6lycmV6    (il doppio due punti indica una riga in formato Base64 UTF-8)

    che in Base64 diventa

    dn: cn=Mary Guti+¬rrez    (ovvero, il carattere non-ASCII é è stato codificato con i due bytes 0xC3 and 0xA9 () in formato UTF-8, prima di essere codificato in Base64)

    Per finire, la riga qui sopra va modificata in

    dn: cn=Mary Guti\C3\A9rrez

    che è un formato accettabile per il server LDAP (e sicuramente più leggibile per un umano).

    Solo le righe dn:: e member:: vanno cambiate, non le righe cn:: (o, per generalità, qualsiasi altra linea che inizia con un nome di attributo seguito da un doppio due punti).

    L'intero processo per entrambe le modifiche, è spiegato nell'articolo UTF-8 String Representation of Distinguished Names.

  3. Ogni Distinguished Name che abbia sia il campo cn= che mail=, va cambiato in un formato accettabile per il server LDAP. In particolare, le due parti devono essere unite con un segno più (invece che separate da una virgola) come per creare un Relative Distinguished Name (RDN) multivalore Il formato esportato da Thunderbird ha una forma simile a questa:

    dn: cn=First Last,mail=email@example.com     e deve essere cambiato in
    dn: cn=First Last+mail=email@example.com

    Ci sono altri modi di ottenere qualcosa di simile, come ad esempio omettere la parte mail= della riga dn:, ma la modifica che ti suggerisco, consente di avere più righe con lo stesso nome e differenti indirizzi email.

  4. Ogni Distinguished Name deve essere seguito dalla Base DN per la rubrica (ad esempio o=Home,ou=AddressBooks,dc=YourDomain,dc=com). Questa modifica si rende necessaria per il server LDAP, in modo da fargli capire dove posizionare la definizione nella gerarchia.

    Ad esempio, il distinguished name

    dn: cn=First Last+mail=email@example.com     sarà cambiato in
    dn: cn=First Last+mail=email@example.com,o=Home,ou=AddressBooks,dc=YourDomain,dc=com

  5. Gli attributi xmozillausehtmlmail e mozillaUseHtmlMail richiedono un valore booleano (TRUE o FALSE) e vanno indicati in maiuscolo. Sfortunatamente, Thunderbird esporta questi attributi in minuscolo — sostituiscili con i corrispondenti maiuscolo.

  6. Personalmente, non sono riuscito ad ottenere dal campo modifytimestamp: 0Z altro che un errore, quindi non mi rimaneva che commentare le righe corrispondenti, facendole precedere dal segno di cancelletto. Se riesci a capire il motivo di tale errore (o meglio, come risolverlo — ho già letto NO-USER-MODIFICATION), .

  7. Se utilizzi un soprannome per definire una Lista (Rubrica > Nuova Lista, o click destro > Proprietà su una lista esistente), Thunderbird esporta questo valore usando l'attributo mozillaNickname — ad esempio:

    dn: cn=Poker
    objectclass: top
    objectclass: groupOfNames
    cn: Poker
    mozillaNickname: fish
    description: Gli amici del Poker
    member: cn=Stan Jones,mail=stan@example.com

    Comunque, quell'attributo non può essere presente in objectclass: groupOfNames, quindi non rimane che commentarlo.

  8. L'attributo mozilla_AimScreenName esportato da Thunderbird non è compreso nella definizione dello schema sebbene nsAIMid lo sia, per questo tutte le occorrenze del primo, vanno sostituite con il secondo. In maniera analoga, il file LDIF esportato da Thunderbird 1.5 e lo schema mozillaAbPersonAlpha differiscono come segue:

    Thunderbird 1.5    Schema più vicino
    company:    o:
    department:    ou:
    homeStreet:    mozillaHomeStreet:

    dunque queste modifiche devono essere riportate sul file, se usi Thunderbird 1.5.

  9. Poichè una delle definizioni di objectclass è person e che objectclass richiede la definizione di certi attributi, tutte le righe devono avere sia un nome comune (common name, cn) che un cognome (surname, sn), definiti con i rispettivi attributi. Se trovi dei contatti nella rubrica che non hanno uno dei due parametri, definiscilo per default a tuo piacimento.

  10. Se ci sono dei contatti duplicati (ad esempio con lo stesso nome comune (cn) ed indirizzo email (mail)), rimuovi il duplicato o accorporali o ancora, cambiane uno dei due affinché abbia un diverso cn o indirizzo mail.

Benchè Thunderbird generalmente accetti ogni testo per ogni campo nella sua rubrica, i server LDAP sono molto più schizzinosi. Alcuni campi (ad esempio quelli contenenti i numeri di telefono), devono essere indicati in un ben preciso formato. Questo script non cerca di verificare che tali campi siano conformi ai requisiti imposti dal server, per questo potrebbe capitare che ldapadd faccia storie, nel gestirle. Per risolvere il problema, serve consultare la documentazione per la specifica riga, al fine di stabilire il formato corretto. Ti servirà cercare il nome del campo (dallo schema) e possibilmente il nome del suo identificatore (Object Identifier, da ricercare anche questo nello schema); dopo ciò in rete trovi sicuramente le definizioni corrispondenti, ad esempio su Alvestrand's Object Identifier Registry.

Ci potrebbe essere qualche altra modifica necessaria, per avere un servizio funzionante con questo file di Thunderbird, ma si tratta in genere di avvisi che si ottengono quando si cerca di importare la rubrica. Se questo è il tuo caso, per favore in modo che possa aggiungerlo alla lista qui sopra. Ti ricordo ancora che queste modifiche possono essere fatte automaticamente scaricando ed eseguendo questo script PHP.

Caricare la rubrica sul server LDAP

Dopo tutte queste modifiche, la rubrica sul file dovrebbe essere sufficientemente ripulita da errori o differenze di caratteri, per essere conforme a quello che il server LDAP richiede. Per caricare il file di rubrica sul server, usa questo comando:

ldapadd -x -D "cn=Manager,dc=YourDomain,dc=com" -w secret -v -f abook.ldif

A questo punto mi sono accorto (prima di incappare in tutte le cose che ho descritto in precedenza), che si verificavano alcuni errori che fermavano la chiamata a ldapadd, impedendone il completamento. Allora ho:

  1. Corretto gli errori (agendo sul file abook.ldif)
  2. Fermato il server LDAP
  3. Rimosso il suo database
  4. Riavviato il server LDAP
  5. Inizializzato nuovamente la riga dc=YourDomain,dc=com e quelle che seguono (tramite init.ldif)
  6. e provato ancora il comando ldapadd.

Se incappi in errori che non sono descritti in questa guida, ti suggerisco di adottare lo stesso approccio, ed in caso , se trovi qualcosa che sarebbe bene aggiungere qui.

Se l'esecuzione di ldapadd si completa senza errori, hai appena importato la tua rubrica sul server LDAP!

Istruire Thunderbird su come connettersi al server LDAP

A questo punto, hai esportato la rubrica da Thunderbird 1.0/1.5 verso il server LDAP, dal quale puoi ora accederla istruendo Thunderbird su come connettersi:

Fatto questo, Thunderbird userà d'ora in poi il server LDAP per reperire gli indirizzi email, quando inizi a digitare parte di un nome, nella finestra di composizione. In Thunderbird 1.5 la funzione di scaricamento di un'intera rubrica in locale sembra avere qualche bug di funzionamento, come riportato anche sul loro sito, quindi non allarmarti se non dovesse funzionare!

Autore e crediti

Questa pagina è stata creata da Bob Smith — per favore qualsiasi domanda o commento in proposito.

Vorrei ringraziare John W. Keating III per avermi segnalato il problema di mozillaNickname: dentro una lista, e per la traduzione italiana.

Valid XHTML 1.0! Valid CSS!
© Sudley Place Software 1997-2017. Get Firefox!   Get Thunderbird!   Get LibreOffice!   I Support Science!
Comments or suggestions? Send them to .