4. The check_host() Function (La fonction check_host())
4. The check_host() Function (La fonction check_host())
Cette description n'est pas une définition d'interface de programmation d'application, mais une description de fonction pour illustrer l'algorithme. Les implémentations SPF conformes doivent produire des résultats sémantiquement équivalents à cette description.
La fonction check_host() récupère les enregistrements SPF, les analyse et les évalue pour déterminer si un hôte particulier est autorisé ou non autorisé à envoyer des courriers avec une identité donnée. L'ADMD de réception effectuant cette vérification doit évaluer correctement la fonction check_host() comme décrit ici.
Les implémentations peuvent utiliser un algorithme différent de l'algorithme canonique défini ici, tant que les résultats sont identiques dans tous les cas.
4.1 Arguments (Arguments)
La fonction check_host() prend les arguments suivants:
<ip> - L'adresse IP du client SMTP qui envoie le courrier, soit IPv4 soit IPv6.
<domain> - Le domaine qui fournit les informations d'autorisation recherchées; initialement la partie domaine de l'identité "MAIL FROM" ou "HELO".
<sender> - L'identité "MAIL FROM" ou "HELO".
Pour les évaluations récursives, la partie domaine de <sender> peut différer de l'argument <domain> lors de la première évaluation de check_host(). Dans la plupart des autres cas, elle sera la même (voir section 5.2 ci-dessous). La limite de requête DNS globale pour les termes SPF décrite dans la section 4.6.4 doit être suivie comme une limite globale unique sur toutes les évaluations, pas seulement pour une instance d'évaluation récursive unique.
Notez que l'argument <domain> peut ne pas être un nom de domaine bien formé. Par exemple, si le chemin inverse est vide, le domaine EHLO/HELO et ses problèmes associés sont utilisés (voir section 2.3). Dans ces cas, check_host() est défini dans la section 4.3 pour retourner un résultat "none".
4.2 Results (Résultats)
La fonction check_host() peut retourner l'un des plusieurs résultats décrits dans la section 2.6. L'action à entreprendre en fonction du résultat est déterminée par la politique locale du destinataire. Ceci est discuté dans la section 8.
4.3 Initial Processing (Traitement initial)
Si <domain> est mal formaté (par exemple, longueur d'étiquette supérieure à 63 caractères, étiquettes de longueur nulle non terminales, etc.) ou n'est pas un nom de domaine multi-étiquettes, ou si la requête DNS retourne "Name Error" (RCODE 3, également connu sous le nom de "NXDOMAIN" [RFC2308]), check_host() retourne immédiatement le résultat "none". Les RCODE DNS sont définis dans [RFC1035]. Un domaine bien formé est un nom de domaine pleinement qualifié tel que défini dans [RFC1983]. C'est-à-dire que dans le DNS, ils sont implicitement qualifiés par rapport à la racine (voir section 3.1 de [RFC1034]). Les noms de domaine internationalisés doivent être encodés en A-label, comme décrit dans la section 2.3 de [RFC5890].
Si <sender> n'a pas de local-part, remplacez le local-part par la chaîne "postmaster".
4.4 Record Lookup (Recherche d'enregistrement)
En fonction de la manière dont l'enregistrement est publié (voir section 3 ci-dessus), une requête DNS pour le nom <domain> est nécessaire, uniquement pour le type TXT.
Si la requête DNS retourne une défaillance du serveur (RCODE 2) ou une autre erreur (RCODE ni 0 ni 3), ou si la requête expire, check_host() se termine immédiatement avec le résultat "temperror".
4.5 Selecting Records (Sélection des enregistrements)
Les enregistrements commencent par une partie version:
record = version terms *SP
version = "v=spf1"
En commençant par l'ensemble d'enregistrements retourné par la requête, supprimez les enregistrements qui ne commencent pas par une partie version de exactement "v=spf1". Notez que la partie version est terminée par un caractère SP ou la fin de l'enregistrement. Par exemple, un enregistrement avec une partie version "v=spf10" ne correspond pas et est supprimé.
Si l'ensemble d'enregistrements résultant ne contient aucun enregistrement, check_host() produit un résultat "none". Si l'ensemble d'enregistrements résultant contient plusieurs enregistrements, check_host() produit un résultat "permerror".
4.6 Record Evaluation (Évaluation de l'enregistrement)
La fonction check_host() analyse et interprète l'enregistrement SPF pour trouver un résultat pour le test actuel. Tout d'abord, la syntaxe de l'enregistrement est validée, et si des erreurs de syntaxe sont présentes n'importe où dans l'enregistrement, check_host() retourne immédiatement le résultat "permerror" sans interprétation ou évaluation supplémentaire.
4.6.1 Term Evaluation (Évaluation des termes)
Il existe deux types de termes: les mécanismes (définis dans la section 5) et les modificateurs (définis dans la section 6). Les enregistrements contiennent une liste ordonnée de ceux-ci, comme spécifié dans la notation de forme de Backus-Naur augmentée (ABNF) suivante.
terms = *( 1*SP ( directive / modifier ) )
directive = [ qualifier ] mechanism
qualifier = "+" / "-" / "?" / "~"
mechanism = ( all / include
/ a / mx / ptr / ip4 / ip6 / exists )
modifier = redirect / explanation / unknown-modifier
unknown-modifier = name "=" macro-string
; where name is not any known modifier
name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
La plupart des mécanismes autorisent un caractère ":" ou "/" après le nom.
Les modificateurs contiennent toujours un caractère égal ('=') immédiatement après le nom et avant tout caractère ":" ou "/" qui pourrait faire partie d'un macro-string.
Un terme qui ne contient aucun des caractères "=", ":" ou "/" est un mécanisme, tel que défini dans la section 5.
Selon la notation ABNF telle que définie dans [RFC5234], les noms de mécanismes et de modificateurs ne sont pas sensibles à la casse.
4.6.2 Mechanisms (Mécanismes)
Chaque mécanisme est considéré dans l'ordre de gauche à droite. S'il n'y a plus de mécanismes, le résultat est le résultat par défaut décrit dans la section 4.7.
Lorsqu'un mécanisme est évalué, trois choses peuvent se produire: il peut correspondre, ne pas correspondre ou retourner une exception.
S'il correspond, le traitement se termine et la valeur du qualificateur est retournée comme résultat pour cet enregistrement. S'il ne correspond pas, le traitement continue avec le mécanisme suivant. S'il retourne une exception, le traitement du mécanisme se termine et la valeur d'exception est retournée.
Les qualificateurs possibles et les résultats qu'ils provoquent pour check_host() sont les suivants:
"+" pass
"-" fail
"~" softfail
"?" neutral
Le qualificateur est optionnel et vaut par défaut "+".
Lorsque le mécanisme correspond et que le qualificateur est "-", un résultat "fail" est retourné et la chaîne d'explication est calculée comme décrit dans la section 6.2.
La section 5 décrit les mécanismes spécifiques.
4.6.3 Modifiers (Modificateurs)
Les modificateurs ne sont pas des mécanismes. Ils ne retournent pas de correspondance ou de non-correspondance. Au lieu de cela, ils fournissent des informations supplémentaires. Bien que les modificateurs n'affectent pas directement l'évaluation de l'enregistrement, le modificateur "redirect" a un impact après l'évaluation de tous les mécanismes.
4.6.4 DNS Lookup Limits (Limites de recherche DNS)
Certains mécanismes et modificateurs (collectivement appelés "termes") provoquent des requêtes DNS lors de l'évaluation, tandis que d'autres non. Les termes suivants provoquent des requêtes DNS: les mécanismes "include", "a", "mx", "ptr" et "exists", ainsi que le modificateur "redirect". Les implémentations SPF doivent limiter le nombre total de ces termes à 10 pendant une évaluation SPF, pour éviter une charge déraisonnable sur le DNS. Si cette limite est dépassée, l'implémentation doit retourner "permerror". Les autres termes -- les mécanismes "all", "ip4" et "ip6", ainsi que le modificateur "exp" -- ne provoquent pas de requêtes DNS lors de l'évaluation SPF (le modificateur "exp" ne provoque une requête qu'à un moment ultérieur), et leur utilisation n'est pas soumise à cette limite.
Lors de l'évaluation du mécanisme "mx", le nombre d'enregistrements de ressources "MX" interrogés est inclus dans la limite globale ci-dessus de 10 mécanismes/modificateurs provoquant des requêtes DNS. En plus de cette limite, l'évaluation de chaque enregistrement "MX" ne doit absolument pas entraîner l'interrogation de plus de 10 enregistrements d'adresses -- enregistrements de ressources "A" ou "AAAA". Si cette limite est dépassée, le mécanisme "mx" doit produire un résultat "permerror".
Lors de l'évaluation du mécanisme "ptr" ou de la macro %\{p}, le nombre d'enregistrements de ressources "PTR" interrogés est inclus dans la limite globale ci-dessus de 10 mécanismes/modificateurs provoquant des requêtes DNS. En plus de cette limite, l'évaluation de chaque enregistrement "PTR" ne doit absolument pas entraîner l'interrogation de plus de 10 enregistrements d'adresses -- enregistrements de ressources "A" ou "AAAA". Si cette limite est dépassée, tous les enregistrements sauf les 10 premiers doivent être ignorés.
La raison de la différence est que l'ensemble et le contenu des enregistrements MX sont sous le contrôle de l'ADMD de publication, tandis que l'ensemble et le contenu des enregistrements PTR sont sous le contrôle du propriétaire de l'adresse IP qui établit réellement la connexion.
Ces limites sont par mécanisme ou macro dans un enregistrement et s'ajoutent aux limites de requête spécifiées ci-dessus.
Un MTA ou un autre processeur devrait imposer une limite de temps écoulé maximum pour l'évaluation de check_host(). Une telle limite devrait permettre au moins 20 secondes. Si une telle limite est dépassée, le résultat d'autorisation devrait être "temperror".
Comme mentionné à la fin de la section 11.1, dans certains cas, il peut être utile de limiter le nombre de "termes" qui renvoient des requêtes DNS retournant une réponse positive (RCODE 0) avec un compte de réponses de 0, ou une réponse "Name Error" (RCODE 3). Celles-ci sont parfois collectivement appelées "void lookups". Les implémentations SPF devraient limiter les "void lookups" à deux. Les implémentations peuvent choisir de rendre une telle limite configurable. Dans ce cas, il est recommandé que la valeur par défaut soit deux. Le dépassement de la limite produit un résultat "permerror".
4.7 Default Result (Résultat par défaut)
Si aucun des mécanismes ne correspond et qu'il n'y a pas de modificateur "redirect", check_host() retourne le résultat "neutral", comme si "?all" était spécifié comme dernière directive. Si un modificateur "redirect" est présent, check_host() continue comme défini dans la section 6.1.
Il est préférable d'utiliser un modificateur "redirect" ou un mécanisme "all" pour terminer explicitement le traitement. Bien qu'il y ait un "?all" implicite à la fin de chaque enregistrement qui ne se termine pas explicitement, cela aide les efforts de débogage lorsqu'il est fourni explicitement.
Exemple:
v=spf1 +mx -all
Ou
v=spf1 +mx redirect=_spf.example.com
4.8 Domain Specification (Spécification de domaine)
Plusieurs de ces mécanismes et modificateurs ont une partie <domain-spec>. La chaîne est soumise à une expansion de macro (voir section 7). La chaîne résultante est la représentation habituelle d'un nom DNS pleinement qualifié: une séquence d'étiquettes séparées par des points. Ce domaine est appelé <target-name> dans le reste de ce document.
Note: Le résultat de l'expansion de macro n'est soumis à aucun échappement supplémentaire. Par conséquent, cet outil ne peut pas produire tous les caractères légaux dans les étiquettes DNS (par exemple, les caractères de contrôle). Cependant, cet outil est suffisamment puissant pour exprimer les noms d'hôtes légaux et les étiquettes utilitaires courantes utilisées dans le DNS (par exemple, "_spf").
Pour plusieurs mécanismes, <domain-spec> est optionnel. S'il n'est pas fourni, le <domain> des arguments check_host() (voir section 4.1) est utilisé comme <target-name>. "domain" et <target-name> sont syntaxiquement identiques après l'expansion des macros. "domain" est la valeur d'entrée pour check_host(), tandis que <target-name> est calculé par check_host().
L'évaluation de check_host() avec un domaine syntaxiquement invalide est indéfinie.
Note: Ce document et son prédécesseur ne contiennent aucune disposition pour la gestion correcte des <domain-spec> syntaxiquement invalides (éventuellement le résultat d'une expansion de macro) selon [RFC1035]. Des exemples incluent les noms avec des étiquettes vides comme "foo..example.com" et les étiquettes d'une longueur supérieure à 63 caractères. Certaines implémentations choisissent de traiter de telles erreurs comme une non-correspondance et ignorent donc ces noms, tandis que d'autres implémentations retournent une exception "permerror".