diff options
| author | Shulhan <m.shulhan@gmail.com> | 2019-08-28 23:59:56 +0700 |
|---|---|---|
| committer | Shulhan <m.shulhan@gmail.com> | 2019-08-28 23:59:56 +0700 |
| commit | 292bbb29aa44ff3a1632b27715596b2b00b77589 (patch) | |
| tree | f1ca497d5635d5f85835e46fdd816378c6f38780 | |
| parent | c4468122196b768c71c0abe4edc57265905decdf (diff) | |
| download | pakakeh.go-292bbb29aa44ff3a1632b27715596b2b00b77589.tar.xz | |
all: replace document generator from asciidoctor to ciigo
Previously, generating HTML files from asciidoc files require installing
ruby, asciidoctor, and its dependency through Gemfile.
To simplify this, we replace it with ciigo. Ciigo not only can convert
the asciidoc files but it also support serving the file inside HTTP
server and watching changes on asciidoc files during development for
local previewing.
37 files changed, 4210 insertions, 3238 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index e1281d58..1142cf43 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -1,8 +1,8 @@ = CHANGELOG +:stylesheet: doc/style.css :toc: -This library is released each month, either at the end of month or at the -first week of next month. +This library is released each month, usually at the first week of month. == share v0.8.1 (2019-08-05) diff --git a/CHANGELOG.html b/CHANGELOG.html index 09831b35..31961a41 100644 --- a/CHANGELOG.html +++ b/CHANGELOG.html @@ -1,18 +1,32 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<title>CHANGELOG</title> -<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> -<link rel="stylesheet" href="./asciidoctor.css"> -</head> -<body class="article"> -<div id="header"> -<h1>CHANGELOG</h1> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>CHANGELOG</title> + <link rel="stylesheet" href="doc/style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>CHANGELOG</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> <li><a href="#_share_v0_8_1_2019_08_05">share v0.8.1 (2019-08-05)</a> @@ -73,13 +87,10 @@ <li><a href="#_share_v0_1_0_2018_11_29">share v0.1.0 (2018-11-29)</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> -<p>This library is released each month, either at the end of month or at the -first week of next month.</p> +<p>This library is released each month, usually at the first week of month.</p> </div> </div> </div> @@ -99,15 +110,13 @@ first week of next month.</p> <li> <p>lib/memfs: add method to encode the content of file.</p> <div class="paragraph"> -<p>The ContentEncode() method encode each node’s content into specific +<p>The ContentEncode() method encode each node's content into specific encoding, in other words this method can be used to compress the content -of file in memory before being served or written.</p> -</div> -<div class="paragraph"> -<p>Only file with size greater than 0 will be encoded.</p> -</div> -<div class="paragraph"> -<p>List of known encoding is "gzip".</p> +of file in memory before being served or written. ++ +Only file with size greater than 0 will be encoded. ++ +List of known encoding is "gzip".</p> </div> </li> <li> @@ -134,7 +143,7 @@ file, we want that file to be excluded from .go static source.</p> <ul> <li> <p>All ASCII related contants and functions now being moved from <code>bytes</code> -package to <code>ascii</code> package.</p> + package to <code>ascii</code> package.</p> </li> </ul> </div> @@ -214,7 +223,7 @@ simple API.</p> <p>doc: regenerate to use new style</p> </li> <li> -<p>http: print the not-found path on Server’s getFSNode()</p> +<p>http: print the not-found path on Server's getFSNode()</p> </li> <li> <p>ini: add method Vars that return all variables as map</p> @@ -330,7 +339,7 @@ removing the server handler.</p> <p>rename Send to Write, and change the parameter type to slice of byte</p> </li> <li> -<p>remove "elapsed" parameter on Message.IsExpired()</p> +<p>remove "elapsed" parameter on Message.IsExpired()</p> </li> <li> <p>unexport the Request type</p> @@ -342,7 +351,7 @@ removing the server handler.</p> <p>unexport connection type</p> </li> <li> -<p>remove unused address parameter on client’s Query()</p> +<p>remove unused address parameter on client's Query()</p> </li> <li> <p>unexport all fields from UDP and TCP clients</p> @@ -567,7 +576,7 @@ server and client API to make it easy and extensible. The websocket is now <ul> <li> <p>Rewrite most of client and server APIs to be more simple and pass autobahn -testsuite</p> + testsuite</p> </li> <li> <p>Minimize global variables and unexport internal constants and functions</p> @@ -598,7 +607,7 @@ testsuite</p> </li> <li> <p><code>email/dkim</code>: new package for parsing and creating DKIM signature -(RFC 6376)</p> + (RFC 6376)</p> </li> <li> <p><code>email/maildir</code>: new package to manage email using maildir format</p> @@ -656,7 +665,7 @@ testsuite</p> <div class="ulist"> <ul> <li> -<p>add the charset type to content-type "text/plain"</p> +<p>add the charset type to content-type "text/plain"</p> </li> <li> <p>listen and serve using TLS if TLSConfig is defined</p> @@ -751,7 +760,7 @@ testsuite</p> <div class="ulist"> <ul> <li> -<p>all: fix the usage of "iota"</p> +<p>all: fix the usage of "iota"</p> </li> <li> <p><code>dns</code>: fix creating new UDP/TCP client without port number</p> @@ -877,7 +886,7 @@ and several libraries.</p> </div> <div class="literalblock"> <div class="content"> -<pre>https://godoc.org/github.com/shuLhan/share</pre> +<pre> https://godoc.org/github.com/shuLhan/share</pre> </div> </div> <div class="paragraph"> @@ -885,11 +894,16 @@ and several libraries.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-08-05 12:52:47 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 5c2c02bb..00000000 --- a/Gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'https://rubygems.org' - -gem 'guard-asciidoctor' -gem 'guard-livereload' -gem 'guard-shell' -gem 'rb-inotify' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index c5e4bcaa..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,66 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - asciidoctor (2.0.9) - coderay (1.1.2) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - eventmachine (1.2.7) - ffi (1.10.0) - formatador (0.2.5) - guard (2.15.0) - formatador (>= 0.2.4) - listen (>= 2.7, < 4.0) - lumberjack (>= 1.0.12, < 2.0) - nenv (~> 0.1) - notiffany (~> 0.0) - pry (>= 0.9.12) - shellany (~> 0.0) - thor (>= 0.18.1) - guard-asciidoctor (0.1.1) - asciidoctor - guard (~> 2.0) - guard-compat (~> 1.1) - guard-compat (1.2.1) - guard-livereload (2.5.2) - em-websocket (~> 0.5) - guard (~> 2.8) - guard-compat (~> 1.0) - multi_json (~> 1.8) - guard-shell (0.7.1) - guard (>= 2.0.0) - guard-compat (~> 1.0) - http_parser.rb (0.6.0) - listen (3.1.5) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - lumberjack (1.0.13) - method_source (0.9.2) - multi_json (1.13.1) - nenv (0.3.0) - notiffany (0.1.1) - nenv (~> 0.1) - shellany (~> 0.0) - pry (0.12.2) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - rb-fsevent (0.10.3) - rb-inotify (0.10.0) - ffi (~> 1.0) - ruby_dep (1.5.0) - shellany (0.0.1) - thor (0.20.3) - -PLATFORMS - ruby - -DEPENDENCIES - guard-asciidoctor - guard-livereload - guard-shell - rb-inotify - -BUNDLED WITH - 2.0.1 diff --git a/Guardfile b/Guardfile deleted file mode 100644 index 0fd74661..00000000 --- a/Guardfile +++ /dev/null @@ -1,19 +0,0 @@ -require 'asciidoctor' - -ignore! /.git/ - -guard 'shell' do - watch(%r{^.+\.adoc$}) {|m| - Asciidoctor.convert_file m[0] - } - watch(%r{doc/.+\.adoc$}) {|m| - Asciidoctor.convert_file m[0] - } - watch(%r{lib/websocket/AUTOBAHN.+\.adoc$}) {|m| - Asciidoctor.convert_file m[0] - } -end - -guard 'livereload' do - watch(%r{^.+\.(css|js|html)$}) -end diff --git a/README.adoc b/README.adoc index b44153a2..6456f50b 100644 --- a/README.adoc +++ b/README.adoc @@ -14,129 +14,129 @@ A collection of libraries and tools written in Go. == Command Line Interface -* link:{url-godoc}/cmd/gofmtcomment[*gofmtcomment*^]: Program to convert - multilines "/\*\*/" comment into single line "//" format. +* link:{url-godoc}/cmd/gofmtcomment[*gofmtcomment*]: Program to convert + multilines "/**/" comment into single line "//" format. -* link:{url-godoc}/cmd/smtpcli[*smtpcli*^]: Command smtpcli provide a command +* link:{url-godoc}/cmd/smtpcli[*smtpcli*]: Command smtpcli provide a command line interface to SMTP client protocol. == Libraries -* link:{url-godoc}/lib/ascii[*ascii*^]: A library for working with ASCII +* link:{url-godoc}/lib/ascii[*ascii*]: A library for working with ASCII characters. -* link:{url-godoc}/lib/bytes[*bytes*^]: A library for working with slice of +* link:{url-godoc}/lib/bytes[*bytes*]: A library for working with slice of bytes. -* link:{url-godoc}/lib/contact[*contact*^]: A library to import contact from +* link:{url-godoc}/lib/contact[*contact*]: A library to import contact from Google, Microsoft, or Yahoo -* link:{url-godoc}/lib/crypto[*crypto*^]: Package crypto provide a wrapper +* link:{url-godoc}/lib/crypto[*crypto*]: Package crypto provide a wrapper for standard crypto package. -* link:{url-godoc}/lib/dns[*dns*^]: A library for working with Domain Name +* link:{url-godoc}/lib/dns[*dns*]: A library for working with Domain Name System (DNS) protocol. -* link:{url-godoc}/lib/dsv[*dsv*^]: A library for working with delimited +* link:{url-godoc}/lib/dsv[*dsv*]: A library for working with delimited separated value (DSV). -* link:{url-godoc}/lib/email[*email*^]: A library for working with Internet +* link:{url-godoc}/lib/email[*email*]: A library for working with Internet Message Format as defined by RFC 5322. -** link:{url-godoc}/lib/email/dkim[*dkim*^]: A library to parse and create +** link:{url-godoc}/lib/email/dkim[*dkim*]: A library to parse and create DKIM-Signature header field value, as defined in RFC 6376. -** link:{url-godoc}/lib/email/maildir[*maildir*^]: A library to manage email +** link:{url-godoc}/lib/email/maildir[*maildir*]: A library to manage email using maildir format. -* link:{url-godoc}/lib/errors[*errors*^]: Package errors provide an error +* link:{url-godoc}/lib/errors[*errors*]: Package errors provide an error type with code. -* link:{url-godoc}/lib/floats[*floats*^]: A library for working with slice of +* link:{url-godoc}/lib/floats[*floats*]: A library for working with slice of floats. -* link:{url-godoc}/lib/git[*git*^]: A wrapper for git command line interface. +* link:{url-godoc}/lib/git[*git*]: A wrapper for git command line interface. -* link:{url-godoc}/lib/http[*http*^]: Custom HTTP server with memory file +* link:{url-godoc}/lib/http[*http*]: Custom HTTP server with memory file system and simplified routing handler. -* link:{url-godoc}/lib/ini[*ini*^]: A library for reading and writing INI +* link:{url-godoc}/lib/ini[*ini*]: A library for reading and writing INI configuration as defined by Git configuration file syntax. -* link:{url-godoc}/lib/ints[*ints*^]: A library for working with slice of +* link:{url-godoc}/lib/ints[*ints*]: A library for working with slice of integer. -* link:{url-godoc}/lib/ints[*ints64*^]: A library for working with slice of +* link:{url-godoc}/lib/ints[*ints64*]: A library for working with slice of 64 bit integer. -* link:{url-godoc}/lib/io[*io*^]: A library for reading and watching file, +* link:{url-godoc}/lib/io[*io*]: A library for reading and watching file, and reading from standard input. -* link:{url-godoc}/lib/memfs[*memfs*^]: A library for mapping file system +* link:{url-godoc}/lib/memfs[*memfs*]: A library for mapping file system into memory. -* link:{url-godoc}/lib/mining[*mining*^]: A library for data mining. +* link:{url-godoc}/lib/mining[*mining*]: A library for data mining. -** link:{url-godoc}/lib/mining/classifier/cart[*classifier/cart*^]: +** link:{url-godoc}/lib/mining/classifier/cart[*classifier/cart*]: Implementation of the Classification and Regression Tree by Breiman, et al. -** link:{url-godoc}/lib/mining/classifier/crf[*classififer/crf*^]: +** link:{url-godoc}/lib/mining/classifier/crf[*classififer/crf*]: Implementation of the Cascaded Random Forest (CRF) algorithm, proposed by Baumann, Florian, et al. -** link:{url-godoc}/lib/mining/classifier/rf[*classifier/rf*^]: +** link:{url-godoc}/lib/mining/classifier/rf[*classifier/rf*]: Implementation of ensemble of classifiers using random forest algorithm by Breiman and Cutler. -** link:{url-godoc}/lib/mining/gain/gini[*gain/gini*^]: A library to +** link:{url-godoc}/lib/mining/gain/gini[*gain/gini*]: A library to calculate Gini gain. -** link:{url-godoc}/lib/mining/knn[*knn*^]: Implementation of the K +** link:{url-godoc}/lib/mining/knn[*knn*]: Implementation of the K Nearest Neighbor (KNN) using Euclidian to compute the distance between samples. -** link:{url-godoc}/lib/mining/math[*math*^]: A library for working with +** link:{url-godoc}/lib/mining/math[*math*]: A library for working with mathematic. -** link:{url-godoc}/lib/mining/resampling/lnsmote[*resampling/lnsmote*^]: +** link:{url-godoc}/lib/mining/resampling/lnsmote[*resampling/lnsmote*]: Implementation of the Local-Neighborhood algorithm from the paper of Maciejewski, Tomasz, and Jerzy Stefanowski. -** link:{url-godoc}/lib/mining/resampling/smote[*resampling/smote*^]: +** link:{url-godoc}/lib/mining/resampling/smote[*resampling/smote*]: Implementation of the Synthetic Minority Oversampling TEchnique (SMOTE). -** link:{url-godoc}/lib/mining/tree/binary[*tree/binary*^]: Implementation of +** link:{url-godoc}/lib/mining/tree/binary[*tree/binary*]: Implementation of binary tree. -* link:{url-godoc}/lib/net[*net*^]: Constants and library for networking. +* link:{url-godoc}/lib/net[*net*]: Constants and library for networking. -* link:{url-godoc}/lib/numbers[*numbers*^]: A library for working with +* link:{url-godoc}/lib/numbers[*numbers*]: A library for working with integer, float, slice of integer, and slice of floats. -* link:{url-godoc}/lib/runes[*runes*^]: A library for working with slice of +* link:{url-godoc}/lib/runes[*runes*]: A library for working with slice of rune. -* link:{url-godoc}/lib/smtp[*smtp*^]: A library for building SMTP server or +* link:{url-godoc}/lib/smtp[*smtp*]: A library for building SMTP server or client. This package is working in progress. -* link:{url-godoc}/lib/strings[*strings*^]: A library for working with slice +* link:{url-godoc}/lib/strings[*strings*]: A library for working with slice of string. -* link:{url-godoc}/lib/tabula[*tabula*^]: A library for working with rows, +* link:{url-godoc}/lib/tabula[*tabula*]: A library for working with rows, columns, or matrix (table), or in another terms working with data set. -* link:{url-godoc}/lib/test[*test*^]: A library for helping with testing. +* link:{url-godoc}/lib/test[*test*]: A library for helping with testing. -* link:{url-godoc}/lib/text[*text*^]: A library for working with text. +* link:{url-godoc}/lib/text[*text*]: A library for working with text. -** link:{url-godoc}/lib/text/diff[*text/diff*^]: Text comparison. +** link:{url-godoc}/lib/text/diff[*text/diff*]: Text comparison. -* link:{url-godoc}/lib/time[*time*^]: A library for working with time. +* link:{url-godoc}/lib/time[*time*]: A library for working with time. -* link:{url-godoc}/lib/websocket[*websocket*^]: Websocket library for server +* link:{url-godoc}/lib/websocket[*websocket*]: Websocket library for server and client. The websocket is tested with autobahn testsuite with 100% success rate. See link:{url-github-master}/lib/websocket/AUTOBAHN.adoc[the status @@ -145,7 +145,7 @@ reports]. == Changelog -include::CHANGELOG.adoc[] +link:CHANGELOG.html[CHANGELOG]. == Documentations @@ -184,21 +184,31 @@ NOTE: The links below is used to be viewed locally, not through Github. * link:doc/SPF.html[Sender Policy Framework version 1 (RFC 7208)] -=== Development +The documentation created using +https://github.com/shuLhan/ciigo[`ciigo`]. +First, install `ciigo` command line interface, -The documentation created using asciidoctor. First, install `ruby` and -`bundler`, and then execute `bundler` on source root directory. +---- +$ go install github.com/shuLhan/ciigo/cmd/ciigo +---- -During development of documentation execute, +and then run ---- -$ bundler exec guard -i +$ ciigo -template=html.tmpl serve . ---- -to watch changes on documentation files (".adoc") and regenerate the HTML +to serve documentation on HTTP server at http://127.0.0.1:8080 and watch +changes on documentation files (".adoc") and regenerate the HTML files. +To generate HTML files for all asciidoc and markdown files, run + +---- +$ ciigo -template=html.tmpl convert . +---- + == Credits -* link:https://github.com/crossbario/autobahn-testsuite[Autobahn testsuite^] +* link:https://github.com/crossbario/autobahn-testsuite[Autobahn testsuite] diff --git a/README.html b/README.html index e8d80bb4..f922d2a6 100644 --- a/README.html +++ b/README.html @@ -1,42 +1,46 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>import "github/shuLhan/share"</title> -<link rel="stylesheet" href="./doc/style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>import "github/shuLhan/share"</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>import "github/shuLhan/share"</title> + <link rel="stylesheet" href="doc/style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>import "github/shuLhan/share"</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> <li><a href="#_command_line_interface">Command Line Interface</a></li> <li><a href="#_libraries">Libraries</a></li> <li><a href="#_changelog">Changelog</a></li> -<li><a href="#_documentations">Documentations</a> -<ul class="sectlevel2"> -<li><a href="#_development">Development</a></li> -</ul> -</li> +<li><a href="#_documentations">Documentations</a></li> <li><a href="#_credits">Credits</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> -<p><span class="image"><a class="image" href="https://godoc.org/github.com/shuLhan/share"><img src="https://godoc.org/github.com/shuLhan/share?status.svg" alt="GoDoc"></a></span> -<span class="image"><a class="image" href="https://goreportcard.com/report/github.com/shuLhan/share"><img src="https://goreportcard.com/badge/github.com/shuLhan/share" alt="Go Report Card"></a></span></p> +<p><span class="image"><img src="https://godoc.org/github.com/shuLhan/share?status.svg" alt="GoDoc"></span> +<span class="image"><img src="https://goreportcard.com/badge/github.com/shuLhan/share" alt="Go Report Card"></span></p> </div> <div class="paragraph"> <p>A collection of libraries and tools written in Go.</p> @@ -49,12 +53,12 @@ <div class="ulist"> <ul> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/cmd/gofmtcomment" target="_blank" rel="noopener"><strong>gofmtcomment</strong></a>: Program to convert -multilines "/*\*/" comment into single line "//" format.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/cmd/gofmtcomment"><strong>gofmtcomment</strong></a>: Program to convert + multilines "/**/" comment into single line "//" format.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/cmd/smtpcli" target="_blank" rel="noopener"><strong>smtpcli</strong></a>: Command smtpcli provide a command -line interface to SMTP client protocol.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/cmd/smtpcli"><strong>smtpcli</strong></a>: Command smtpcli provide a command + line interface to SMTP client protocol.</p> </li> </ul> </div> @@ -66,170 +70,170 @@ line interface to SMTP client protocol.</p> <div class="ulist"> <ul> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ascii" target="_blank" rel="noopener"><strong>ascii</strong></a>: A library for working with ASCII -characters.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ascii"><strong>ascii</strong></a>: A library for working with ASCII + characters.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/bytes" target="_blank" rel="noopener"><strong>bytes</strong></a>: A library for working with slice of -bytes.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/bytes"><strong>bytes</strong></a>: A library for working with slice of + bytes.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/contact" target="_blank" rel="noopener"><strong>contact</strong></a>: A library to import contact from -Google, Microsoft, or Yahoo</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/contact"><strong>contact</strong></a>: A library to import contact from + Google, Microsoft, or Yahoo</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/crypto" target="_blank" rel="noopener"><strong>crypto</strong></a>: Package crypto provide a wrapper -for standard crypto package.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/crypto"><strong>crypto</strong></a>: Package crypto provide a wrapper + for standard crypto package.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/dns" target="_blank" rel="noopener"><strong>dns</strong></a>: A library for working with Domain Name -System (DNS) protocol.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/dns"><strong>dns</strong></a>: A library for working with Domain Name + System (DNS) protocol.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/dsv" target="_blank" rel="noopener"><strong>dsv</strong></a>: A library for working with delimited -separated value (DSV).</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/dsv"><strong>dsv</strong></a>: A library for working with delimited + separated value (DSV).</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/email" target="_blank" rel="noopener"><strong>email</strong></a>: A library for working with Internet -Message Format as defined by RFC 5322.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/email"><strong>email</strong></a>: A library for working with Internet + Message Format as defined by RFC 5322.</p> <div class="ulist"> <ul> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/email/dkim" target="_blank" rel="noopener"><strong>dkim</strong></a>: A library to parse and create -DKIM-Signature header field value, as defined in RFC 6376.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/email/dkim"><strong>dkim</strong></a>: A library to parse and create + DKIM-Signature header field value, as defined in RFC 6376.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/email/maildir" target="_blank" rel="noopener"><strong>maildir</strong></a>: A library to manage email -using maildir format.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/email/maildir"><strong>maildir</strong></a>: A library to manage email + using maildir format.</p> </li> </ul> </div> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/errors" target="_blank" rel="noopener"><strong>errors</strong></a>: Package errors provide an error -type with code.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/errors"><strong>errors</strong></a>: Package errors provide an error + type with code.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/floats" target="_blank" rel="noopener"><strong>floats</strong></a>: A library for working with slice of -floats.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/floats"><strong>floats</strong></a>: A library for working with slice of + floats.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/git" target="_blank" rel="noopener"><strong>git</strong></a>: A wrapper for git command line interface.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/git"><strong>git</strong></a>: A wrapper for git command line interface.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/http" target="_blank" rel="noopener"><strong>http</strong></a>: Custom HTTP server with memory file -system and simplified routing handler.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/http"><strong>http</strong></a>: Custom HTTP server with memory file + system and simplified routing handler.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ini" target="_blank" rel="noopener"><strong>ini</strong></a>: A library for reading and writing INI -configuration as defined by Git configuration file syntax.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ini"><strong>ini</strong></a>: A library for reading and writing INI + configuration as defined by Git configuration file syntax.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ints" target="_blank" rel="noopener"><strong>ints</strong></a>: A library for working with slice of -integer.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ints"><strong>ints</strong></a>: A library for working with slice of + integer.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ints" target="_blank" rel="noopener"><strong>ints64</strong></a>: A library for working with slice of -64 bit integer.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/ints"><strong>ints64</strong></a>: A library for working with slice of + 64 bit integer.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/io" target="_blank" rel="noopener"><strong>io</strong></a>: A library for reading and watching file, -and reading from standard input.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/io"><strong>io</strong></a>: A library for reading and watching file, + and reading from standard input.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/memfs" target="_blank" rel="noopener"><strong>memfs</strong></a>: A library for mapping file system -into memory.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/memfs"><strong>memfs</strong></a>: A library for mapping file system + into memory.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining" target="_blank" rel="noopener"><strong>mining</strong></a>: A library for data mining.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining"><strong>mining</strong></a>: A library for data mining.</p> <div class="ulist"> <ul> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/classifier/cart" target="_blank" rel="noopener"><strong>classifier/cart</strong></a>: -Implementation of the Classification and Regression Tree by -Breiman, et al.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/classifier/cart"><strong>classifier/cart</strong></a>: + Implementation of the Classification and Regression Tree by + Breiman, et al.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/classifier/crf" target="_blank" rel="noopener"><strong>classififer/crf</strong></a>: -Implementation of the Cascaded Random Forest (CRF) algorithm, proposed by -Baumann, Florian, et al.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/classifier/crf"><strong>classififer/crf</strong></a>: + Implementation of the Cascaded Random Forest (CRF) algorithm, proposed by + Baumann, Florian, et al.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/classifier/rf" target="_blank" rel="noopener"><strong>classifier/rf</strong></a>: -Implementation of ensemble of classifiers using random forest algorithm by -Breiman and Cutler.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/classifier/rf"><strong>classifier/rf</strong></a>: + Implementation of ensemble of classifiers using random forest algorithm by + Breiman and Cutler.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/gain/gini" target="_blank" rel="noopener"><strong>gain/gini</strong></a>: A library to -calculate Gini gain.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/gain/gini"><strong>gain/gini</strong></a>: A library to + calculate Gini gain.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/knn" target="_blank" rel="noopener"><strong>knn</strong></a>: Implementation of the K -Nearest Neighbor (KNN) using Euclidian to compute the distance between -samples.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/knn"><strong>knn</strong></a>: Implementation of the K + Nearest Neighbor (KNN) using Euclidian to compute the distance between + samples.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/math" target="_blank" rel="noopener"><strong>math</strong></a>: A library for working with -mathematic.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/math"><strong>math</strong></a>: A library for working with + mathematic.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/resampling/lnsmote" target="_blank" rel="noopener"><strong>resampling/lnsmote</strong></a>: -Implementation of the Local-Neighborhood algorithm from the paper of -Maciejewski, Tomasz, and Jerzy Stefanowski.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/resampling/lnsmote"><strong>resampling/lnsmote</strong></a>: + Implementation of the Local-Neighborhood algorithm from the paper of + Maciejewski, Tomasz, and Jerzy Stefanowski.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/resampling/smote" target="_blank" rel="noopener"><strong>resampling/smote</strong></a>: -Implementation of the Synthetic Minority Oversampling TEchnique (SMOTE).</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/resampling/smote"><strong>resampling/smote</strong></a>: + Implementation of the Synthetic Minority Oversampling TEchnique (SMOTE).</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/tree/binary" target="_blank" rel="noopener"><strong>tree/binary</strong></a>: Implementation of -binary tree.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining/tree/binary"><strong>tree/binary</strong></a>: Implementation of + binary tree.</p> </li> </ul> </div> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/net" target="_blank" rel="noopener"><strong>net</strong></a>: Constants and library for networking.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/net"><strong>net</strong></a>: Constants and library for networking.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/numbers" target="_blank" rel="noopener"><strong>numbers</strong></a>: A library for working with -integer, float, slice of integer, and slice of floats.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/numbers"><strong>numbers</strong></a>: A library for working with + integer, float, slice of integer, and slice of floats.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/runes" target="_blank" rel="noopener"><strong>runes</strong></a>: A library for working with slice of -rune.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/runes"><strong>runes</strong></a>: A library for working with slice of + rune.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/smtp" target="_blank" rel="noopener"><strong>smtp</strong></a>: A library for building SMTP server or -client. -This package is working in progress.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/smtp"><strong>smtp</strong></a>: A library for building SMTP server or + client. + This package is working in progress.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/strings" target="_blank" rel="noopener"><strong>strings</strong></a>: A library for working with slice -of string.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/strings"><strong>strings</strong></a>: A library for working with slice + of string.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula" target="_blank" rel="noopener"><strong>tabula</strong></a>: A library for working with rows, -columns, or matrix (table), or in another terms working with data set.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula"><strong>tabula</strong></a>: A library for working with rows, + columns, or matrix (table), or in another terms working with data set.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/test" target="_blank" rel="noopener"><strong>test</strong></a>: A library for helping with testing.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/test"><strong>test</strong></a>: A library for helping with testing.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/text" target="_blank" rel="noopener"><strong>text</strong></a>: A library for working with text.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/text"><strong>text</strong></a>: A library for working with text.</p> <div class="ulist"> <ul> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/text/diff" target="_blank" rel="noopener"><strong>text/diff</strong></a>: Text comparison.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/text/diff"><strong>text/diff</strong></a>: Text comparison.</p> </li> </ul> </div> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/time" target="_blank" rel="noopener"><strong>time</strong></a>: A library for working with time.</p> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/time"><strong>time</strong></a>: A library for working with time.</p> </li> <li> -<p><a href="https://godoc.org/github.com/shuLhan/share/lib/websocket" target="_blank" rel="noopener"><strong>websocket</strong></a>: Websocket library for server +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/websocket"><strong>websocket</strong></a>: Websocket library for server and client. The websocket is tested with autobahn testsuite with 100% success rate. See <a href="https://github.com/shuLhan/share/tree/master/lib/websocket/AUTOBAHN.adoc">the status @@ -243,7 +247,7 @@ reports</a>.</p> <h2 id="_changelog">Changelog</h2> <div class="sectionbody"> <div class="paragraph"> -<p><a href="CHANGELOG.adoc" class="bare">CHANGELOG.adoc</a></p> +<p><a href="CHANGELOG.html">CHANGELOG</a>.</p> </div> </div> </div> @@ -252,7 +256,7 @@ reports</a>.</p> <div class="sectionbody"> <div class="paragraph"> <p>Beside <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a>, that provides documentation for API in packages, -there are also additional documentations that we can’t include inside source +there are also additional documentations that we can't include inside source code due to their scope and limitation of godoc formatting itself.</p> </div> <div class="admonitionblock note"> @@ -275,14 +279,14 @@ The links below is used to be viewed locally, not through Github. <ul> <li> <p><a href="doc/MIME_I_FORMAT.html">MIME Part One: Format of Internet Message -Bodies (RFC 2045)</a></p> + Bodies (RFC 2045)</a></p> </li> <li> <p><a href="doc/MIME_II_MEDIA_TYPES.html">MIME Part Two: Media Types (RFC 2046)</a></p> </li> <li> <p><a href="doc/MIME_V_CONFORMANCE.html">MIME Part Five: Conformance Criteria and -Examples (RFC 2049)</a></p> + Examples (RFC 2049)</a></p> </li> </ul> </div> @@ -293,22 +297,21 @@ Examples (RFC 2049)</a></p> <ul> <li> <p><a href="doc/SASL_PLAIN.html">The PLAIN Simple Authentication and Security -Layer (SASL) Mechanism (RFC 4616)</a></p> + Layer (SASL) Mechanism (RFC 4616)</a></p> </li> </ul> </div> </li> <li> <p><a href="doc/DKIM_OVERVIEW.html">DomainKeys Identified Mail Service Overview -(RFC 5585)</a></p> + (RFC 5585)</a></p> <div class="ulist"> <ul> <li> <p><a href="doc/DKIM_THREATS.html">Analysis of Threats Motivating DKIM (RFC 4686)</a></p> </li> <li> -<p><a href="doc/DKIM_DEVOPS.html">DKIM Development, Deployment, and Operations -(RFC 5863)</a></p> +<p><a href="doc/DKIM_DEVOPS.html">DKIM Development</a></p> </li> <li> <p><a href="doc/DKIM_SIGNATURES.html">DKIM Signatures (RFC 6376)</a></p> @@ -325,11 +328,11 @@ Layer (SASL) Mechanism (RFC 4616)</a></p> </li> <li> <p><a href="doc/ESMTP_TLS.html">SMTP Service Extension for Secure SMTP over -Transport Layer Security (RFC3207)</a></p> + Transport Layer Security (RFC3207)</a></p> </li> <li> <p><a href="doc/ESMTP_AUTH.html">SMTP Service Extension for Authentication -(RFC 4954)</a></p> + (RFC 4954)</a></p> </li> </ul> </div> @@ -339,24 +342,36 @@ Transport Layer Security (RFC3207)</a></p> </li> </ul> </div> -<div class="sect2"> -<h3 id="_development">Development</h3> <div class="paragraph"> -<p>The documentation created using asciidoctor. First, install <code>ruby</code> and -<code>bundler</code>, and then execute <code>bundler</code> on source root directory.</p> +<p>The documentation created using +<a href="https://github.com/shuLhan/ciigo"><code>ciigo</code></a>. +First, install <code>ciigo</code> command line interface,</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre>$ go install github.com/shuLhan/ciigo/cmd/ciigo</pre> +</div> </div> <div class="paragraph"> -<p>During development of documentation execute,</p> +<p>and then run</p> </div> <div class="listingblock"> <div class="content"> -<pre>$ bundler exec guard -i</pre> +<pre>$ ciigo -template=html.tmpl serve .</pre> </div> </div> <div class="paragraph"> -<p>to watch changes on documentation files (".adoc") and regenerate the HTML +<p>to serve documentation on HTTP server at <a href="http://127.0.0.1:8080 and watch" class="bare">http://127.0.0.1:8080 and watch</a> +changes on documentation files (".adoc") and regenerate the HTML files.</p> </div> +<div class="paragraph"> +<p>To generate HTML files for all asciidoc and markdown files, run</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre>$ ciigo -template=html.tmpl convert .</pre> +</div> </div> </div> </div> @@ -366,17 +381,22 @@ files.</p> <div class="ulist"> <ul> <li> -<p><a href="https://github.com/crossbario/autobahn-testsuite" target="_blank" rel="noopener">Autobahn testsuite</a></p> +<p><a href="https://github.com/crossbario/autobahn-testsuite">Autobahn testsuite</a></p> </li> </ul> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-06-14 18:59:06 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/DKIM_DEVOPS.html b/doc/DKIM_DEVOPS.html index d674d255..fc2cc860 100644 --- a/doc/DKIM_DEVOPS.html +++ b/doc/DKIM_DEVOPS.html @@ -1,94 +1,102 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>DomainKeys Identified Mail (DKIM) Development, Deployment, and Operations</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>DomainKeys Identified Mail (DKIM) Development, Deployment, and Operations</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>DomainKeys Identified Mail (DKIM) Development, Deployment, and Operations</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>DomainKeys Identified Mail (DKIM) Development, Deployment, and Operations</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a></li> -<li><a href="#_using_dkim_as_part_of_trust_assessment">2. Using DKIM as Part of Trust Assessment</a> +<li><a href="#_introduction">Introduction</a></li> +<li><a href="#_using_dkim_as_part_of_trust_assessment">Using DKIM as Part of Trust Assessment</a> <ul class="sectlevel2"> -<li><a href="#_a_systems_view_of_email_trust_assessment">2.1. A Systems View of Email Trust Assessment</a></li> -<li><a href="#_choosing_a_dkim_tag_for_the_assessment_identifier">2.2. Choosing a DKIM Tag for the Assessment Identifier</a></li> -<li><a href="#_choosing_the_signing_domain_name">2.3. Choosing the Signing Domain Name</a></li> -<li><a href="#_recipient_based_assessments">2.4. Recipient-Based Assessments</a></li> -<li><a href="#_filtering">2.5. Filtering</a></li> +<li><a href="#_a_systems_view_of_email_trust_assessment">A Systems View of Email Trust Assessment</a></li> +<li><a href="#_choosing_a_dkim_tag_for_the_assessment_identifier">Choosing a DKIM Tag for the Assessment Identifier</a></li> +<li><a href="#_choosing_the_signing_domain_name">Choosing the Signing Domain Name</a></li> +<li><a href="#_recipient_based_assessments">Recipient-Based Assessments</a></li> +<li><a href="#_filtering">Filtering</a></li> </ul> </li> -<li><a href="#_dkim_key_generation_storage_and_management">3. DKIM Key Generation, Storage, and Management</a> +<li><a href="#_dkim_key_generation_storage_and_management">DKIM Key Generation, Storage, and Management</a> <ul class="sectlevel2"> -<li><a href="#_private_key_management_deployment_and_ongoing_operations">3.1. Private Key Management: Deployment and Ongoing Operations</a></li> -<li><a href="#_storing_public_keys_dns_server_software_considerations">3.2. Storing Public Keys: DNS Server Software Considerations</a></li> -<li><a href="#_assignment_of_selectors">3.3. Assignment of Selectors</a></li> -<li><a href="#_per_user_signing_key_management_issues">3.4. Per-User Signing Key Management Issues</a></li> -<li><a href="#_third_party_signer_key_management_and_selector_administration">3.5. Third-Party Signer Key Management and Selector Administration</a></li> -<li><a href="#_key_pair_selector_life_cycle_management">3.6. Key Pair / Selector Life Cycle Management</a></li> +<li><a href="#_private_key_management_deployment_and_ongoing_operations">Private Key Management: Deployment and Ongoing Operations</a></li> +<li><a href="#_storing_public_keys_dns_server_software_considerations">Storing Public Keys: DNS Server Software Considerations</a></li> +<li><a href="#_assignment_of_selectors">Assignment of Selectors</a></li> +<li><a href="#_per_user_signing_key_management_issues">Per-User Signing Key Management Issues</a></li> +<li><a href="#_third_party_signer_key_management_and_selector_administration">Third-Party Signer Key Management and Selector Administration</a></li> +<li><a href="#_key_pair_selector_life_cycle_management">Key Pair / Selector Life Cycle Management</a></li> </ul> </li> -<li><a href="#_signing">4. Signing</a> +<li><a href="#_signing">Signing</a> <ul class="sectlevel2"> -<li><a href="#_dns_record">4.1. DNS Record</a></li> -<li><a href="#_signing_module">4.2. Signing Module</a></li> -<li><a href="#_signing_policies_and_practices">4.3. Signing Policies and Practices</a></li> +<li><a href="#_dns_record">DNS Record</a></li> +<li><a href="#_signing_module">Signing Module</a></li> +<li><a href="#_signing_policies_and_practices">Signing Policies and Practices</a></li> </ul> </li> -<li><a href="#_verifying">5. Verifying</a> +<li><a href="#_verifying">Verifying</a> <ul class="sectlevel2"> -<li><a href="#_intended_scope_of_use">5.1. Intended Scope of Use</a></li> -<li><a href="#_signature_scope">5.2. Signature Scope</a></li> -<li><a href="#_design_scope_of_use">5.3. Design Scope of Use</a></li> -<li><a href="#_inbound_mail_filtering">5.4. Inbound Mail Filtering</a></li> -<li><a href="#_messages_sent_through_mailing_lists_and_other_intermediaries">5.5. Messages Sent through Mailing Lists and Other Intermediaries</a></li> -<li><a href="#_generation_transmission_and_use_of_results_headers">5.6. Generation, Transmission, and Use of Results Headers</a></li> +<li><a href="#_intended_scope_of_use">Intended Scope of Use</a></li> +<li><a href="#_signature_scope">Signature Scope</a></li> +<li><a href="#_design_scope_of_use">Design Scope of Use</a></li> +<li><a href="#_inbound_mail_filtering">Inbound Mail Filtering</a></li> +<li><a href="#_messages_sent_through_mailing_lists_and_other_intermediaries">Messages Sent through Mailing Lists and Other Intermediaries</a></li> +<li><a href="#_generation_transmission_and_use_of_results_headers">Generation, Transmission, and Use of Results Headers</a></li> </ul> </li> -<li><a href="#_taxonomy_of_signatures">6. Taxonomy of Signatures</a> +<li><a href="#_taxonomy_of_signatures">Taxonomy of Signatures</a> <ul class="sectlevel2"> -<li><a href="#_single_domain_signature">6.1. Single Domain Signature</a></li> -<li><a href="#_parent_domain_signature">6.2. Parent Domain Signature</a></li> -<li><a href="#_third_party_signature">6.3. Third Party Signature</a></li> -<li><a href="#_using_trusted_third_party_ttp_senders">6.4. Using Trusted Third Party (TTP) Senders</a></li> -<li><a href="#_multiple_signatures">6.5. Multiple Signatures</a></li> +<li><a href="#_single_domain_signature">Single Domain Signature</a></li> +<li><a href="#_parent_domain_signature">Parent Domain Signature</a></li> +<li><a href="#_third_party_signature">Third Party Signature</a></li> +<li><a href="#_using_trusted_third_party_ttp_senders">Using Trusted Third Party (TTP) Senders</a></li> +<li><a href="#_multiple_signatures">Multiple Signatures</a></li> </ul> </li> -<li><a href="#_example_usage_scenarios">7. Example Usage Scenarios</a> +<li><a href="#_example_usage_scenarios">Example Usage Scenarios</a> <ul class="sectlevel2"> -<li><a href="#_authors_organization_simple">7.1. Author’s Organization - Simple</a></li> -<li><a href="#_authors_organization_differentiated_types_of_mail">7.2. Author’s Organization - Differentiated Types of Mail</a></li> -<li><a href="#_author_domain_signing_practices_adsp">7.3. Author Domain Signing Practices (ADSP)</a></li> -<li><a href="#_delegated_signing">7.4. Delegated Signing</a></li> -<li><a href="#_independent_third_party_service_providers">7.5. Independent Third-Party Service Providers</a></li> -<li><a href="#_mail_streams_based_on_behavioral_assessment">7.6. Mail Streams Based on Behavioral Assessment</a></li> -<li><a href="#_agent_or_mediator_signatures">7.7. Agent or Mediator Signatures</a></li> +<li><a href="#_author_s_organization_simple">Author's Organization - Simple</a></li> +<li><a href="#_author_s_organization_differentiated_types_of_mail">Author's Organization - Differentiated Types of Mail</a></li> +<li><a href="#_author_domain_signing_practices_adsp">Author Domain Signing Practices (ADSP)</a></li> +<li><a href="#_delegated_signing">Delegated Signing</a></li> +<li><a href="#_independent_third_party_service_providers">Independent Third-Party Service Providers</a></li> +<li><a href="#_mail_streams_based_on_behavioral_assessment">Mail Streams Based on Behavioral Assessment</a></li> +<li><a href="#_agent_or_mediator_signatures">Agent or Mediator Signatures</a></li> </ul> </li> -<li><a href="#_usage_considerations">8. Usage Considerations</a> +<li><a href="#_usage_considerations">Usage Considerations</a> <ul class="sectlevel2"> -<li><a href="#_a_non_standard_submission_and_delivery_scenarios">8.1. A Non-Standard Submission and Delivery Scenarios</a></li> -<li><a href="#_protection_of_internal_mail">8.2. Protection of Internal Mail</a></li> -<li><a href="#_signature_granularity">8.3. Signature Granularity</a></li> -<li><a href="#_email_infrastructure_agents">8.4. Email Infrastructure Agents</a></li> -<li><a href="#_mail_user_agent">8.5. Mail User Agent</a></li> +<li><a href="#_a_non_standard_submission_and_delivery_scenarios">A Non-Standard Submission and Delivery Scenarios</a></li> +<li><a href="#_protection_of_internal_mail">Protection of Internal Mail</a></li> +<li><a href="#_signature_granularity">Signature Granularity</a></li> +<li><a href="#_email_infrastructure_agents">Email Infrastructure Agents</a></li> +<li><a href="#_mail_user_agent">Mail User Agent</a></li> </ul> </li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -98,7 +106,7 @@ Deployment, and Operations.</p> </div> </div> <div class="sect1"> -<h2 id="_introduction">1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> <p>This document provides practical tips for those who are developing DKIM @@ -108,14 +116,15 @@ DKIM verification, and DNS servers.</p> </div> </div> <div class="sect1"> -<h2 id="_using_dkim_as_part_of_trust_assessment">2. Using DKIM as Part of Trust Assessment</h2> +<h2 id="_using_dkim_as_part_of_trust_assessment">Using DKIM as Part of Trust Assessment</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_a_systems_view_of_email_trust_assessment">2.1. A Systems View of Email Trust Assessment</h3> +<h3 id="_a_systems_view_of_email_trust_assessment">A Systems View of Email Trust Assessment</h3> <div class="paragraph"> <p>DKIM only claim about message content is that the content cited in the -"DKIM-Signature:" field’s "h=" tag has been delivered without modification. -That is, it asserts message content integrity — between signing and verifying — not message content validity.</p> +"DKIM-Signature:" field's "h=" tag has been delivered without modification. +That is, it asserts message content integrity -- between signing and verifying +-- not message content validity.</p> </div> <div class="literalblock"> <div class="content"> @@ -125,21 +134,21 @@ That is, it asserts message content integrity — between signin | ^ | | | +------+------+ - | -->| Handling |<-- - | -->| Filter |<-- + | -->| Handling |<-- + | -->| Filter |<-- | +-------------+ | ^ V Responsible | +-------------+ Identifier +------+------+ - | Responsible |. . . . . . . . . . .>| Identity | + | Responsible |. . . . . . . . . . .>| Identity | | Identity | . . | Assessor | +------+------+ . . +-------------+ | V . ^ ^ V . . | | +------------------.-------.--------------------+ | | - | +------+------+ . . . > . +-------------+ | | | +-----------+ + | +------+------+ . . . > . +-------------+ | | | +-----------+ | | Identifier | | Identifier +--|--+ +--+ Assessment| - | | Signer +------------->| Validator | | | Databases | + | | Signer +------------->| Validator | | | Databases | | +-------------+ +-------------+ | +-----------+ | DKIM Service | +-----------------------------------------------+ @@ -149,7 +158,7 @@ That is, it asserts message content integrity — between signin </div> </div> <div class="sect2"> -<h3 id="_choosing_a_dkim_tag_for_the_assessment_identifier">2.2. Choosing a DKIM Tag for the Assessment Identifier</h3> +<h3 id="_choosing_a_dkim_tag_for_the_assessment_identifier">Choosing a DKIM Tag for the Assessment Identifier</h3> <div class="paragraph"> <p>DKIM has three values that specify identification information and it is easy to confuse their use, although only one defines the formal input and output of @@ -157,7 +166,7 @@ DKIM, with the other two being used for internal protocol functioning and adjunct purposes, such as auditing and debugging.</p> </div> <div class="paragraph"> -<p>DKIM’s primary task is to communicate from the Signer to a recipient-side +<p>DKIM's primary task is to communicate from the Signer to a recipient-side Identity Assessor a single Signing Domain Identifier (SDID) that refers to a responsible identity. DKIM MAY optionally provide a single responsible Agent or User Identifier @@ -167,7 +176,7 @@ A receive-side DKIM verifier MUST communicate the Signing Domain Identifier Agent Identifier (i=) if present. To the extent that a receiver attempts to intuit any structured semantics for either of the identifiers, this is a heuristic function that is outside the -scope of DKIM’s specification and semantics.</p> +scope of DKIM's specification and semantics.</p> </div> <div class="paragraph"> <p>The single, mandatory value that DKIM supplies as its output is:</p> @@ -187,9 +196,9 @@ be used for the same SDID. As discussed in Section 4.3 of [RFC5585],</p> </div> <div class="paragraph"> -<p>"If verifiers were to employ the selector as part of an assessment mechanism, +<p>"If verifiers were to employ the selector as part of an assessment mechanism, then there would be no remaining mechanism for making a transition from an -old, or compromised, key to a new one".</p> +old, or compromised, key to a new one".</p> </div> <div class="paragraph"> <p>Consequently, the selector is not appropriate for use as part or all of the @@ -201,8 +210,8 @@ This tag is optional and provides the Agent or User Identifier (AUID) on behalf of which the SDID is taking responsibility [RFC5672]. The identity can be in the syntax of an entire email address or only a domain name. -The domain name can be the same as for "d=" or it can be a sub-name of the -"d=" name.</p> +The domain name can be the same as for "d=" or it can be a sub-name of the +"d=" name.</p> </div> <div class="admonitionblock note"> <table> @@ -211,29 +220,29 @@ The domain name can be the same as for "d=" or it can be a sub-name of the <div class="title">Note</div> </td> <td class="content"> -Although the "i=" identity has the syntax of an email address, it is not +Although the "i=" identity has the syntax of an email address, it is not required to have those semantics. -That is, "the identity of the user" need not be the same as the user’s +That is, "the identity of the user" need not be the same as the user's mailbox. -For example, the signer might wish to use "i=" to encode user-related audit +For example, the signer might wish to use "i=" to encode user-related audit information, such as how they were accessing the service at the time of message posting. -Therefore, it is not possible to conclude anything from the "i=" string’s +Therefore, it is not possible to conclude anything from the "i=" string's (dis)similarity to email addresses elsewhere in the header. </td> </tr> </table> </div> <div class="paragraph"> -<p>So, "i=" can have any of these properties:</p> +<p>So, "i=" can have any of these properties:</p> </div> <div class="ulist"> <ul> <li> -<p>Be a valid domain when it is the same as "d="</p> +<p>Be a valid domain when it is the same as "d="</p> </li> <li> -<p>Appear to be a subdomain of "d=" but might not even exist</p> +<p>Appear to be a subdomain of "d=" but might not even exist</p> </li> <li> <p>Look like a mailbox address but might have different semantics and @@ -250,21 +259,21 @@ for the specific posting</p> represent any semantics, known only to the signer.</p> </div> <div class="paragraph"> -<p>Hence, "i=" serves well as a token that is usable like a Web cookie, for -return to the signing Administrative Management Domain (ADMD) — such as for +<p>Hence, "i=" serves well as a token that is usable like a Web cookie, for +return to the signing Administrative Management Domain (ADMD) -- such as for auditing and debugging. -Of course in some scenarios the "i=" string might provide a useful adjunct +Of course in some scenarios the "i=" string might provide a useful adjunct value for additional (heuristic) processing by the Handling Filter.</p> </div> </div> <div class="sect2"> -<h3 id="_choosing_the_signing_domain_name">2.3. Choosing the Signing Domain Name</h3> +<h3 id="_choosing_the_signing_domain_name">Choosing the Signing Domain Name</h3> <div class="paragraph"> <p>For an entity creating DKIM signatures, it is likely that different portions of its mail will warrant different levels of trust.</p> </div> <div class="paragraph"> -<p>It is therefore likely to be useful for a signer to use different "d=" +<p>It is therefore likely to be useful for a signer to use different "d=" subdomain names, for different message traffic streams, so that receivers can make differential assessments.</p> </div> @@ -283,7 +292,7 @@ over time, so the scheme needs to be flexible.</p> </div> </div> <div class="sect2"> -<h3 id="_recipient_based_assessments">2.4. Recipient-Based Assessments</h3> +<h3 id="_recipient_based_assessments">Recipient-Based Assessments</h3> <div class="paragraph"> <p>With DKIM, the Assessor can know that two messages with the same SDID are, in fact, signed by the same person or organization. @@ -298,45 +307,32 @@ for the identifier(s).</p> </div> </div> <div class="sect2"> -<h3 id="_filtering">2.5. Filtering</h3> -<table class="tableblock frame-all grid-all stretch"> -<caption class="title">Table 1. Trust versus Risk Handling Tradeoffs Example</caption> -<colgroup> -<col style="width: 25%;"> -<col style="width: 25%;"> -<col style="width: 25%;"> -<col style="width: 25%;"> -</colgroup> -<tbody> -<tr> -<td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock">Stream Risk</p></td> -<td class="tableblock halign-center valign-top" colspan="3"><p class="tableblock">Organizational Trust</p></td> -</tr> -<tr> -<td class="tableblock halign-center valign-top"><p class="tableblock">Low</p></td> -<td class="tableblock halign-center valign-top"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-center valign-top"><p class="tableblock">High</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">BENIGN: Moderate filter</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">DILIGENT: Mild filter</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">PRISTINE: Accept</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">UNKNOWN: Strong filter</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">TYPICAL: Targeted filter</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">PROTECTED: Accept and Contact</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">MALICIOUS: Block and Counter</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">NEGLIGENT: Block</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">COMPROMISED: Block and Contact</p></td> -</tr> -</tbody> -</table> +<h3 id="_filtering">Filtering</h3> +<div class="paragraph"> +<div class="doctitle">Trust versus Risk Handling Tradeoffs Example</div> +<p>|=== +.2^.^| Stream Risk 3^| Organizational Trust +^| Low ^| Medium ^| High</p> +</div> +<div class="paragraph"> +<p>| Low +| BENIGN: Moderate filter +| DILIGENT: Mild filter +| PRISTINE: Accept</p> +</div> +<div class="paragraph"> +<p>| Medium +| UNKNOWN: Strong filter +| TYPICAL: Targeted filter +| PROTECTED: Accept and Contact</p> +</div> +<div class="paragraph"> +<p>| High +| MALICIOUS: Block and Counter +| NEGLIGENT: Block +| COMPROMISED: Block and Contact +|===</p> +</div> <div class="dlist"> <dl> <dt class="hdlist1">Stream Risk</dt> @@ -381,7 +377,7 @@ In other words, the paramount concern, here, is false positives.</p> <dt class="hdlist1">Unknown</dt> <dd> <p>There is no history with the organization. -Apply an aggressive level of "naive" filtering, given the nature of the public +Apply an aggressive level of "naive" filtering, given the nature of the public email environment.</p> </dd> <dt class="hdlist1">Typical</dt> @@ -404,7 +400,7 @@ resolve the matter.</p> <dd> <p>A persistently problematic message stream is coming from an organization that appears to contribute to the problem. -The stream will be blocked, but the organization’s role is sufficiently +The stream will be blocked, but the organization's role is sufficiently troubling to warrant following up with others in the anti-abuse or legal communities, to constrain or end their impact.</p> </dd> @@ -428,10 +424,10 @@ resolve the matter.</p> </div> </div> <div class="sect1"> -<h2 id="_dkim_key_generation_storage_and_management">3. DKIM Key Generation, Storage, and Management</h2> +<h2 id="_dkim_key_generation_storage_and_management">DKIM Key Generation, Storage, and Management</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_private_key_management_deployment_and_ongoing_operations">3.1. Private Key Management: Deployment and Ongoing Operations</h3> +<h3 id="_private_key_management_deployment_and_ongoing_operations">Private Key Management: Deployment and Ongoing Operations</h3> <div class="paragraph"> <p>Best practices on key managements,</p> </div> @@ -496,7 +492,7 @@ to use a different key to enable accountability and auditing.</p> </div> </div> <div class="sect2"> -<h3 id="_storing_public_keys_dns_server_software_considerations">3.2. Storing Public Keys: DNS Server Software Considerations</h3> +<h3 id="_storing_public_keys_dns_server_software_considerations">Storing Public Keys: DNS Server Software Considerations</h3> <div class="paragraph"> <p>Ideally, DNS Security (DNSSEC) [RFC4034] needs to be employed in a configuration that provides protection against record insertion attacks and @@ -504,14 +500,14 @@ zone enumeration.</p> </div> </div> <div class="sect2"> -<h3 id="_assignment_of_selectors">3.3. Assignment of Selectors</h3> +<h3 id="_assignment_of_selectors">Assignment of Selectors</h3> <div class="paragraph"> <p>It is intended that assessments of DKIM identities be based on the domain name, and not include the selector.</p> </div> </div> <div class="sect2"> -<h3 id="_per_user_signing_key_management_issues">3.4. Per-User Signing Key Management Issues</h3> +<h3 id="_per_user_signing_key_management_issues">Per-User Signing Key Management Issues</h3> <div class="paragraph"> <p>If per-user signing keys are assigned for internal purposes, the following issues need to be considered before using such signatures as an alternative to @@ -537,7 +533,7 @@ administrator running an edge MTA.</p> </div> </div> <div class="sect2"> -<h3 id="_third_party_signer_key_management_and_selector_administration">3.5. Third-Party Signer Key Management and Selector Administration</h3> +<h3 id="_third_party_signer_key_management_and_selector_administration">Third-Party Signer Key Management and Selector Administration</h3> <div class="paragraph"> <p>Best practices when signer is handled by other provider,</p> </div> @@ -557,7 +553,7 @@ component to the third-party signer.</p> </div> </div> <div class="sect2"> -<h3 id="_key_pair_selector_life_cycle_management">3.6. Key Pair / Selector Life Cycle Management</h3> +<h3 id="_key_pair_selector_life_cycle_management">Key Pair / Selector Life Cycle Management</h3> <div class="paragraph"> <p>Example of key deployment process,</p> </div> @@ -639,12 +635,12 @@ public-key data (p=) field, or deletes the key selector record entirely.</p> </li> <li> <p>As far as the verifier is concerned, there is no functional difference -between verifying against a key selector with an empty "p=" field, and +between verifying against a key selector with an empty "p=" field, and verifying against a missing key selector: both result in a failed signature and the signature needs to be treated as if it had not been there. -However, there is a minor semantic difference: with the empty "p=" field, the +However, there is a minor semantic difference: with the empty "p=" field, the signer is explicitly stating that the key has been revoked. -The empty "p=" record provides a gravestone for an old selector, making it less +The empty "p=" record provides a gravestone for an old selector, making it less likely that the selector might be accidentally reused with a different public key.</p> </li> @@ -654,7 +650,7 @@ key.</p> </div> </div> <div class="sect1"> -<h2 id="_signing">4. Signing</h2> +<h2 id="_signing">Signing</h2> <div class="sectionbody"> <div class="paragraph"> <p>Signing a message require two services,</p> @@ -666,28 +662,28 @@ key.</p> </li> <li> <p>A trusted service where outgoing email within organization will be added the -"DKIM-Signature:" header field.</p> +"DKIM-Signature:" header field.</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_dns_record">4.1. DNS Record</h3> +<h3 id="_dns_record">DNS Record</h3> <div class="paragraph"> <p>Initial DKIM DNS information is contained within TXT RRs.</p> </div> <div class="paragraph"> -<p>The "DKIM-Signature:" header in the message contains the "d=" tag with the +<p>The "DKIM-Signature:" header in the message contains the "d=" tag with the basic domain name doing the signing and serving as output to the Identity Assessor and the s= tag with the selector that is added to the name, for finding the specific public key. -Hence, the relevant "<selector>._domainkey.<domain-name>" DNS record needs to +Hence, the relevant "<selector>._domainkey.<domain-name>" DNS record needs to contain a DKIM-related RR that provides the public key information</p> </div> </div> <div class="sect2"> -<h3 id="_signing_module">4.2. Signing Module</h3> +<h3 id="_signing_module">Signing Module</h3> <div class="paragraph"> -<p>The module doing signing can be placed anywhere within an organization’s +<p>The module doing signing can be placed anywhere within an organization's trusted Administrative Management Domain (ADMD); obvious choices include department-level posting agents, as well as outbound boundary MTAs to the open Internet.</p> @@ -700,7 +696,7 @@ into software.</p> </div> </div> <div class="sect2"> -<h3 id="_signing_policies_and_practices">4.3. Signing Policies and Practices</h3> +<h3 id="_signing_policies_and_practices">Signing Policies and Practices</h3> <div class="paragraph"> <p>Every organization (ADMD) will have its own policies and practices for deciding when to sign messages (message stream) and with what domain name, @@ -710,17 +706,17 @@ selector, and key.</p> </div> </div> <div class="sect1"> -<h2 id="_verifying">5. Verifying</h2> +<h2 id="_verifying">Verifying</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_intended_scope_of_use">5.1. Intended Scope of Use</h3> +<h3 id="_intended_scope_of_use">Intended Scope of Use</h3> <div class="paragraph"> <p>DKIM requires that a message with a signature that is found to be invalid is to be treated as if the message had not been signed at all.</p> </div> <div class="paragraph"> <p>If a DKIM signature fails to verify, it is entirely possible that the message -is valid and that either there is a configuration error in the signer’s system +is valid and that either there is a configuration error in the signer's system (e.g., a missing key record) or that the message was inadvertently modified in transit. If messages with invalid signatures were to be treated preferentially to @@ -729,14 +725,14 @@ signature blocks to gain the preferential treatment.</p> </div> </div> <div class="sect2"> -<h3 id="_signature_scope">5.2. Signature Scope</h3> +<h3 id="_signature_scope">Signature Scope</h3> <div class="paragraph"> <p>Verifiers need to consider only the part of the message that is inside the scope of the message as being authenticated by the signature.</p> </div> </div> <div class="sect2"> -<h3 id="_design_scope_of_use">5.3. Design Scope of Use</h3> +<h3 id="_design_scope_of_use">Design Scope of Use</h3> <div class="paragraph"> <p>Valid DKIM signature does not represent proof positive that a valid claim of responsibility was made for it by the indicated party, that the message is @@ -764,7 +760,7 @@ for the zone from which the key record was retrieved.</p> </div> </div> <div class="sect2"> -<h3 id="_inbound_mail_filtering">5.4. Inbound Mail Filtering</h3> +<h3 id="_inbound_mail_filtering">Inbound Mail Filtering</h3> <div class="paragraph"> <p>Messages that carry a valid DKIM signature from a trusted source can be whitelisted, avoiding the need to perform computation and hence @@ -778,7 +774,7 @@ header data entirely.</p> </div> </div> <div class="sect2"> -<h3 id="_messages_sent_through_mailing_lists_and_other_intermediaries">5.5. Messages Sent through Mailing Lists and Other Intermediaries</h3> +<h3 id="_messages_sent_through_mailing_lists_and_other_intermediaries">Messages Sent through Mailing Lists and Other Intermediaries</h3> <div class="paragraph"> <p>The intermediary that change the message content are strongly encouraged to deploy DKIM signing so that a verifiable claim of responsibility remains @@ -786,7 +782,7 @@ available to parties attempting to verify the modified message.</p> </div> </div> <div class="sect2"> -<h3 id="_generation_transmission_and_use_of_results_headers">5.6. Generation, Transmission, and Use of Results Headers</h3> +<h3 id="_generation_transmission_and_use_of_results_headers">Generation, Transmission, and Use of Results Headers</h3> <div class="paragraph"> <p>Consider the cases where:</p> </div> @@ -813,19 +809,19 @@ prevent insertion of a message that carries a bogus results header.</p> </div> </div> <div class="sect1"> -<h2 id="_taxonomy_of_signatures">6. Taxonomy of Signatures</h2> +<h2 id="_taxonomy_of_signatures">Taxonomy of Signatures</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_single_domain_signature">6.1. Single Domain Signature</h3> +<h3 id="_single_domain_signature">Single Domain Signature</h3> <div class="paragraph"> <p>The simplest case is when an organization use their own domain in the SDID of the signatures. -The addresses in the "RFC5322.From" field would also be organization’s domain +The addresses in the "RFC5322.From" field would also be organization's domain name.</p> </div> </div> <div class="sect2"> -<h3 id="_parent_domain_signature">6.2. Parent Domain Signature</h3> +<h3 id="_parent_domain_signature">Parent Domain Signature</h3> <div class="paragraph"> <p>An organization with multiple active subdomains may apply the same (single) signature domain to mail from all subdomains.</p> @@ -835,11 +831,11 @@ signature domain to mail from all subdomains.</p> be to leverage the AUID [RFC5672] (i= tag) in the DKIM signature to differentiate the mail streams. For example, marketing email would be signed with -"i=@marketing.domain.example" and "d=domain.example".</p> +"i=@marketing.domain.example" and "d=domain.example".</p> </div> </div> <div class="sect2"> -<h3 id="_third_party_signature">6.3. Third Party Signature</h3> +<h3 id="_third_party_signature">Third Party Signature</h3> <div class="paragraph"> <p>A signature whose domain does not match the domain of the RFC5322.From address is sometimes referred to as a third-party signature.</p> @@ -857,7 +853,7 @@ Such provider can DKIM-sign outbound mail with their own identifier.</p> <p><strong>Parent Domain</strong>: As discussed above, organizations choosing to apply a parent-domain signature to mail originating from subdomains can have their signatures treated as third -party by some verifiers, depending on whether or not the "t=s" tag is used to +party by some verifiers, depending on whether or not the "t=s" tag is used to constrain the parent signature to apply only to its own specific domain.</p> </div> <div class="paragraph"> @@ -867,20 +863,20 @@ vouched for by that third party.</p> </div> </div> <div class="sect2"> -<h3 id="_using_trusted_third_party_ttp_senders">6.4. Using Trusted Third Party (TTP) Senders</h3> +<h3 id="_using_trusted_third_party_ttp_senders">Using Trusted Third Party (TTP) Senders</h3> <div class="paragraph"> <p>A different model arises when an organization uses a trusted third-party sender for certain key business functions, but still wants that email to -benefit from the organization’s own identity and reputation.</p> +benefit from the organization's own identity and reputation.</p> </div> <div class="paragraph"> <p>This can be done by having the third party generate a key pair that is designated uniquely for use by that trusted third party and publishing the -public key in the controlling organization’s DNS domain, thus enabling the +public key in the controlling organization's DNS domain, thus enabling the third party to sign mail using the signature of the controlling organization.</p> </div> <div class="sect3"> -<h4 id="_dns_delegation">6.4.1. DNS Delegation</h4> +<h4 id="_dns_delegation">DNS Delegation</h4> <div class="paragraph"> <p>In this case, Company A would create a subdomain benefits.companya.example, and delegate the DNS management of that subdomain to the benefits company @@ -891,7 +887,7 @@ delegation record.</p> </div> </div> <div class="sect2"> -<h3 id="_multiple_signatures">6.5. Multiple Signatures</h3> +<h3 id="_multiple_signatures">Multiple Signatures</h3> <div class="paragraph"> <p>One important caveat to the use of multiple signatures is that there is currently no clear consensus among receivers on how they plan to handle them. @@ -918,8 +914,8 @@ might choose to sign with distinct subdomain identities to enable each subdomain to manage its own identity. However, it might also want to provide a common identity that cuts across all of the distinct subdomains. For example, Company A can sign mail for its sales department with a signature -where "d=sales.companya.example" and a second signature where -"d=companya.example".</p> +where "d=sales.companya.example" and a second signature where +"d=companya.example".</p> </li> <li> <p>Service Providers. @@ -929,12 +925,12 @@ with either its own identity or an identity unique to each of its clients However, it can also do both: sign each outbound message with its own identity as well as with the identity of each individual client. For example, ESP A might sign mail for its client Company B with its service -provider signature "d=espa.example", and a second client-specific signature -where "d=" either "companyb.example" or "companyb.espa.example".</p> +provider signature "d=espa.example", and a second client-specific signature +where "d=" either "companyb.example" or "companyb.espa.example".</p> </li> <li> <p>Forwarders. -Some forwarders such as mailing lists or "forward article to a friend" +Some forwarders such as mailing lists or "forward article to a friend" services might choose to add their own signatures to outbound messages to vouch for them having legitimately originated from the designated service. In this case, the signature would be added even in the presence of a @@ -950,9 +946,9 @@ signatures needs to sign its forwarded messages.</p> <ul> <li> <p>Reputation Providers. -It is possible that they, or other organizations willing to put their "seal of -approval" on an email stream, might choose to use a DKIM signature to do it. -In nearly all cases, this "reputation" signature would be in addition to the +It is possible that they, or other organizations willing to put their "seal of +approval" on an email stream, might choose to use a DKIM signature to do it. +In nearly all cases, this "reputation" signature would be in addition to the author or originator signature.</p> </li> </ul> @@ -961,13 +957,13 @@ author or originator signature.</p> </div> </div> <div class="sect1"> -<h2 id="_example_usage_scenarios">7. Example Usage Scenarios</h2> +<h2 id="_example_usage_scenarios">Example Usage Scenarios</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section provides some examples of usage scenarios for DKIM deployments.</p> </div> <div class="sect2"> -<h3 id="_authors_organization_simple">7.1. Author’s Organization - Simple</h3> +<h3 id="_author_s_organization_simple">Author's Organization - Simple</h3> <div class="paragraph"> <p>In this scenario, Company A need only generate a single signing key and publish it under their top-level domain (companya.example); the signing module @@ -975,16 +971,16 @@ would then tailor the AUID value as needed at signing time.</p> </div> </div> <div class="sect2"> -<h3 id="_authors_organization_differentiated_types_of_mail">7.2. Author’s Organization - Differentiated Types of Mail</h3> +<h3 id="_author_s_organization_differentiated_types_of_mail">Author's Organization - Differentiated Types of Mail</h3> <div class="paragraph"> <p>An organization may distinguish email from several department, where each department may have their own subdomain with its unique signing keys.</p> </div> </div> <div class="sect2"> -<h3 id="_author_domain_signing_practices_adsp">7.3. Author Domain Signing Practices (ADSP)</h3> +<h3 id="_author_domain_signing_practices_adsp">Author Domain Signing Practices (ADSP)</h3> <div class="sect3"> -<h4 id="_introduction_2">7.3.1. Introduction</h4> +<h4 id="_introduction_2">Introduction</h4> <div class="paragraph"> <p>A domain might decide to sign all of their outgoing mail. In such a configuration, the absence of a signature would be more significant @@ -999,14 +995,14 @@ risk of phishing attacks against the likelihood of undelivered mail.</p> </div> </div> <div class="sect3"> -<h4 id="_a_few_definitions">7.3.2. A Few Definitions</h4> +<h4 id="_a_few_definitions">A Few Definitions</h4> <div class="paragraph"> <p>An address in the RFC5322.From header field of a message is defined as an -"Author Address", and an "Author Domain" is defined as anything to the right -of the '@' in an author address.</p> +"Author Address", and an "Author Domain" is defined as anything to the right +of the '@' in an author address.</p> </div> <div class="paragraph"> -<p>An "Author Signature" is thus any valid signature where the value of the SDID +<p>An "Author Signature" is thus any valid signature where the value of the SDID matches an author domain in the message.</p> </div> <div class="paragraph"> @@ -1017,20 +1013,20 @@ failures.</p> </div> </div> <div class="sect3"> -<h4 id="_some_adsp_examples">7.3.3. Some ADSP Examples</h4> +<h4 id="_some_adsp_examples">Some ADSP Examples</h4> <div class="paragraph"> <p>An organization (Company A) can specify its signing practices by -publishing an ADSP record with "dkim=all" or "dkim=discardable". +publishing an ADSP record with "dkim=all" or "dkim=discardable". Any email with an RFC5322.From address that uses the domain where the ADSP record is published that does not have a valid author signature is at risk of being misdelivered or discarded.</p> </div> <div class="paragraph"> -<p>For example, email with an RFC5322.From address of "bob@companyA.example" -needs to have an author signature where the SDID value is "companyA.example" +<p>For example, email with an RFC5322.From address of "bob@companyA.example" +needs to have an author signature where the SDID value is "companyA.example" or it will fail an ADSP validation. -If a message with an RFC5322.From address of "newsletter@companyA.example" has -a signature with "d=marketing.companyA.example", that message will fail the +If a message with an RFC5322.From address of "newsletter@companyA.example" has +a signature with "d=marketing.companyA.example", that message will fail the ADSP check because the signature would not be considered a valid author signature.</p> </div> @@ -1038,14 +1034,14 @@ signature.</p> <p>In particular, in order to prevent mail from being negatively impacted or even discarded at the receiver, it is essential to perform a thorough survey of outbound mail from a domain before publishing an ADSP policy of anything -stronger than "unknown".</p> +stronger than "unknown".</p> </div> </div> </div> <div class="sect2"> -<h3 id="_delegated_signing">7.4. Delegated Signing</h3> +<h3 id="_delegated_signing">Delegated Signing</h3> <div class="paragraph"> -<p>A company might outsource its department’s mail service to other provider. +<p>A company might outsource its department's mail service to other provider. For example, Company A with marketing department, marketing.company-a.example, might be managed by provider X.</p> </div> @@ -1056,7 +1052,7 @@ In other words, the provider X would generate keys.</p> </div> </div> <div class="sect2"> -<h3 id="_independent_third_party_service_providers">7.5. Independent Third-Party Service Providers</h3> +<h3 id="_independent_third_party_service_providers">Independent Third-Party Service Providers</h3> <div class="paragraph"> <p>An Email Service Provider (ESP A) might want to share its own mailing reputation with its clients, and might sign all outgoing mail from its clients @@ -1069,37 +1065,37 @@ with its own d= domain (e.g., d=espa.example).</p> <ul> <li> <p>Share the SDID domain and use the AUID value to distinguish among the -clients, e.g., a signature on behalf of client A would have "d=espa.example" -and "i=@clienta.espa.example" (or "i=clienta@espa.example").</p> +clients, e.g., a signature on behalf of client A would have "d=espa.example" +and "i=@clienta.espa.example" (or "i=clienta@espa.example").</p> </li> <li> <p>Extend the SDID domain, so there is a unique value (and subdomain) for each client, e.g., a signature on behalf of client A would have -"d=clienta.espa.example".</p> +"d=clienta.espa.example".</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_mail_streams_based_on_behavioral_assessment">7.6. Mail Streams Based on Behavioral Assessment</h3> +<h3 id="_mail_streams_based_on_behavioral_assessment">Mail Streams Based on Behavioral Assessment</h3> <div class="paragraph"> <p>An ISP (ISP A) might want to assign signatures to outbound mail from its users -according to each user’s past sending behavior (reputation). +according to each user's past sending behavior (reputation). ISP A (ispa.example) can configure subdomains corresponding to the assessment categories (e.g., good.ispa.example, neutral.ispa.example, bad.ispa.example), -and use these subdomains in the "d=" value of the signature.</p> +and use these subdomains in the "d=" value of the signature.</p> </div> <div class="paragraph"> <p>The signing module can also set the AUID value to have a unique user ID -(distinct from the local-part of the user’s email address), for example, -"user3456@neutral.domain.example".</p> +(distinct from the local-part of the user's email address), for example, +"user3456@neutral.domain.example".</p> </div> </div> <div class="sect2"> -<h3 id="_agent_or_mediator_signatures">7.7. Agent or Mediator Signatures</h3> +<h3 id="_agent_or_mediator_signatures">Agent or Mediator Signatures</h3> <div class="paragraph"> -<p>Some examples of agents might be a mailing list manager, or the "forward -article to a friend" service that many online publications offer. +<p>Some examples of agents might be a mailing list manager, or the "forward +article to a friend" service that many online publications offer. In most of these cases, the signature is asserting that the message originated with, or was relayed by, the service asserting responsibility. In general, if the service is configured in such a way that its forwarding @@ -1110,12 +1106,12 @@ signature.</p> </div> </div> <div class="sect1"> -<h2 id="_usage_considerations">8. Usage Considerations</h2> +<h2 id="_usage_considerations">Usage Considerations</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_a_non_standard_submission_and_delivery_scenarios">8.1. A Non-Standard Submission and Delivery Scenarios</h3> +<h3 id="_a_non_standard_submission_and_delivery_scenarios">A Non-Standard Submission and Delivery Scenarios</h3> <div class="paragraph"> -<p>The robustness of DKIM’s verification mechanism is based on the fact +<p>The robustness of DKIM's verification mechanism is based on the fact that only authorized signing modules have access to the designated private key. This has the side effect that email submission and delivery scenarios that @@ -1131,14 +1127,14 @@ or modify headers, or modify the message body.</p> joe@isp-1.example, and joe@isp-2.example.</p> </div> <div class="paragraph"> -<p>When Joe send email through "isp-1" as "joe@company-a.example", that email -cannot have a signature with d=company-a.example, because "isp-1" -have no access to company-a.example’s private key. -The email will have signature from "isp-1.example" instead.</p> +<p>When Joe send email through "isp-1" as "joe@company-a.example", that email +cannot have a signature with d=company-a.example, because "isp-1" +have no access to company-a.example's private key. +The email will have signature from "isp-1.example" instead.</p> </div> </div> <div class="sect2"> -<h3 id="_protection_of_internal_mail">8.2. Protection of Internal Mail</h3> +<h3 id="_protection_of_internal_mail">Protection of Internal Mail</h3> <div class="paragraph"> <p>If the organization signs all of its mail, then its boundary MTAs can look for mail purporting to be from the organization that does not contain a verifiable @@ -1153,12 +1149,12 @@ Signing Practices.</p> </div> </div> <div class="sect2"> -<h3 id="_signature_granularity">8.3. Signature Granularity</h3> +<h3 id="_signature_granularity">Signature Granularity</h3> <div class="paragraph"> <p>It is possible to administer subdomains or otherwise adjust signatures in a way that supports per-user identification. This user-level granularity can be specified in two ways: either by sharing -the signing identity and specifying an extension to the "i=" value that has a +the signing identity and specifying an extension to the "i=" value that has a per-user granularity or by creating and signing with unique per-user keys.</p> </div> <div class="paragraph"> @@ -1185,12 +1181,12 @@ This can create significant and often unnecessary management complexity.</p> <p>For those who choose to represent user-level granularity in signatures, the performance and management considerations above suggest that it would be more effective to do so by specifying a local part or subdomain extension in the -"i=" tag rather than by extending the "d=" domain and publishing individual +"i=" tag rather than by extending the "d=" domain and publishing individual keys.</p> </div> </div> <div class="sect2"> -<h3 id="_email_infrastructure_agents">8.4. Email Infrastructure Agents</h3> +<h3 id="_email_infrastructure_agents">Email Infrastructure Agents</h3> <div class="paragraph"> <p><strong>Outbound</strong></p> </div> @@ -1255,7 +1251,7 @@ Authentication-Results header field).</p> </div> </div> <div class="sect2"> -<h3 id="_mail_user_agent">8.5. Mail User Agent</h3> +<h3 id="_mail_user_agent">Mail User Agent</h3> <div class="paragraph"> <p><strong>Outbound</strong></p> </div> @@ -1289,11 +1285,16 @@ However, it can be used as input into a reputation system.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/DKIM_OVERVIEW.adoc b/doc/DKIM_OVERVIEW.adoc index d762fd6a..807ca80b 100644 --- a/doc/DKIM_OVERVIEW.adoc +++ b/doc/DKIM_OVERVIEW.adoc @@ -193,7 +193,7 @@ email. This specification defines an initial set, using DNS and SMTP, for basic interoperability. -.... +---- | |- RFC5322 Message V @@ -234,7 +234,7 @@ interoperability. +-------------+ +-----------+ +------------+ Figure 1: DKIM Service Architecture -.... +---- *Signing* diff --git a/doc/DKIM_OVERVIEW.html b/doc/DKIM_OVERVIEW.html index e5c944d0..45ec760f 100644 --- a/doc/DKIM_OVERVIEW.html +++ b/doc/DKIM_OVERVIEW.html @@ -1,52 +1,60 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>DomainKeys Identified Mail (DKIM) Service Overview</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>DomainKeys Identified Mail (DKIM) Service Overview</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>DomainKeys Identified Mail (DKIM) Service Overview</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>DomainKeys Identified Mail (DKIM) Service Overview</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a></li> -<li><a href="#_the_dkim_value_proposition">2. The DKIM Value Proposition</a> +<li><a href="#_introduction">Introduction</a></li> +<li><a href="#_the_dkim_value_proposition">The DKIM Value Proposition</a> <ul class="sectlevel2"> -<li><a href="#_identity_verification">2.1. Identity Verification</a></li> -<li><a href="#_enabling_trust_assessments">2.2. Enabling Trust Assessments</a></li> -<li><a href="#_establishing_message_validity">2.3. Establishing Message Validity</a></li> +<li><a href="#_identity_verification">Identity Verification</a></li> +<li><a href="#_enabling_trust_assessments">Enabling Trust Assessments</a></li> +<li><a href="#_establishing_message_validity">Establishing Message Validity</a></li> </ul> </li> -<li><a href="#_dkim_goals">3. DKIM Goals</a> +<li><a href="#_dkim_goals">DKIM Goals</a> <ul class="sectlevel2"> -<li><a href="#_functional_goals">3.1. Functional Goals</a></li> -<li><a href="#_operational_goals">3.2. Operational Goals</a></li> +<li><a href="#_functional_goals">Functional Goals</a></li> +<li><a href="#_operational_goals">Operational Goals</a></li> </ul> </li> -<li><a href="#_dkim_function">4. DKIM Function</a> +<li><a href="#_dkim_function">DKIM Function</a> <ul class="sectlevel2"> -<li><a href="#_basic_signing">4.1. Basic Signing</a></li> -<li><a href="#_characteristics_of_a_dkim_signature">4.2. Characteristics of a DKIM Signature</a></li> -<li><a href="#_the_selector_construct">4.3. The Selector Construct</a></li> -<li><a href="#_verification">4.4. Verification</a></li> -<li><a href="#_sub_domain_assessment">4.5. Sub-Domain Assessment</a></li> +<li><a href="#_basic_signing">Basic Signing</a></li> +<li><a href="#_characteristics_of_a_dkim_signature">Characteristics of a DKIM Signature</a></li> +<li><a href="#_the_selector_construct">The Selector Construct</a></li> +<li><a href="#_verification">Verification</a></li> +<li><a href="#_sub_domain_assessment">Sub-Domain Assessment</a></li> </ul> </li> -<li><a href="#_service_architecture">5. Service Architecture</a></li> +<li><a href="#_service_architecture">Service Architecture</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -55,7 +63,7 @@ </div> </div> <div class="sect1"> -<h2 id="_introduction">1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> <p>DKIM defines a domain-level digital signature authentication framework for @@ -67,7 +75,7 @@ using the Domain Name System (DNS) as its key server technology.</p> Identifier refer to the identity of a responsible person or organization. The same identity can have multiple identifiers. This identifier is called the Signing Domain IDentifier (SDID) and is -contained in the DKIM-Signature header fields "d=" tag. +contained in the DKIM-Signature header fields "d=" tag. The owner of the SDID is declaring that they accept responsibility for the message and can thus be held accountable for it.</p> </div> @@ -78,7 +86,7 @@ message and can thus be held accountable for it.</p> <ul> <li> <p>Does not authenticate or verify the contents of the message header or body, -such as the author "From" field, beyond certifying data integrity between the +such as the author "From" field, beyond certifying data integrity between the time of signing and the time of verifying.</p> </li> <li> @@ -94,7 +102,7 @@ successful signature verification.</p> <li> <p>Does not protect against re-sending (replay of) a message that already has a verified signature; therefore, a transit intermediary or a -recipient can re-post the message — that is, post it as a new message — with +recipient can re-post the message -- that is, post it as a new message -- with the original signature remaining verifiable, even though the new recipient(s) might be different from those who were originally specified by the author.</p> @@ -104,10 +112,10 @@ author.</p> </div> </div> <div class="sect1"> -<h2 id="_the_dkim_value_proposition">2. The DKIM Value Proposition</h2> +<h2 id="_the_dkim_value_proposition">The DKIM Value Proposition</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_identity_verification">2.1. Identity Verification</h3> +<h3 id="_identity_verification">Identity Verification</h3> <div class="paragraph"> <p>An assessment service that uses DKIM can differentiate between a domain (SDID) used by a known organization and a domain used by others. @@ -119,7 +127,7 @@ question for later stages of assessment.</p> </div> </div> <div class="sect2"> -<h3 id="_enabling_trust_assessments">2.2. Enabling Trust Assessments</h3> +<h3 id="_enabling_trust_assessments">Enabling Trust Assessments</h3> <div class="paragraph"> <p>A valid DKIM signature neither lowers nor raises the level of trust associated with the message, but it enables other mechanisms to be used for doing so.</p> @@ -134,10 +142,10 @@ unchanged.</p> </div> </div> <div class="sect2"> -<h3 id="_establishing_message_validity">2.3. Establishing Message Validity</h3> +<h3 id="_establishing_message_validity">Establishing Message Validity</h3> <div class="paragraph"> <p>An interesting side effect of the cryptographic method used by DKIM is that it -is possible to be certain that a signed message (or, if "l=" is used, the +is possible to be certain that a signed message (or, if "l=" is used, the signed portion of a message) has not been modified between the time of signing and the time of verifying. If it has been changed in any way, then the message will not be verified @@ -147,10 +155,10 @@ successfully with DKIM.</p> </div> </div> <div class="sect1"> -<h2 id="_dkim_goals">3. DKIM Goals</h2> +<h2 id="_dkim_goals">DKIM Goals</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_functional_goals">3.1. Functional Goals</h3> +<h3 id="_functional_goals">Functional Goals</h3> <div class="paragraph"> <p><strong>Use Domain-Level Granularity for Assurance</strong>. DKIM binds a signing key record to a Domain Name as the SDID. @@ -161,7 +169,7 @@ reducing privacy concerns.</p> <div class="paragraph"> <p><strong>Implementation Locality</strong>. Any party, anywhere along the transit path, can implement DKIM signing. -Its use is not confined to particular systems, such as the author’s MUA or the +Its use is not confined to particular systems, such as the author's MUA or the inbound boundary MTA, and there can be more than one signature per message.</p> </div> <div class="paragraph"> @@ -188,22 +196,22 @@ the anonymity of the user who authored it.</p> </div> </div> <div class="sect2"> -<h3 id="_operational_goals">3.2. Operational Goals</h3> +<h3 id="_operational_goals">Operational Goals</h3> <div class="paragraph"> <p><strong>Make Presence of Signature Transparent to Non-Supporting Recipients</strong>. Recipient that does not support DKIM still can read the message.</p> </div> <div class="paragraph"> <p><strong>Treat Verification Failure the Same as No Signature Present</strong>. -If verification of the message’s signature failed, the message will revert to -normal handling, through the receiver’s existing filtering mechanisms.</p> +If verification of the message's signature failed, the message will revert to +normal handling, through the receiver's existing filtering mechanisms.</p> </div> <div class="paragraph"> <p><strong>Permit Incremental Adoption for Incremental Benefit</strong>. DKIM allows pairwise sets of email providers and spam filtering companies to distinguish mail that is associated with a known organization, versus mail that might deceptively purport to have the affiliation. -This in turn allows the development of "whitelist" schemes whereby +This in turn allows the development of "whitelist" schemes whereby authenticated mail from a known source with good reputation is allowed to bypass some anti-abuse filters.</p> </div> @@ -215,7 +223,7 @@ infrastructure that is needed across the open Internet.</p> </div> <div class="paragraph"> <p><strong>Permit a Wide Range of Deployment Choices</strong>. -DKIM can be deployed at a variety of places within an organization’s +DKIM can be deployed at a variety of places within an organization's email service. This affords flexibility in terms of who administers its use, as well as what traffic carries a DKIM signature.</p> @@ -224,46 +232,46 @@ traffic carries a DKIM signature.</p> </div> </div> <div class="sect1"> -<h2 id="_dkim_function">4. DKIM Function</h2> +<h2 id="_dkim_function">DKIM Function</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_basic_signing">4.1. Basic Signing</h3> +<h3 id="_basic_signing">Basic Signing</h3> <div class="paragraph"> <p>With the DKIM signature mechanism, a signer chooses an SDID, performs digital signing on the message, and adds the signature information using a DKIM header field. -A verifier obtains the domain name and the "selector" from the DKIM header +A verifier obtains the domain name and the "selector" from the DKIM header field, obtains the public key associated with the name, and verifies the signature.</p> </div> </div> <div class="sect2"> -<h3 id="_characteristics_of_a_dkim_signature">4.2. Characteristics of a DKIM Signature</h3> +<h3 id="_characteristics_of_a_dkim_signature">Characteristics of a DKIM Signature</h3> <div class="paragraph"> <p>A DKIM signature applies to the message body and selected header fields. The signer computes a hash of the selected header fields and another hash of the body. The signer then uses a private key to cryptographically encode this information, along with other signing parameters. -Signature information is placed into "DKIM-Signature:", a new [RFC5322] +Signature information is placed into "DKIM-Signature:", a new [RFC5322] message header field.</p> </div> </div> <div class="sect2"> -<h3 id="_the_selector_construct">4.3. The Selector Construct</h3> +<h3 id="_the_selector_construct">The Selector Construct</h3> <div class="paragraph"> <p>A single SDID can have multiple signing keys and/or multiple potential signers. To support this, DKIM identifies a particular signature as using a combination -of the SDID and an added field, called the "selector", specified in a separate -"DKIM-Signature:" header field parameter.</p> +of the SDID and an added field, called the "selector", specified in a separate +"DKIM-Signature:" header field parameter.</p> </div> </div> <div class="sect2"> -<h3 id="_verification">4.4. Verification</h3> +<h3 id="_verification">Verification</h3> <div class="paragraph"> <p>Message recipients can verify the signature by querying the DNS for the -signer’s domain directly, to retrieve the appropriate public key, and thereby +signer's domain directly, to retrieve the appropriate public key, and thereby confirm that the message was signed by a party in possession of the private key for the SDID.</p> </div> @@ -273,7 +281,7 @@ Management Domain (ADMD) of the message recipient.</p> </div> </div> <div class="sect2"> -<h3 id="_sub_domain_assessment">4.5. Sub-Domain Assessment</h3> +<h3 id="_sub_domain_assessment">Sub-Domain Assessment</h3> <div class="paragraph"> <p>To permit assessments that are independent, one method is for an organization to use different sub-domains as the SDID tag.</p> @@ -282,7 +290,7 @@ to use different sub-domains as the SDID tag.</p> </div> </div> <div class="sect1"> -<h2 id="_service_architecture">5. Service Architecture</h2> +<h2 id="_service_architecture">Service Architecture</h2> <div class="sectionbody"> <div class="paragraph"> <p>DKIM uses external service components, such as for key retrieval and relaying @@ -290,7 +298,7 @@ email. This specification defines an initial set, using DNS and SMTP, for basic interoperability.</p> </div> -<div class="literalblock"> +<div class="listingblock"> <div class="content"> <pre> | |- RFC5322 Message @@ -353,14 +361,14 @@ was required. Verifying the signature uses public information from the Key Store. If the signature passes, reputation information is used to assess the signer and that information is passed to the message filtering system. -If the signature fails or there is no signature using the author’s domain, +If the signature fails or there is no signature using the author's domain, information about signing practices related to the author can be retrieved remotely and/or locally, and that information is passed to the message filtering system.</p> </div> <div class="paragraph"> <p>Messages lacking a valid author signature can prompt a query for any -published "signing practices" information, as an aid in determining whether +published "signing practices" information, as an aid in determining whether the author information has been used without authorization.</p> </div> <div class="paragraph"> @@ -368,7 +376,7 @@ the author information has been used without authorization.</p> </div> <div class="paragraph"> <p>A popular use of reputation information is as input to a Filtering Engine that -decides whether to deliver — and possibly whether to specially mark — a +decides whether to deliver -- and possibly whether to specially mark -- a message.</p> </div> <div class="paragraph"> @@ -395,7 +403,7 @@ keys.</p> </div> <div class="paragraph"> <p>If a message contains a valid signature, then the verifier can evaluate the -associated domain name’s reputation, in order to determine appropriate +associated domain name's reputation, in order to determine appropriate delivery or display options for that message.</p> </div> <div class="paragraph"> @@ -420,11 +428,16 @@ to the evaluating site and is strictly a matter of local policy.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/DKIM_SIGNATURES.html b/doc/DKIM_SIGNATURES.html index 2c10065a..d61abdf4 100644 --- a/doc/DKIM_SIGNATURES.html +++ b/doc/DKIM_SIGNATURES.html @@ -1,90 +1,98 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>DomainKeys Identified Mail (DKIM) Signatures</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>DomainKeys Identified Mail (DKIM) Signatures</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>DomainKeys Identified Mail (DKIM) Signatures</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>DomainKeys Identified Mail (DKIM) Signatures</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a> +<li><a href="#_introduction">Introduction</a> <ul class="sectlevel2"> -<li><a href="#_signing_identity">1.1. Signing Identity</a></li> -<li><a href="#_scalability">1.2. Scalability</a></li> -<li><a href="#_simple_key_management">1.3. Simple Key Management</a></li> -<li><a href="#_data_integrity">1.4. Data Integrity</a></li> +<li><a href="#_signing_identity">Signing Identity</a></li> +<li><a href="#_scalability">Scalability</a></li> +<li><a href="#_simple_key_management">Simple Key Management</a></li> +<li><a href="#_data_integrity">Data Integrity</a></li> </ul> </li> -<li><a href="#_terminology_and_definitions">2. Terminology and Definitions</a></li> -<li><a href="#_protocol_elements">3. Protocol Elements</a> +<li><a href="#_terminology_and_definitions">Terminology and Definitions</a></li> +<li><a href="#_protocol_elements">Protocol Elements</a> <ul class="sectlevel2"> -<li><a href="#_selectors">3.1. Selectors</a></li> -<li><a href="#_tagvalue_lists">3.2. Tag=Value Lists</a></li> -<li><a href="#_signing_and_verification_algorithms">3.3. Signing and Verification Algorithms</a></li> -<li><a href="#_canonicalization">3.4. Canonicalization</a></li> +<li><a href="#_selectors">Selectors</a></li> +<li><a href="#_tagvalue_lists">Tag=Value Lists</a></li> +<li><a href="#_signing_and_verification_algorithms">Signing and Verification Algorithms</a></li> +<li><a href="#_canonicalization">Canonicalization</a></li> </ul> </li> -<li><a href="#_the_dkim_signature_header_field">4. The DKIM-Signature Header Field</a> +<li><a href="#_the_dkim_signature_header_field">The DKIM-Signature Header Field</a> <ul class="sectlevel2"> -<li><a href="#_key_management_and_representation">4.1. Key Management and Representation</a></li> -<li><a href="#_computing_the_message_hashes">4.2. Computing the Message Hashes</a></li> -<li><a href="#_input_requirements">4.3. Input Requirements</a></li> -<li><a href="#_output_requirements">4.4. Output Requirements</a></li> -<li><a href="#_signing_by_parent_domains">4.5. Signing by Parent Domains</a></li> -<li><a href="#_relationship_between_sdid_and_auid">4.6. Relationship between SDID and AUID</a></li> -<li><a href="#_semantics_of_multiple_signatures">4.7. Semantics of Multiple Signatures</a></li> +<li><a href="#_key_management_and_representation">Key Management and Representation</a></li> +<li><a href="#_computing_the_message_hashes">Computing the Message Hashes</a></li> +<li><a href="#_input_requirements">Input Requirements</a></li> +<li><a href="#_output_requirements">Output Requirements</a></li> +<li><a href="#_signing_by_parent_domains">Signing by Parent Domains</a></li> +<li><a href="#_relationship_between_sdid_and_auid">Relationship between SDID and AUID</a></li> +<li><a href="#_semantics_of_multiple_signatures">Semantics of Multiple Signatures</a></li> </ul> </li> -<li><a href="#_signer_actions">5. Signer Actions</a> +<li><a href="#_signer_actions">Signer Actions</a> <ul class="sectlevel2"> -<li><a href="#_determine_whether_the_email_should_be_signed_and_by_whom">5.1. Determine Whether the Email Should Be Signed and by Whom</a></li> -<li><a href="#_select_a_private_key_and_corresponding_selector_information">5.2. Select a Private Key and Corresponding Selector Information</a></li> -<li><a href="#_normalize_the_message_to_prevent_transport_conversions">5.3. Normalize the Message to Prevent Transport Conversions</a></li> -<li><a href="#_determine_the_header_fields_to_sign">5.4. Determine the Header Fields to Sign</a></li> -<li><a href="#_compute_the_message_hash_and_signature">5.5. Compute the Message Hash and Signature</a></li> -<li><a href="#_insert_the_dkim_signature_header_field">5.6. Insert the DKIM-Signature Header Field</a></li> +<li><a href="#_determine_whether_the_email_should_be_signed_and_by_whom">Determine Whether the Email Should Be Signed and by Whom</a></li> +<li><a href="#_select_a_private_key_and_corresponding_selector_information">Select a Private Key and Corresponding Selector Information</a></li> +<li><a href="#_normalize_the_message_to_prevent_transport_conversions">Normalize the Message to Prevent Transport Conversions</a></li> +<li><a href="#_determine_the_header_fields_to_sign">Determine the Header Fields to Sign</a></li> +<li><a href="#_compute_the_message_hash_and_signature">Compute the Message Hash and Signature</a></li> +<li><a href="#_insert_the_dkim_signature_header_field">Insert the DKIM-Signature Header Field</a></li> </ul> </li> -<li><a href="#_verifier_actions">6. Verifier Actions</a> +<li><a href="#_verifier_actions">Verifier Actions</a> <ul class="sectlevel2"> -<li><a href="#_extract_signatures_from_the_message">6.1. Extract Signatures from the Message</a></li> -<li><a href="#_communicate_verification_results">6.2. Communicate Verification Results</a></li> -<li><a href="#_interpret_resultapply_local_policy">6.3. Interpret Result/Apply Local Policy</a></li> +<li><a href="#_extract_signatures_from_the_message">Extract Signatures from the Message</a></li> +<li><a href="#_communicate_verification_results">Communicate Verification Results</a></li> +<li><a href="#_interpret_result_apply_local_policy">Interpret Result/Apply Local Policy</a></li> </ul> </li> -<li><a href="#_security_considerations">7. Security Considerations</a> +<li><a href="#_security_considerations">Security Considerations</a> <ul class="sectlevel2"> -<li><a href="#_ascii_art_attacks">7.1. ASCII Art Attacks</a></li> -<li><a href="#_misuse_of_body_length_limits_l_tag">7.2. Misuse of Body Length Limits ("l=" Tag)</a></li> -<li><a href="#_misappropriated_private_key">7.3. Misappropriated Private Key</a></li> -<li><a href="#_key_server_denial_of_service_attacks">7.4. Key Server Denial-of-Service Attacks</a></li> -<li><a href="#_attacks_against_the_dns">7.5. Attacks against the DNS</a></li> -<li><a href="#_replayspam_attacks">7.6. Replay/Spam Attacks</a></li> -<li><a href="#_limits_on_revoking_keys">7.7. Limits on Revoking Keys</a></li> -<li><a href="#_intentionally_malformed_key_records">7.8. Intentionally Malformed Key Records</a></li> -<li><a href="#_intentionally_malformed_dkim_signature_header_fields">7.9. Intentionally Malformed DKIM-Signature Header Fields</a></li> -<li><a href="#_information_leakage">7.10. Information Leakage</a></li> -<li><a href="#_remote_timing_attacks">7.11. Remote Timing Attacks</a></li> -<li><a href="#_reordered_header_fields">7.12. Reordered Header Fields</a></li> -<li><a href="#_rsa_attacks">7.13. RSA Attacks</a></li> +<li><a href="#_ascii_art_attacks">ASCII Art Attacks</a></li> +<li><a href="#_misuse_of_body_length_limits_l_tag">Misuse of Body Length Limits ("l=" Tag)</a></li> +<li><a href="#_misappropriated_private_key">Misappropriated Private Key</a></li> +<li><a href="#_key_server_denial_of_service_attacks">Key Server Denial-of-Service Attacks</a></li> +<li><a href="#_attacks_against_the_dns">Attacks against the DNS</a></li> +<li><a href="#_replay_spam_attacks">Replay/Spam Attacks</a></li> +<li><a href="#_limits_on_revoking_keys">Limits on Revoking Keys</a></li> +<li><a href="#_intentionally_malformed_key_records">Intentionally Malformed Key Records</a></li> +<li><a href="#_intentionally_malformed_dkim_signature_header_fields">Intentionally Malformed DKIM-Signature Header Fields</a></li> +<li><a href="#_information_leakage">Information Leakage</a></li> +<li><a href="#_remote_timing_attacks">Remote Timing Attacks</a></li> +<li><a href="#_reordered_header_fields">Reordered Header Fields</a></li> +<li><a href="#_rsa_attacks">RSA Attacks</a></li> </ul> </li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -94,13 +102,13 @@ </div> </div> <div class="sect1"> -<h2 id="_introduction">1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> -<p><a href="https://tools.ietf.org/html/rfc4685" target="_blank" rel="noopener">RFC 4685</a> provide a background for the development of +<p><a href="https://tools.ietf.org/html/rfc4685">RFC 4685^</a> provide a background for the development of DKIM, -<a href="https://tools.ietf.org/html/rfc5585" target="_blank" rel="noopener">RFC 5585</a> provide an overview of the service, and -<a href="https://tools.ietf.org/html/rfc5863" target="_blank" rel="noopener">RFC 5863</a> provide deployment and operations guidance and +<a href="https://tools.ietf.org/html/rfc5585">RFC 5585^</a> provide an overview of the service, and +<a href="https://tools.ietf.org/html/rfc5863">RFC 5863^</a> provide deployment and operations guidance and advice.</p> </div> <div class="paragraph"> @@ -108,7 +116,7 @@ advice.</p> (e.g., Secure/Multipurpose Internet Mail Extensions (S/MIME), OpenPGP).</p> </div> <div class="sect2"> -<h3 id="_signing_identity">1.1. Signing Identity</h3> +<h3 id="_signing_identity">Signing Identity</h3> <div class="paragraph"> <p>The signing identity is included as part of the signature header field, and is not required to match an address in any particular header fields.</p> @@ -120,7 +128,7 @@ signature-related content appearing in the message body.</p> </div> </div> <div class="sect2"> -<h3 id="_scalability">1.2. Scalability</h3> +<h3 id="_scalability">Scalability</h3> <div class="paragraph"> <p>DKIM is designed to support the extreme scalability requirements that characterize the email identification problem. @@ -135,7 +143,7 @@ parties.</p> </div> </div> <div class="sect2"> -<h3 id="_simple_key_management">1.3. Simple Key Management</h3> +<h3 id="_simple_key_management">Simple Key Management</h3> <div class="paragraph"> <p>DKIM require no certificate authority infrastructure. DKIM currently depends on DNS administration and the security of the DNS @@ -145,10 +153,10 @@ claimed Signer directly rather than from a third party.</p> </div> </div> <div class="sect2"> -<h3 id="_data_integrity">1.4. Data Integrity</h3> +<h3 id="_data_integrity">Data Integrity</h3> <div class="paragraph"> <p>Verifying the signature asserts that the hashed content has not changed since -it was signed and asserts nothing else about "protecting" the end-to-end +it was signed and asserts nothing else about "protecting" the end-to-end integrity of the message.</p> </div> <div class="paragraph"> @@ -159,7 +167,7 @@ Signature verification failure does not force rejection of the message.</p> </div> </div> <div class="sect1"> -<h2 id="_terminology_and_definitions">2. Terminology and Definitions</h2> +<h2 id="_terminology_and_definitions">Terminology and Definitions</h2> <div class="sectionbody"> <div class="dlist"> <dl> @@ -195,7 +203,7 @@ behalf of SDID.</p> </dd> <dt class="hdlist1">Identity Assessor</dt> <dd> -<p>An element in the mail system that consumes DKIM’s payload, which is the +<p>An element in the mail system that consumes DKIM's payload, which is the responsible Signing Domain Identifier (SDID). The Identity Assessor is dedicated to the assessment of the delivered identifier.</p> @@ -223,7 +231,7 @@ FWS (folding whitespace) = [*WSP CRLF] 1*WSP ; folding whitespace</pre> <pre>atext = ALPHA / DIGIT / ; Printable US-ASCII "!" / "#" / ; characters not including "$" / "%" / ; specials. Used for atoms. - "&" / "'" / + "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / @@ -305,7 +313,8 @@ Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig</pre> </div> <div class="literalblock"> <div class="content"> -<pre>dot-atom-text = 1*atext *("." 1*atext)</pre> +<pre> +dot-atom-text = 1*atext *("." 1*atext)</pre> </div> </div> <div class="paragraph"> @@ -321,7 +330,7 @@ Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig</pre> ptext = hex-octet / safe-char hex-octet = "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F") - ; Octet MUST be used for characters > 127, =, + ; Octet MUST be used for characters > 127, =, ; SPACEs or TABs at the ends of lines, and is ; recommended for any character not listed in ; RFC 2049 as "mail-safe". @@ -340,7 +349,7 @@ safe-char = ; any octet with decimal value of 33 through <pre>dkim-quoted-printable = *(FWS / hex-octet / dkim-safe-char) ; hex-octet is from RFC 2045 dkim-safe-char = %x21-3A / %x3C / %x3E-7E - ; '!' - ':', '<', '>' - '~'</pre> + ; '!' - ':', '<', '>' - '~'</pre> </div> </div> <div class="paragraph"> @@ -351,45 +360,45 @@ several important ways:</p> <ol class="arabic"> <li> <p>Whitespace in the input text, including CR and LF, MUST be encoded. -[RFC2045] does not require such encoding, and does not permit encoding of -CR or LF characters that are part of a CRLF line break.</p> + [RFC2045] does not require such encoding, and does not permit encoding of + CR or LF characters that are part of a CRLF line break.</p> </li> <li> <p>Whitespace in the encoded text is ignored. -This is to allow tags encoded using DKIM-Quoted-Printable to be wrapped as -needed. -In particular, [RFC2045] requires that line breaks in the input be -represented as physical line breaks; that is not the case here.</p> + This is to allow tags encoded using DKIM-Quoted-Printable to be wrapped as + needed. + In particular, [RFC2045] requires that line breaks in the input be + represented as physical line breaks; that is not the case here.</p> </li> <li> -<p>The "soft line break" syntax ("=" as the last non-whitespace character on -the line) does not apply.</p> +<p>The "soft line break" syntax ("=" as the last non-whitespace character on + the line) does not apply.</p> </li> <li> <p>It does not require that encoded lines be no more than 76 characters long -(although there may be other requirements depending on the context in which -the encoded text is being used).</p> + (although there may be other requirements depending on the context in which + the encoded text is being used).</p> </li> </ol> </div> </div> </div> <div class="sect1"> -<h2 id="_protocol_elements">3. Protocol Elements</h2> +<h2 id="_protocol_elements">Protocol Elements</h2> <div class="sectionbody"> <div class="paragraph"> <p>Protocol Elements are conceptual parts of the protocol that are not specific to either Signers or Verifiers.</p> </div> <div class="sect2"> -<h3 id="_selectors">3.1. Selectors</h3> +<h3 id="_selectors">Selectors</h3> <div class="literalblock"> <div class="content"> <pre>selector = sub-domain *( "." sub-domain )</pre> </div> </div> <div class="paragraph"> -<p>The key namespace is subdivided using "selectors", to support multiple +<p>The key namespace is subdivided using "selectors", to support multiple concurrent public keys per signing domain.</p> </div> <div class="paragraph"> @@ -400,33 +409,33 @@ For example:</p> <ul> <li> <p>Domains that want to delegate signing capability for a specific address for -a given duration to a partner, such as an advertising provider or other -outsourced function.</p> + a given duration to a partner, such as an advertising provider or other + outsourced function.</p> </li> <li> <p>Domains that want to allow frequent travelers to send messages locally -without the need to connect with a particular MSA.</p> + without the need to connect with a particular MSA.</p> </li> <li> -<p>"Affinity" domains (e.g., college alumni associations) that provide -forwarding of incoming mail, but that do not operate a mail submission -agent for outgoing mail.</p> +<p>"Affinity" domains (e.g., college alumni associations) that provide + forwarding of incoming mail, but that do not operate a mail submission + agent for outgoing mail.</p> </li> </ul> </div> <div class="paragraph"> <p>Reusing a selector with a new key (for example, changing the key associated -with a user’s name) makes it impossible to tell the difference between a -message that didn’t verify because the key is no longer valid and a message +with a user's name) makes it impossible to tell the difference between a +message that didn't verify because the key is no longer valid and a message that is actually forged. For this reason, Signers are ill-advised to reuse selectors for new keys. A better strategy is to assign new keys to new selectors.</p> </div> </div> <div class="sect2"> -<h3 id="_tagvalue_lists">3.2. Tag=Value Lists</h3> +<h3 id="_tagvalue_lists">Tag=Value Lists</h3> <div class="paragraph"> -<p>DKIM uses a simple "tag=value" syntax in several contexts, including in +<p>DKIM uses a simple "tag=value" syntax in several contexts, including in messages and domain signature records.</p> </div> <div class="literalblock"> @@ -445,46 +454,46 @@ ALNUMPUNC = ALPHA / DIGIT / "_"</pre> <div class="ulist"> <ul> <li> -<p>Values are a series of strings containing either plain text, "base64" text, -"qp-section", or "dkim-quoted-printable".</p> +<p>Values are a series of strings containing either plain text, "base64" text, + "qp-section", or "dkim-quoted-printable".</p> </li> <li> <p>The name of the tag will determine the encoding of each value.</p> </li> <li> -<p>Unencoded semicolon (";") characters MUST NOT occur in the tag value, since -that separates tag-specs.</p> +<p>Unencoded semicolon (";") characters MUST NOT occur in the tag value, since + that separates tag-specs.</p> </li> <li> <p>Tags MUST be interpreted in a case-sensitive manner.</p> </li> <li> <p>Values MUST be processed as case sensitive unless the specific tag -description of semantics specifies case insensitivity.</p> + description of semantics specifies case insensitivity.</p> </li> <li> <p>Tags MUST NOT duplicate, otherwise entire tags list is invalid.</p> </li> <li> <p>Whitespace within a value MUST be retained unless explicitly excluded -by the specific tag description.</p> + by the specific tag description.</p> </li> <li> <p>Tag=value pairs that represent the default value MAY be included to -aid legibility.</p> + aid legibility.</p> </li> <li> <p>Unrecognized tags MUST be ignored.</p> </li> <li> <p>Tag with an empty value explicitly designates the empty string as the -value.</p> + value.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_signing_and_verification_algorithms">3.3. Signing and Verification Algorithms</h3> +<h3 id="_signing_and_verification_algorithms">Signing and Verification Algorithms</h3> <div class="paragraph"> <p>Two algorithms are defined by this specification at this time: rsa-sha1 and rsa-sha256.</p> @@ -502,23 +511,23 @@ rsa-sha256.</p> </li> <li> <p>Verifiers MUST ignore any signatures using algorithms that they do not -implement.</p> + implement.</p> </li> <li> <p>The rsa-sha1 computes a message hash using SHA-1 and then the hash is then -signed using the RSA algorithm and the Signer’s private key.</p> + signed using the RSA algorithm and the Signer's private key.</p> </li> <li> <p>The rsa-sha256 computes a message hash using SHA-256 and then the hash is -signed using the RSA algorithm and the Signer’s private key.</p> + signed using the RSA algorithm and the Signer's private key.</p> </li> <li> <p>Signers MUST use RSA keys of at least 1024 bits for long-lived keys.</p> </li> <li> <p>Verifiers MUST be able to validate signatures with keys ranging from 512 -bits to 2048 bits, and they MAY be able to validate signatures with larger -keys.</p> + bits to 2048 bits, and they MAY be able to validate signatures with larger + keys.</p> </li> </ul> </div> @@ -529,31 +538,31 @@ keys.</p> <ul> <li> <p>The practical constraint that large (e.g., 4096-bit) keys might not fit -within a 512-byte DNS UDP response packet</p> + within a 512-byte DNS UDP response packet</p> </li> <li> <p>The security constraint that keys smaller than 1024 bits are subject to -off-line attacks</p> + off-line attacks</p> </li> <li> <p>Larger keys impose higher CPU costs to verify and sign email</p> </li> <li> <p>Keys can be replaced on a regular basis; thus, their lifetime can be -relatively short</p> + relatively short</p> </li> <li> <p>The security goals of this specification are modest compared to typical -goals of other systems that employ digital signatures</p> + goals of other systems that employ digital signatures</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_canonicalization">3.4. Canonicalization</h3> +<h3 id="_canonicalization">Canonicalization</h3> <div class="paragraph"> <p>Canonicalization is a process for converting data that has more than one -possible representation into a "standard", "normal", or canonical form.</p> +possible representation into a "standard", "normal", or canonical form.</p> </div> <div class="paragraph"> <p>Canonicalization is only used to prepare the email for signing or verifying; @@ -561,23 +570,23 @@ it does not affect the transmitted email in any way.</p> </div> <div class="paragraph"> <p>Two canonicalization algorithms are defined for each of the header and the -body, a "simple" and "relaxed" algorithms.</p> +body, a "simple" and "relaxed" algorithms.</p> </div> <div class="ulist"> <ul> <li> -<p>A "simple" algorithm tolerates almost no modification.</p> +<p>A "simple" algorithm tolerates almost no modification.</p> </li> <li> -<p>A "relaxed" algorithm tolerates common modifications such as whitespace -replacement and header field line rewrapping.</p> +<p>A "relaxed" algorithm tolerates common modifications such as whitespace + replacement and header field line rewrapping.</p> </li> <li> <p>A Signer MAY specify either algorithm for header or body.</p> </li> <li> -<p>If no canonicalization algorithm is specified by the Signer, the "simple" -algorithm defaults for both header and body.</p> +<p>If no canonicalization algorithm is specified by the Signer, the "simple" + algorithm defaults for both header and body.</p> </li> <li> <p>Verifiers MUST implement both canonicalization algorithms.</p> @@ -587,30 +596,30 @@ algorithm defaults for both header and body.</p> </li> <li> <p>Verifiers MUST ignore any signatures that use unrecognized canonicalization -algorithms.</p> + algorithms.</p> </li> <li> <p>Canonicalization algorithms MUST NOT change the transmitted data in any -way.</p> + way.</p> </li> </ul> </div> <div class="sect3"> -<h4 id="_the_simple_canonicalization_algorithm">3.4.1. The "simple" Canonicalization Algorithm</h4> +<h4 id="_the_simple_canonicalization_algorithm">The "simple" Canonicalization Algorithm</h4> <div class="ulist"> <ul> <li> <p>Header fields MUST be presented to the signing or verification algorithm -exactly as they are in the message being signed or verified.</p> + exactly as they are in the message being signed or verified.</p> </li> <li> <p>Header field names MUST NOT be case folded and whitespace MUST NOT be -changed.</p> + changed.</p> </li> </ul> </div> <div class="paragraph"> -<p>The "simple" body canonicalization algorithm,</p> +<p>The "simple" body canonicalization algorithm,</p> </div> <div class="olist arabic"> <ol class="arabic"> @@ -619,15 +628,15 @@ changed.</p> </li> <li> <p>If there is no body or no trailing CRLF on the message body, a CRLF is -added.</p> + added.</p> </li> </ol> </div> </div> <div class="sect3"> -<h4 id="_the_relaxed_canonicalization_algorithm">3.4.2. The "relaxed" Canonicalization Algorithm</h4> +<h4 id="_the_relaxed_canonicalization_algorithm">The "relaxed" Canonicalization Algorithm</h4> <div class="paragraph"> -<p>The "relaxed" header canonicalization algorithm MUST apply the following steps +<p>The "relaxed" header canonicalization algorithm MUST apply the following steps in order:</p> </div> <div class="ulist"> @@ -640,11 +649,11 @@ in order:</p> </li> <li> <p>Implementations MUST NOT remove the CRLF at the end of the header field -value.</p> + value.</p> </li> <li> <p>Convert all sequences of one or more WSP characters to a single SP -character.</p> + character.</p> </li> <li> <p>Delete all WSP characters at the end of each unfolded header field value.</p> @@ -658,18 +667,18 @@ character.</p> </ul> </div> <div class="paragraph"> -<p>The "relaxed" body canonicalization algorithm MUST apply the following steps +<p>The "relaxed" body canonicalization algorithm MUST apply the following steps (a) and (b) in order:</p> </div> <div class="olist loweralpha"> -<ol class="loweralpha"> +<ol class="loweralpha" type="a"> <li> <p>Reduce whitespace:</p> <div class="ulist"> <ul> <li> <p>Ignore all whitespace at the end of lines. -Implementations MUST NOT remove the CRLF at the end of the line.</p> + Implementations MUST NOT remove the CRLF at the end of the line.</p> </li> <li> <p>Reduce all sequences of WSP within a line to a single SP character.</p> @@ -691,33 +700,33 @@ Implementations MUST NOT remove the CRLF at the end of the line.</p> </div> </div> <div class="sect3"> -<h4 id="_example">3.4.3. Example</h4> +<h4 id="_example">Example</h4> <div class="paragraph"> <p>A message reading:</p> </div> <div class="literalblock"> <div class="content"> -<pre>A: <SP> X <CRLF> -B <SP> : <SP> Y <HTAB><CRLF> -<HTAB> Z <SP><SP><CRLF> -<CRLF> -<SP> C <SP><CRLF> -D <SP><HTAB><SP> E <CRLF> -<CRLF> -<CRLF></pre> +<pre>A: <SP> X <CRLF> +B <SP> : <SP> Y <HTAB><CRLF> +<HTAB> Z <SP><SP><CRLF> +<CRLF> +<SP> C <SP><CRLF> +D <SP><HTAB><SP> E <CRLF> +<CRLF> +<CRLF></pre> </div> </div> <div class="paragraph"> -<p>Output for "simple" canonicalization,</p> +<p>Output for "simple" canonicalization,</p> </div> <div class="literalblock"> <div class="content"> -<pre>A: <SP> X <CRLF> -B <SP> : <SP> Y <HTAB><CRLF> -<HTAB> Z <SP><SP><CRLF> -<CRLF> -<SP> C <SP><CRLF> -D <SP><HTAB><SP> E <CRLF></pre> +<pre>A: <SP> X <CRLF> +B <SP> : <SP> Y <HTAB><CRLF> +<HTAB> Z <SP><SP><CRLF> +<CRLF> +<SP> C <SP><CRLF> +D <SP><HTAB><SP> E <CRLF></pre> </div> </div> <div class="paragraph"> @@ -725,11 +734,11 @@ D <SP><HTAB><SP> E <CRLF></pre> </div> <div class="literalblock"> <div class="content"> -<pre>a:X <CRLF> -b:Y <SP> Z <CRLF> -<CRLF> -<SP> C <CRLF> -D <SP> E <CRLF></pre> +<pre>a:X <CRLF> +b:Y <SP> Z <CRLF> +<CRLF> +<SP> C <CRLF> +D <SP> E <CRLF></pre> </div> </div> </div> @@ -737,13 +746,13 @@ D <SP> E <CRLF></pre> </div> </div> <div class="sect1"> -<h2 id="_the_dkim_signature_header_field">4. The DKIM-Signature Header Field</h2> +<h2 id="_the_dkim_signature_header_field">The DKIM-Signature Header Field</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> <p>The DKIM-Signature header field SHOULD be treated as though it were a -trace header field as defined in Section 3.6 of [RFC5322].</p> + trace header field as defined in Section 3.6 of [RFC5322].</p> </li> <li> <p>Its SHOULD NOT be reordered</p> @@ -753,15 +762,15 @@ trace header field as defined in Section 3.6 of [RFC5322].</p> </li> <li> <p>The DKIM-Signature header field being created or verified is always -included in the signature calculation, after the rest of the header fields -being signed; -however, when calculating or verifying the signature, the value of the "b=" -tag (signature value) of that DKIM-Signature header field MUST be treated -as though it were an empty string.</p> + included in the signature calculation, after the rest of the header fields + being signed; + however, when calculating or verifying the signature, the value of the "b=" + tag (signature value) of that DKIM-Signature header field MUST be treated + as though it were an empty string.</p> </li> <li> <p>Unknown tags in the DKIM-Signature header field MUST be included in the -signature calculation</p> + signature calculation</p> </li> <li> <p>Unknown tags MUST be ignored by Verifiers</p> @@ -786,8 +795,8 @@ status are shown below.</p> <div class="ulist"> <ul> <li> -<p>It MUST have the value "1" for implementations compliant with this version -of DKIM.</p> +<p>It MUST have the value "1" for implementations compliant with this version + of DKIM.</p> </li> </ul> </div> @@ -825,11 +834,11 @@ sig-b-tag-data = base64string</pre> <ul> <li> <p>Whitespace is ignored in this value and MUST be ignored when reassembling -the original signature.</p> + the original signature.</p> </li> <li> <p>The signing process can safely insert FWS in this value in arbitrary places -to conform to line-length limits.</p> + to conform to line-length limits.</p> </li> </ul> </div> @@ -843,23 +852,23 @@ sig-bh-tag-data = base64string</pre> </div> </div> <div class="paragraph"> -<p>The hash of the canonicalized body part of the message as limited by the "l=" +<p>The hash of the canonicalized body part of the message as limited by the "l=" tag.</p> </div> <div class="ulist"> <ul> <li> <p>Whitespace is ignored in this value and MUST be ignored when reassembling -the original signature.</p> + the original signature.</p> </li> <li> <p>The signing process can safely insert FWS in this value in arbitrary places -to conform to line-length limits.</p> + to conform to line-length limits.</p> </li> </ul> </div> <div class="paragraph"> -<p><strong>c=</strong> (plain-text; OPTIONAL, default is "simple/simple")</p> +<p><strong>c=</strong> (plain-text; OPTIONAL, default is "simple/simple")</p> </div> <div class="literalblock"> <div class="content"> @@ -875,14 +884,14 @@ x-sig-c-tag-alg = hyphenated-word <div class="ulist"> <ul> <li> -<p>It consists of two names separated by a "slash" (%d47) character, -corresponding to the header and body canonicalization algorithms, -respectively.</p> +<p>It consists of two names separated by a "slash" (%d47) character, + corresponding to the header and body canonicalization algorithms, + respectively.</p> </li> <li> <p>If only one algorithm is named, that algorithm is used for the header and -"simple" is used for the body. -For example, "c=relaxed" is treated the same as "c=relaxed/simple".</p> + "simple" is used for the body. + For example, "c=relaxed" is treated the same as "c=relaxed/simple".</p> </li> </ul> </div> @@ -903,15 +912,15 @@ domain-name = sub-domain 1*("." sub-domain) <ul> <li> <p>It MUST correspond to a valid DNS name under which the DKIM key record -is published.</p> + is published.</p> </li> <li> <p>When presented with a signature that does not meet these requirements, -Verifiers MUST consider the signature as invalid.</p> + Verifiers MUST consider the signature as invalid.</p> </li> <li> <p>Internationalized domain names MUST be encoded as A-labels, as described in -Section 2.3 of [RFC5890].</p> + Section 2.3 of [RFC5890].</p> </li> </ul> </div> @@ -932,36 +941,36 @@ algorithm.</p> <ul> <li> <p>The field MUST contain the complete list of header fields in the order -presented to the signing algorithm.</p> + presented to the signing algorithm.</p> </li> <li> <p>The field MAY contain names of header fields that do not exist when signed; -nonexistent header fields do not contribute to the signature computation. -By "signing" header fields that do not actually exist, a Signer can allow a -Verifier to detect insertion of those header fields after signing and -also prevents adding fields with no values.</p> + nonexistent header fields do not contribute to the signature computation. + By "signing" header fields that do not actually exist, a Signer can allow a + Verifier to detect insertion of those header fields after signing and + also prevents adding fields with no values.</p> </li> <li> <p>The field MAY contain multiple instances of a header field name, meaning -multiple occurrences of the corresponding header field are included in the -header hash.</p> + multiple occurrences of the corresponding header field are included in the + header hash.</p> </li> <li> <p>The field MUST NOT include the DKIM-Signature header field that is being -created or verified but may include others.</p> + created or verified but may include others.</p> </li> <li> <p>Folding whitespace (FWS) MAY be included on either side of the colon -separator.</p> + separator.</p> </li> <li> <p>Header field names MUST be compared against actual header field names in a -case-insensitive manner.</p> + case-insensitive manner.</p> </li> </ul> </div> <div class="paragraph"> -<p><strong>i=</strong> (dkim-quoted-printable; OPTIONAL; default is "@" + "d=" value)</p> +<p><strong>i=</strong> (dkim-quoted-printable; OPTIONAL; default is "@" + "d=" value)</p> </div> <div class="literalblock"> <div class="content"> @@ -975,26 +984,26 @@ case-insensitive manner.</p> <ul> <li> <p>The local-part MAY be omitted, because in some cases a Signer may not be -able to establish a verified individual identity.</p> + able to establish a verified individual identity.</p> </li> <li> <p>The local-part MAY be drawn from a namespace unrelated to any mailbox.</p> </li> <li> <p>The domain-name MUST be the same as, or a subdomain of, the value of the -"d=" tag.</p> + "d=" tag.</p> </li> <li> -<p>The domain-name need not be registered in the DNS — so it might not -resolve in a query</p> +<p>The domain-name need not be registered in the DNS -- so it might not + resolve in a query</p> </li> <li> -<p>If no "i=" tag, the Verifier MUST behave as though the value of that tag -were "@d", where "d" is the value from the "d=" tag.</p> +<p>If no "i=" tag, the Verifier MUST behave as though the value of that tag + were "@d", where "d" is the value from the "d=" tag.</p> </li> <li> -<p>The Signer MAY choose to use the same namespace for its AUIDs as its users' -email addresses or MAY choose other means of representing its users.</p> +<p>The Signer MAY choose to use the same namespace for its AUIDs as its users' + email addresses or MAY choose other means of representing its users.</p> </li> </ul> </div> @@ -1015,32 +1024,32 @@ preceding the body.</p> <ul> <li> <p>This value MUST NOT be larger than the actual number of octets in the -canonicalized message body.</p> + canonicalized message body.</p> </li> <li> -<p>The value of the "l=" tag is constrained to 76 decimal digits.</p> +<p>The value of the "l=" tag is constrained to 76 decimal digits.</p> </li> <li> <p>Implementers MAY need to limit the actual value expressed to a value -smaller than <code>10^76</code>, e.g., to allow a message to fit within the available -storage space.</p> + smaller than <code>10^76</code>, e.g., to allow a message to fit within the available + storage space.</p> </li> <li> <p>If the body length count is not specified, the entire message body is -signed.</p> + signed.</p> </li> <li> <p>The body length count MUST be calculated following the canonicalization -algorithm; for example, any whitespace ignored by a canonicalization -algorithm is not included as part of the body length count.</p> + algorithm; for example, any whitespace ignored by a canonicalization + algorithm is not included as part of the body length count.</p> </li> <li> <p>A body length count of zero means that the body is completely unsigned.</p> </li> <li> <p>Signers wishing to ensure that no modification of any sort can occur -should specify the "simple" canonicalization algorithm for both header and -body and omit the body length count.</p> + should specify the "simple" canonicalization algorithm for both header and + body and omit the body length count.</p> </li> </ul> </div> @@ -1061,34 +1070,34 @@ qoption = qp-hdr-value</pre> <div class="ulist"> <ul> <li> -<p>Each query method is of the form "type[/options]", where the syntax and -semantics of the options depend on the type and specified options.</p> +<p>Each query method is of the form "type[/options]", where the syntax and + semantics of the options depend on the type and specified options.</p> </li> <li> <p>If there are multiple query mechanisms listed, the choice of query -mechanism MUST NOT change the interpretation of the signature.</p> + mechanism MUST NOT change the interpretation of the signature.</p> </li> <li> <p>Implementations MUST use the recognized query mechanisms in the order -presented.</p> + presented.</p> </li> <li> <p>Unrecognized query mechanisms MUST be ignored.</p> </li> <li> -<p>Default is "dns/txt", which defines the DNS TXT resource record (RR) lookup -algorithm,</p> +<p>Default is "dns/txt", which defines the DNS TXT resource record (RR) lookup + algorithm,</p> <div class="ulist"> <ul> <li> -<p>The only option defined for the "dns" query type is "txt", which MUST be -included.</p> +<p>The only option defined for the "dns" query type is "txt", which MUST be + included.</p> </li> </ul> </div> </li> <li> -<p>Verifiers and Signers MUST support "dns/txt".</p> +<p>Verifiers and Signers MUST support "dns/txt".</p> </li> </ul> </div> @@ -1101,13 +1110,13 @@ included.</p> </div> </div> <div class="paragraph"> -<p>The selector subdividing the namespace for the "d=" tag.</p> +<p>The selector subdividing the namespace for the "d=" tag.</p> </div> <div class="ulist"> <ul> <li> <p>Internationalized selector names MUST be encoded as A-labels, as described -in Section 2.3 of [RFC5890].</p> + in Section 2.3 of [RFC5890].</p> </li> </ul> </div> @@ -1126,7 +1135,7 @@ in Section 2.3 of [RFC5890].</p> <ul> <li> <p>The format is the number of seconds since 00:00:00 on January 1, 1970 in -the UTC time zone.</p> + the UTC time zone.</p> </li> <li> <p>The value is expressed as an unsigned integer in decimal ASCII.</p> @@ -1136,11 +1145,11 @@ the UTC time zone.</p> </li> <li> <p>Implementations SHOULD be prepared to handle values up to at least <code>10^12</code> -(until approximately AD 200,000; this fits into 40 bits).</p> + (until approximately AD 200,000; this fits into 40 bits).</p> </li> <li> <p>To avoid denial-of-service attacks, implementations MAY consider any value -longer than 12 digits to be infinite.</p> + longer than 12 digits to be infinite.</p> </li> <li> <p>Leap seconds are not counted.</p> @@ -1167,33 +1176,33 @@ longer than 12 digits to be infinite.</p> <p>Default is no expiration</p> </li> <li> -<p>The format is the same as in the "t=" tag, represented as an absolute date, -not as a time delta from the signing timestamp.</p> +<p>The format is the same as in the "t=" tag, represented as an absolute date, + not as a time delta from the signing timestamp.</p> </li> <li> <p>The value is expressed as an unsigned integer in decimal ASCII, with the -same constraints on the value in the "t=" tag.</p> + same constraints on the value in the "t=" tag.</p> </li> <li> <p>Signatures MAY be considered invalid if the verification time at the -Verifier is past the expiration date.</p> + Verifier is past the expiration date.</p> </li> <li> <p>The verification time should be the time that the message was first -received at the administrative domain of the Verifier if that time is -reliably available; otherwise, the current time should be used.</p> + received at the administrative domain of the Verifier if that time is + reliably available; otherwise, the current time should be used.</p> </li> <li> -<p>The value of the "x=" tag MUST be greater than the value of the "t=" tag if -both are present.</p> +<p>The value of the "x=" tag MUST be greater than the value of the "t=" tag if + both are present.</p> </li> <li> -<p>The "x=" tag is not intended as an anti-replay defense.</p> +<p>The "x=" tag is not intended as an anti-replay defense.</p> </li> <li> -<p>Due to clock drift, the receiver’s notion of when to consider the signature -expired may not exactly match what the sender is expecting. -Receivers MAY add a 'fudge factor' to allow for such possible drift.</p> +<p>Due to clock drift, the receiver's notion of when to consider the signature + expired may not exactly match what the sender is expecting. + Receivers MAY add a 'fudge factor' to allow for such possible drift.</p> </li> </ul> </div> @@ -1214,32 +1223,32 @@ sig-z-tag-copy = hdr-name [FWS] ":" qp-hdr-value</pre> <ul> <li> <p>A vertical-bar-separated list of selected header fields present when the -message was signed, including both the field name and value.</p> + message was signed, including both the field name and value.</p> </li> <li> <p>Default is null</p> </li> <li> <p>It is not required to include all header fields present at the time of -signing.</p> + signing.</p> </li> <li> -<p>This field need not contain the same header fields listed in the "h=" tag.</p> +<p>This field need not contain the same header fields listed in the "h=" tag.</p> </li> <li> -<p>The header field text itself MUST encode the vertical bar ("|", %x7C) -character (i.e., vertical bars in the "z=" text are meta-characters, and -any actual vertical bar characters in a copied header field MUST be -encoded).</p> +<p>The header field text itself MUST encode the vertical bar ("|", %x7C) + character (i.e., vertical bars in the "z=" text are meta-characters, and + any actual vertical bar characters in a copied header field MUST be + encoded).</p> </li> <li> <p>All whitespace MUST be encoded, including whitespace between the colon and -the header field value.</p> + the header field value.</p> </li> <li> <p>After encoding, FWS MAY be added at arbitrary locations in order to avoid -excessively long lines; such whitespace is NOT part of the value of the -header field and MUST be removed before decoding.</p> + excessively long lines; such whitespace is NOT part of the value of the + header field and MUST be removed before decoding.</p> </li> </ul> </div> @@ -1259,11 +1268,11 @@ header field and MUST be removed before decoding.</p> </div> </div> <div class="sect2"> -<h3 id="_key_management_and_representation">4.1. Key Management and Representation</h3> +<h3 id="_key_management_and_representation">Key Management and Representation</h3> <div class="paragraph"> -<p>Parameters to the key lookup algorithm are the type of the lookup (the "q=" -tag), the domain of the Signer (the "d=" tag of the DKIM-Signature header -field), and the selector (the "s=" tag).</p> +<p>Parameters to the key lookup algorithm are the type of the lookup (the "q=" +tag), the domain of the Signer (the "d=" tag of the DKIM-Signature header +field), and the selector (the "s=" tag).</p> </div> <div class="literalblock"> <div class="content"> @@ -1271,14 +1280,14 @@ field), and the selector (the "s=" tag).</p> </div> </div> <div class="sect3"> -<h4 id="_textual_representation">4.1.1. Textual Representation</h4> +<h4 id="_textual_representation">Textual Representation</h4> <div class="paragraph"> <p>The current valid tags are described below. Other tags MAY be present and MUST be ignored by any implementation that does not understand them.</p> </div> <div class="paragraph"> -<p><strong>v=</strong> (plain-text; RECOMMENDED, default is "DKIM1")</p> +<p><strong>v=</strong> (plain-text; RECOMMENDED, default is "DKIM1")</p> </div> <div class="literalblock"> <div class="content"> @@ -1291,17 +1300,17 @@ not understand them.</p> <div class="ulist"> <ul> <li> -<p>If specified, this tag MUST be set to "DKIM1" (without the quotes).</p> +<p>If specified, this tag MUST be set to "DKIM1" (without the quotes).</p> </li> <li> <p>This tag MUST be the first tag in the record.</p> </li> <li> -<p>Records beginning with a "v=" tag with any other value MUST be discarded.</p> +<p>Records beginning with a "v=" tag with any other value MUST be discarded.</p> </li> <li> -<p>Verifiers MUST do a string comparison on this value; for example, "DKIM1" -is not the same as "DKIM1.0"</p> +<p>Verifiers MUST do a string comparison on this value; for example, "DKIM1" +is not the same as "DKIM1.0"</p> </li> </ul> </div> @@ -1326,12 +1335,12 @@ x-key-h-tag-alg = hyphenated-word ; for future extension</pre> </li> <li> <p>The set of algorithms listed in this tag in each record is an operational -choice made by the Signer.</p> + choice made by the Signer.</p> </li> </ul> </div> <div class="paragraph"> -<p><strong>k=</strong> (plain-text; OPTIONAL, default is "rsa").</p> +<p><strong>k=</strong> (plain-text; OPTIONAL, default is "rsa").</p> </div> <div class="literalblock"> <div class="content"> @@ -1346,13 +1355,13 @@ x-key-k-tag-type = hyphenated-word ; for future extension</pre> <div class="ulist"> <ul> <li> -<p>Signers and Verifiers MUST support the "rsa" key type.</p> +<p>Signers and Verifiers MUST support the "rsa" key type.</p> </li> <li> -<p>The "rsa" key type indicates that an ASN.1 DER-encoded [ITU-X660-1997] -RSAPublicKey (see [RFC3447], Sections 3.1 and A.1.1) is being used in the -"p=" tag. -(Note: the "p=" tag further encodes the value using the base64 algorithm.)</p> +<p>The "rsa" key type indicates that an ASN.1 DER-encoded [ITU-X660-1997] + RSAPublicKey (see [RFC3447], Sections 3.1 and A.1.1) is being used in the + "p=" tag. + (Note: the "p=" tag further encodes the value using the base64 algorithm.)</p> </li> <li> <p>Unrecognized key types MUST be ignored.</p> @@ -1377,7 +1386,7 @@ RSAPublicKey (see [RFC3447], Sections 3.1 and A.1.1) is being used in the </li> <li> <p>This tag should be used sparingly in any key server mechanism that has -space limitations (notably DNS).</p> + space limitations (notably DNS).</p> </li> <li> <p>This is intended for use by administrators, not end users.</p> @@ -1402,29 +1411,29 @@ space limitations (notably DNS).</p> </li> <li> <p>The syntax and semantics of this tag value before being encoded in base64 -are defined by the "k=" tag.</p> + are defined by the "k=" tag.</p> </li> <li> <p>If a private key has been compromised or otherwise disabled, a Signer might -want to explicitly state that it knows about the selector, but all messages -using that selector should fail verification.</p> + want to explicitly state that it knows about the selector, but all messages + using that selector should fail verification.</p> </li> <li> <p>Verifiers SHOULD return an error code for any DKIM-Signature header field -with a selector referencing a revoked key.</p> + with a selector referencing a revoked key.</p> </li> <li> <p>A base64string is permitted to include whitespace (FWS) at arbitrary -places; however, any CRLFs MUST be followed by at least one WSP character.</p> + places; however, any CRLFs MUST be followed by at least one WSP character.</p> </li> <li> <p>Implementers and administrators are cautioned to ensure that selector TXT -RRs conform to this specification.</p> + RRs conform to this specification.</p> </li> </ul> </div> <div class="paragraph"> -<p><strong>s=</strong> (plain-text; OPTIONAL; default is "*").</p> +<p><strong>s=</strong> (plain-text; OPTIONAL; default is "*").</p> </div> <div class="literalblock"> <div class="content"> @@ -1441,7 +1450,7 @@ x-key-s-tag-type = hyphenated-word ; for future extension</pre> <ul> <li> <p>Verifiers for a given service type MUST ignore this record if the -appropriate type is not listed.</p> + appropriate type is not listed.</p> </li> <li> <p>Unrecognized service types MUST be ignored.</p> @@ -1451,10 +1460,10 @@ appropriate type is not listed.</p> <div class="ulist"> <ul> <li> -<p>"*" matches all service types</p> +<p>"*" matches all service types</p> </li> <li> -<p>"email" electronic mail (not necessarily limited to SMTP)</p> +<p>"email" electronic mail (not necessarily limited to SMTP)</p> </li> </ul> </div> @@ -1490,16 +1499,16 @@ x-key-t-tag-flag = hyphenated-word ; for future extension</pre> <ul> <li> <p><strong>y</strong>: This domain is testing DKIM. -Verifiers MUST NOT treat messages from Signers in testing mode differently -from unsigned email, even should the signature fail to verify. -Verifiers MAY wish to track testing mode results to assist the Signer.</p> + Verifiers MUST NOT treat messages from Signers in testing mode differently + from unsigned email, even should the signature fail to verify. + Verifiers MAY wish to track testing mode results to assist the Signer.</p> </li> <li> -<p><strong>s</strong>: Any DKIM-Signature header fields using the "i=" tag MUST have -the same domain value on the right-hand side of the "@" in the "i=" tag -and the value of the "d=" tag. -That is, the "i=" domain MUST NOT be a subdomain of "d=". -Use of this flag is RECOMMENDED unless subdomaining is required.</p> +<p><strong>s</strong>: Any DKIM-Signature header fields using the "i=" tag MUST have + the same domain value on the right-hand side of the "@" in the "i=" tag + and the value of the "d=" tag. + That is, the "i=" domain MUST NOT be a subdomain of "d=". + Use of this flag is RECOMMENDED unless subdomaining is required.</p> </li> </ul> </div> @@ -1508,42 +1517,42 @@ Use of this flag is RECOMMENDED unless subdomaining is required.</p> </div> </div> <div class="sect3"> -<h4 id="_dns_binding">4.1.2. DNS Binding</h4> +<h4 id="_dns_binding">DNS Binding</h4> <div class="ulist"> <ul> <li> <p>All implementations MUST support this binding.</p> </li> <li> -<p>All DKIM keys are stored in a subdomain named "_domainkey". -Given a DKIM-Signature field with a "d=" tag of "example.com" and an "s=" -tag of "foo.bar", the DNS query will be for -"foo.bar._domainkey.example.com".</p> +<p>All DKIM keys are stored in a subdomain named "_domainkey". + Given a DKIM-Signature field with a "d=" tag of "example.com" and an "s=" + tag of "foo.bar", the DNS query will be for + "foo.bar._domainkey.example.com".</p> </li> <li> -<p>The query type "q=" in lookup function specify DNS Resource Record. -The only option defined in this base specification is "txt", indicating the -use of a TXT RR.</p> +<p>The query type "q=" in lookup function specify DNS Resource Record. + The only option defined in this base specification is "txt", indicating the + use of a TXT RR.</p> </li> <li> <p>Strings in a TXT RR MUST be concatenated together before use with no -intervening whitespace.</p> + intervening whitespace.</p> </li> <li> <p>TXT RRs MUST be unique for a particular selector name; that is, if there -are multiple records in an RRset, the results are undefined.</p> + are multiple records in an RRset, the results are undefined.</p> </li> </ul> </div> </div> </div> <div class="sect2"> -<h3 id="_computing_the_message_hashes">4.2. Computing the Message Hashes</h3> +<h3 id="_computing_the_message_hashes">Computing the Message Hashes</h3> <div class="ulist"> <ul> <li> <p>The Signer/Verifier MUST compute two hashes: one over the body of the -message and one over the selected header fields of the message.</p> + message and one over the selected header fields of the message.</p> </li> <li> <p>Signers MUST compute them in the order shown</p> @@ -1563,51 +1572,51 @@ message and one over the selected header fields of the message.</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> -<p>The body canonicalized using algorithm specified in the "c=" tag</p> +<p>The body canonicalized using algorithm specified in the "c=" tag</p> </li> <li> -<p>The body then truncated to the length specified in the "l=" tag</p> +<p>The body then truncated to the length specified in the "l=" tag</p> </li> <li> <p>That hash value is then converted to base64 form</p> </li> <li> -<p>For Signer, the hash value then inserted into "bh=" tag</p> +<p>For Signer, the hash value then inserted into "bh=" tag</p> </li> <li> -<p>For Verifier, the hash value then compared with value of "bh=" tag</p> +<p>For Verifier, the hash value then compared with value of "bh=" tag</p> </li> </ol> </div> </li> <li> <p>The Signer/Verifier MUST pass the following to the hash algorithm in the -indicated order,</p> + indicated order,</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> -<p>The header fields specified by the "h=" tag, in the order specified in -that tag.</p> +<p>The header fields specified by the "h=" tag, in the order specified in + that tag.</p> </li> <li> <p>The header fields then canonicalized using the header canonicalization -algorithm specified in the "c=" tag.</p> + algorithm specified in the "c=" tag.</p> </li> <li> <p>Each header field MUST be terminated with a single CRLF.</p> </li> <li> <p>All tags and their values in the DKIM-Signature header field are included -in the cryptographic hash with the sole exception of the value portion of -the "b=" (signature) tag, which MUST be treated as the null string.</p> + in the cryptographic hash with the sole exception of the value portion of + the "b=" (signature) tag, which MUST be treated as the null string.</p> </li> <li> -<p>The DKIM-Signature header field MUST NOT be included in its own "h=" tag, -although other DKIM-Signature header fields MAY be signed</p> +<p>The DKIM-Signature header field MUST NOT be included in its own "h=" tag, + although other DKIM-Signature header fields MAY be signed</p> </li> <li> <p>All tags MUST be included even if they might not be understood by the -Verifier.</p> + Verifier.</p> </li> </ol> </div> @@ -1621,22 +1630,22 @@ Verifier.</p> <ul> <li> <p>When calculating the hash on messages that will be transmitted using -base64 or quoted-printable encoding, Signers MUST compute the hash after -the encoding, and Verifier MUST incorporate the values into hash before -decoding.</p> + base64 or quoted-printable encoding, Signers MUST compute the hash after + the encoding, and Verifier MUST incorporate the values into hash before + decoding.</p> </li> <li> <p>The hash MUST be computed before transport-level encodings such as SMTP -"dot-stuffing" (the modification of lines beginning with a "." to avoid -confusion with the SMTP end-of-message marker.</p> + "dot-stuffing" (the modification of lines beginning with a "." to avoid + confusion with the SMTP end-of-message marker.</p> </li> <li> <p>DKIM messages MAY be either in plain-text or in MIME format; no special -treatment is afforded to MIME content.</p> + treatment is afforded to MIME content.</p> </li> <li> <p>Message attachments in MIME format MUST be included in the content that is -signed.</p> + signed.</p> </li> </ul> </div> @@ -1660,16 +1669,16 @@ signature = sig-alg (d-domain, selector, data-hash)</pre> <dl> <dt class="hdlist1">hash-alg</dt> <dd> -<p>is the hashing algorithm specified in the "a" parameter.</p> +<p>is the hashing algorithm specified in the "a" parameter.</p> </dd> <dt class="hdlist1">canon-body</dt> <dd> <p>is a canonicalized representation of the body, produced -using the body algorithm specified in the "c" parameter.</p> +using the body algorithm specified in the "c" parameter.</p> </dd> <dt class="hdlist1">l-param</dt> <dd> -<p>is the length-of-body value of the "l" parameter.</p> +<p>is the length-of-body value of the "l" parameter.</p> </dd> <dt class="hdlist1">data-hash</dt> <dd> @@ -1678,7 +1687,7 @@ the header including the DKIM-Signature header, and the body hash.</p> </dd> <dt class="hdlist1">h-headers</dt> <dd> -<p>is the list of headers to be signed, as specified in the "h=" +<p>is the list of headers to be signed, as specified in the "h=" parameter.</p> </dd> <dt class="hdlist1">D-SIG</dt> @@ -1692,21 +1701,21 @@ signature value portion of the parameter, that is, an empty parameter value.</p> </dd> <dt class="hdlist1">sig-alg</dt> <dd> -<p>is the signature algorithm specified by the "a" parameter.</p> +<p>is the signature algorithm specified by the "a" parameter.</p> </dd> <dt class="hdlist1">d-domain</dt> <dd> -<p>is the domain name specified in the "d" parameter.</p> +<p>is the domain name specified in the "d" parameter.</p> </dd> <dt class="hdlist1">selector</dt> <dd> -<p>is the selector value specified in the "s" parameter.</p> +<p>is the selector value specified in the "s" parameter.</p> </dd> </dl> </div> </div> <div class="sect2"> -<h3 id="_input_requirements">4.3. Input Requirements</h3> +<h3 id="_input_requirements">Input Requirements</h3> <div class="paragraph"> <p>Signers and Verifiers SHOULD take reasonable steps to ensure that the messages they are processing are valid according to [RFC5322], [RFC2045], and any other @@ -1714,7 +1723,7 @@ relevant message format standards.</p> </div> </div> <div class="sect2"> -<h3 id="_output_requirements">4.4. Output Requirements</h3> +<h3 id="_output_requirements">Output Requirements</h3> <div class="paragraph"> <p>For each signature verifying result, output of the DKIM algorithm MUST include the set of:</p> @@ -1733,7 +1742,7 @@ the set of:</p> </li> <li> <p>PERMFAIL: a permanent, non-recoverable error such as a signature -verification failure</p> + verification failure</p> </li> <li> <p>TEMPFAIL: a temporary, recoverable error such as a DNS query timeout</p> @@ -1750,58 +1759,58 @@ that consume those results.</p> </div> </div> <div class="sect2"> -<h3 id="_signing_by_parent_domains">4.5. Signing by Parent Domains</h3> +<h3 id="_signing_by_parent_domains">Signing by Parent Domains</h3> <div class="paragraph"> <p>By default, private keys corresponding to a domain can be used to sign messages for any subdomain. -For example, a key record for the domain "example.com" can be used to verify -messages where the AUID ("i=" tag of the signature) is "sub.example.com", or -even "sub1.sub2.example.com".</p> +For example, a key record for the domain "example.com" can be used to verify +messages where the AUID ("i=" tag of the signature) is "sub.example.com", or +even "sub1.sub2.example.com".</p> </div> <div class="paragraph"> <p>In order to limit the capability of such keys when this is not intended, the -"s" flag MAY be set in the "t=" tag of the key record, to constrain the +"s" flag MAY be set in the "t=" tag of the key record, to constrain the validity of the domain of the AUID.</p> </div> <div class="ulist"> <ul> <li> -<p>If the referenced key record contains the "s" flag as part of the "t=" tag, -the domain of the AUID ("i=" flag) MUST be the same as that of the SDID -(d=) domain.</p> +<p>If the referenced key record contains the "s" flag as part of the "t=" tag, + the domain of the AUID ("i=" flag) MUST be the same as that of the SDID + (d=) domain.</p> </li> <li> <p>If this flag is absent, the domain of the AUID MUST be the same as, or a -subdomain of, the SDID.</p> + subdomain of, the SDID.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_relationship_between_sdid_and_auid">4.6. Relationship between SDID and AUID</h3> +<h3 id="_relationship_between_sdid_and_auid">Relationship between SDID and AUID</h3> <div class="ulist"> <ul> <li> <p>DKIM MAY optionally provide a single responsible Agent or User Identifier -(AUID) through "i=" tag.</p> + (AUID) through "i=" tag.</p> </li> <li> <p>Upon successfully verifying the signature, a receive-side DKIM Verifier -MUST communicate the Signing Domain Identifier (d=) to a consuming Identity -Assessor module and MAY communicate the Agent or User Identifier (i=) if -present.</p> + MUST communicate the Signing Domain Identifier (d=) to a consuming Identity + Assessor module and MAY communicate the Agent or User Identifier (i=) if + present.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_semantics_of_multiple_signatures">4.7. Semantics of Multiple Signatures</h3> +<h3 id="_semantics_of_multiple_signatures">Semantics of Multiple Signatures</h3> <div class="sect3"> -<h4 id="_example_scenarios">4.7.1. Example Scenarios</h4> +<h4 id="_example_scenarios">Example Scenarios</h4> <div class="paragraph"> -<p>A Signer might sign a message including all header fields and no "l=" tag +<p>A Signer might sign a message including all header fields and no "l=" tag (to satisfy strict Verifiers) and a second time with a limited set of -header fields and an "l=" tag. +header fields and an "l=" tag. Verifiers could then choose which signature they prefer.</p> </div> <div class="paragraph"> @@ -1820,12 +1829,12 @@ For example, a recipient might have an address at members.example.org, a site that has anti-abuse protection that is somewhat less effective than the recipient would prefer. Such a recipient might have specific authors whose messages would be trusted -absolutely, but messages from unknown authors that had passed the forwarder’s +absolutely, but messages from unknown authors that had passed the forwarder's scrutiny would have only medium trust.</p> </div> </div> <div class="sect3"> -<h4 id="_interpretation">4.7.2. Interpretation</h4> +<h4 id="_interpretation">Interpretation</h4> <div class="paragraph"> <p>If a header field with multiple instances is signed, those header fields are always signed from the bottom up. @@ -1838,35 +1847,35 @@ or C only, but not A only, B only, A and B only, or A and C only.</p> <ul> <li> <p>A Signer MAY add more than one DKIM-Signature header field using different -parameters.</p> + parameters.</p> </li> <li> <p>Signers SHOULD NOT remove any DKIM-Signature header fields from messages -they are signing, even if they know that the signatures cannot be verified.</p> + they are signing, even if they know that the signatures cannot be verified.</p> </li> <li> <p>Verifier SHOULD evaluate signatures independently and on their own merits. -For example, a Verifier that by policy chooses not to accept signatures -with deprecated cryptographic algorithms would consider such signatures -invalid.</p> + For example, a Verifier that by policy chooses not to accept signatures + with deprecated cryptographic algorithms would consider such signatures + invalid.</p> </li> <li> <p>Verifiers MAY process signatures in any order of their choice; for example, -some Verifiers might choose to process signatures corresponding to the From -field in the message header before other signatures.</p> + some Verifiers might choose to process signatures corresponding to the From + field in the message header before other signatures.</p> </li> <li> <p>Verifiers SHOULD continue to check signatures until a signature -successfully verifies to the satisfaction of the Verifier.</p> + successfully verifies to the satisfaction of the Verifier.</p> </li> <li> <p>To limit potential denial-of-service attacks, Verifiers MAY limit the total -number of signatures they will attempt to verify.</p> + number of signatures they will attempt to verify.</p> </li> <li> <p>If a Verifier module reports signatures whose evaluations produced PERMFAIL -results, Identity Assessors SHOULD ignore those signatures, acting as -though they were not present in the message.</p> + results, Identity Assessors SHOULD ignore those signatures, acting as + though they were not present in the message.</p> </li> </ul> </div> @@ -1875,33 +1884,33 @@ though they were not present in the message.</p> </div> </div> <div class="sect1"> -<h2 id="_signer_actions">5. Signer Actions</h2> +<h2 id="_signer_actions">Signer Actions</h2> <div class="sectionbody"> <div class="paragraph"> <p>The following steps are performed in order by Signers.</p> </div> <div class="sect2"> -<h3 id="_determine_whether_the_email_should_be_signed_and_by_whom">5.1. Determine Whether the Email Should Be Signed and by Whom</h3> +<h3 id="_determine_whether_the_email_should_be_signed_and_by_whom">Determine Whether the Email Should Be Signed and by Whom</h3> <div class="ulist"> <ul> <li> <p>SUBMISSION servers might only sign messages from users that are properly -authenticated and authorized.</p> + authenticated and authorized.</p> </li> <li> <p>SUBMISSION servers should not sign Received header fields if the outgoing -gateway MTA obfuscates Received header fields, for example, to hide the -details of internal topology.</p> + gateway MTA obfuscates Received header fields, for example, to hide the + details of internal topology.</p> </li> <li> <p>If an email cannot be signed for some reason, it is a local policy decision -as to what to do with that email.</p> + as to what to do with that email.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_select_a_private_key_and_corresponding_selector_information">5.2. Select a Private Key and Corresponding Selector Information</h3> +<h3 id="_select_a_private_key_and_corresponding_selector_information">Select a Private Key and Corresponding Selector Information</h3> <div class="paragraph"> <p>Currently, all selectors are equal as far as this specification is concerned, so the decision should largely be a matter of administrative convenience.</p> @@ -1918,30 +1927,30 @@ validation interval before being removed from the key server.</p> </div> </div> <div class="sect2"> -<h3 id="_normalize_the_message_to_prevent_transport_conversions">5.3. Normalize the Message to Prevent Transport Conversions</h3> +<h3 id="_normalize_the_message_to_prevent_transport_conversions">Normalize the Message to Prevent Transport Conversions</h3> <div class="ulist"> <ul> <li> <p>In order to minimize the chances of such breakage, Signers SHOULD convert -the message to a suitable MIME content-transfer encoding such as -quoted-printable or base64 before signing.</p> + the message to a suitable MIME content-transfer encoding such as + quoted-printable or base64 before signing.</p> </li> <li> <p>If the message is submitted to the Signer with any local encoding that will -be modified before transmission, that modification to canonical [RFC5322] -form MUST be done before signing. -In particular, bare CR or LF characters MUST be converted to the -SMTP-standard CRLF sequence before the message is signed.</p> + be modified before transmission, that modification to canonical [RFC5322] + form MUST be done before signing. + In particular, bare CR or LF characters MUST be converted to the + SMTP-standard CRLF sequence before the message is signed.</p> </li> <li> <p>The Signer MUST sign the message as it is expected to be received by the -Verifier rather than in some local or internal form.</p> + Verifier rather than in some local or internal form.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_determine_the_header_fields_to_sign">5.4. Determine the Header Fields to Sign</h3> +<h3 id="_determine_the_header_fields_to_sign">Determine the Header Fields to Sign</h3> <div class="ulist"> <ul> <li> @@ -1949,11 +1958,11 @@ Verifier rather than in some local or internal form.</p> </li> <li> <p>Signers SHOULD NOT sign an existing header field likely to be legitimately -modified or removed in transit.</p> + modified or removed in transit.</p> </li> <li> <p>Signers MAY include any other header fields present at the time of signing -at the discretion of the Signer</p> + at the discretion of the Signer</p> </li> <li> <p>Strategies to choose header fields,</p> @@ -1964,42 +1973,42 @@ at the discretion of the Signer</p> </li> <li> <p>Sign only header fields that are likely to be displayed to or otherwise -be likely to affect the processing of the message at the receiver.</p> + be likely to affect the processing of the message at the receiver.</p> </li> <li> -<p>Sign only "well-known" headers.</p> +<p>Sign only "well-known" headers.</p> </li> </ul> </div> </li> <li> <p>Verifiers may treat unsigned header fields with extreme skepticism, -including refusing to display them to the end user or even ignoring the -signature if it does not cover certain header fields. -For this reason, signing fields present in the message such as Date, -Subject, Reply-To, Sender, and all MIME header fields are highly advised.</p> + including refusing to display them to the end user or even ignoring the + signature if it does not cover certain header fields. + For this reason, signing fields present in the message such as Date, + Subject, Reply-To, Sender, and all MIME header fields are highly advised.</p> </li> <li> <p>The DKIM-Signature header field is always implicitly signed and MUST NOT be -included in the "h=" tag except to indicate that other preexisting -signatures are also signed.</p> + included in the "h=" tag except to indicate that other preexisting + signatures are also signed.</p> </li> <li> <p>Signers MAY claim to have signed header fields that do not exist. -When computing the signature, the nonexisting header field MUST be treated -as the null string. -This allows Signers to explicitly assert the absence of a header field; if -that header field is added later, the signature will fail.</p> + When computing the signature, the nonexisting header field MUST be treated + as the null string. + This allows Signers to explicitly assert the absence of a header field; if + that header field is added later, the signature will fail.</p> </li> <li> <p>A header field name need only be listed once more than the actual number of -that header field in a message at the time of signing in order to prevent -any further additions. -For example, if there is a single Comments header field at the time of -signing, listing Comments twice in the "h=" tag is sufficient to prevent -any number of Comments header fields from being appended; it is not -necessary (but is legal) to list Comments three or more times in the "h=" -tag.</p> + that header field in a message at the time of signing in order to prevent + any further additions. + For example, if there is a single Comments header field at the time of + signing, listing Comments twice in the "h=" tag is sufficient to prevent + any number of Comments header fields from being appended; it is not + necessary (but is legal) to list Comments three or more times in the "h=" + tag.</p> </li> </ul> </div> @@ -2015,12 +2024,12 @@ error-prone.</p> </div> <div class="paragraph"> <p>All end-user visible header fields should be signed to avoid possible -"indirect spamming". +"indirect spamming". For example, if the Subject header field is not signed, a spammer can resend a previously signed mail, replacing the legitimate subject with a one-line spam.</p> </div> <div class="sect3"> -<h4 id="_recommended_signature_content">5.4.1. Recommended Signature Content</h4> +<h4 id="_recommended_signature_content">Recommended Signature Content</h4> <div class="paragraph"> <p>Common examples of fields with addresses and fields with textual content related to the body are:</p> @@ -2050,17 +2059,17 @@ related to the body are:</p> </li> <li> <p>List-Id, List-Help, List-Unsubscribe, List-Subscribe, List-Post, -List-Owner, List-Archive</p> + List-Owner, List-Archive</p> </li> <li> -<p>If the "l=" signature tag is in use, the Content-Type field is also a -candidate for being included as it could be replaced in a way that causes -completely different content to be rendered to the receiving user.</p> +<p>If the "l=" signature tag is in use, the Content-Type field is also a + candidate for being included as it could be replaced in a way that causes + completely different content to be rendered to the receiving user.</p> </li> <li> <p>Another class of fields that may be of interest are those that convey -security-related information about the message, such as -Authentication-Results.</p> + security-related information about the message, such as + Authentication-Results.</p> </li> </ul> </div> @@ -2089,24 +2098,24 @@ messages they process and their aversion to risk.</p> </div> </div> <div class="sect3"> -<h4 id="_signatures_involving_multiple_instances_of_a_field">5.4.2. Signatures Involving Multiple Instances of a Field</h4> +<h4 id="_signatures_involving_multiple_instances_of_a_field">Signatures Involving Multiple Instances of a Field</h4> <div class="ulist"> <ul> <li> <p>Signers choosing to sign an existing header field that occurs more -than once in the message (such as Received) MUST sign the physically -last instance of that header field in the header block.</p> + than once in the message (such as Received) MUST sign the physically + last instance of that header field in the header block.</p> </li> <li> <p>Signers wishing to sign multiple instances of such a header field MUST -include the header field name multiple times in the "h=" tag of the -DKIM-Signature header field and MUST sign such header fields in order -from the bottom of the header field block to the top.</p> + include the header field name multiple times in the "h=" tag of the + DKIM-Signature header field and MUST sign such header fields in order + from the bottom of the header field block to the top.</p> </li> <li> -<p>The Signer MAY include more instances of a header field name in "h=" than -there are actual corresponding header fields so that the signature will not -verify if additional header fields of that name are added.</p> +<p>The Signer MAY include more instances of a header field name in "h=" than + there are actual corresponding header fields so that the signature will not + verify if additional header fields of that name are added.</p> </li> </ul> </div> @@ -2119,9 +2128,9 @@ existing header contains:</p> </div> <div class="literalblock"> <div class="content"> -<pre>Received: <A> -Received: <B> -Received: <C></pre> +<pre>Received: <A> +Received: <B> +Received: <C></pre> </div> </div> <div class="paragraph"> @@ -2138,7 +2147,7 @@ Received: <C></pre> </div> </div> <div class="sect2"> -<h3 id="_compute_the_message_hash_and_signature">5.5. Compute the Message Hash and Signature</h3> +<h3 id="_compute_the_message_hash_and_signature">Compute the Message Hash and Signature</h3> <div class="paragraph"> <p>The Signer MUST compute the message hash as and then sign it using the selected public-key algorithm.</p> @@ -2151,19 +2160,19 @@ and MUST make such modifications before re-signing the message.</p> </div> </div> <div class="sect2"> -<h3 id="_insert_the_dkim_signature_header_field">5.6. Insert the DKIM-Signature Header Field</h3> +<h3 id="_insert_the_dkim_signature_header_field">Insert the DKIM-Signature Header Field</h3> <div class="ulist"> <ul> <li> <p>The Signer MUST insert the DKIM-Signature header field created in the -previous step prior to transmitting the email.</p> + previous step prior to transmitting the email.</p> </li> <li> <p>The DKIM-Signature header field MUST be inserted before any other -DKIM-Signature fields in the header block.</p> + DKIM-Signature fields in the header block.</p> </li> <li> -<p>It may be placed before any existing "Received" header fields.</p> +<p>It may be placed before any existing "Received" header fields.</p> </li> </ul> </div> @@ -2171,22 +2180,22 @@ DKIM-Signature fields in the header block.</p> </div> </div> <div class="sect1"> -<h2 id="_verifier_actions">6. Verifier Actions</h2> +<h2 id="_verifier_actions">Verifier Actions</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> <p>Deferring verification until the message is accessed by the end user is -discouraged.</p> + discouraged.</p> </li> <li> <p>MTA who has performed verification MAY communicate the result of that -verification by adding a verification header field to incoming messages.</p> + verification by adding a verification header field to incoming messages.</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_extract_signatures_from_the_message">6.1. Extract Signatures from the Message</h3> +<h3 id="_extract_signatures_from_the_message">Extract Signatures from the Message</h3> <div class="ulist"> <ul> <li> @@ -2194,79 +2203,79 @@ verification by adding a verification header field to incoming messages.</p> </li> <li> <p>Verifiers MUST NOT attribute ultimate meaning to the order of multiple -DKIM-Signature header fields. -In particular, there is reason to believe that some relays will reorder the -header fields in potentially arbitrary ways.</p> + DKIM-Signature header fields. + In particular, there is reason to believe that some relays will reorder the + header fields in potentially arbitrary ways.</p> </li> <li> <p>Verifier SHOULD NOT treat a message that has one or more bad signatures and -no good signatures differently from a message with no signature at all.</p> + no good signatures differently from a message with no signature at all.</p> </li> <li> <p>A Verifier MAY limit the number of signatures it tries, in order to avoid -denial-of-service attacks.</p> + denial-of-service attacks.</p> </li> <li> -<p>If the status is "PERMFAIL", the signature failed and should not be -reconsidered.</p> +<p>If the status is "PERMFAIL", the signature failed and should not be + reconsidered.</p> </li> <li> -<p>If the status is "TEMPFAIL", the signature could not be verified at -this time but may be tried again later.</p> +<p>If the status is "TEMPFAIL", the signature could not be verified at + this time but may be tried again later.</p> </li> <li> <p>A Verifier MAY either arrange to defer the message for later processing or -try another signature; if no good signature is found and any of the -signatures resulted in a TEMPFAIL status, the Verifier MAY arrange to defer -the message for later processing.</p> + try another signature; if no good signature is found and any of the + signatures resulted in a TEMPFAIL status, the Verifier MAY arrange to defer + the message for later processing.</p> </li> </ul> </div> <div class="sect3"> -<h4 id="_validate_the_signature_header_field">6.1.1. Validate the Signature Header Field</h4> +<h4 id="_validate_the_signature_header_field">Validate the Signature Header Field</h4> <div class="ulist"> <ul> <li> <p>Implementers MUST meticulously validate the format and values in the -DKIM-Signature header field; any inconsistency or unexpected values -MUST cause the header field to be completely ignored and the Verifier -to return PERMFAIL (signature syntax error).</p> + DKIM-Signature header field; any inconsistency or unexpected values + MUST cause the header field to be completely ignored and the Verifier + to return PERMFAIL (signature syntax error).</p> </li> <li> <p>Verifiers MUST return PERMFAIL (incompatible version) when presented a -DKIM-Signature header field with a "v=" tag that is inconsistent with this -specification.</p> + DKIM-Signature header field with a "v=" tag that is inconsistent with this + specification.</p> </li> <li> -<p>If any tag listed as "required" in Section 3.5 is omitted from the -DKIM-Signature header field, the Verifier MUST ignore the DKIM-Signature -header field and return PERMFAIL (signature missing required tag).</p> +<p>If any tag listed as "required" in Section 3.5 is omitted from the + DKIM-Signature header field, the Verifier MUST ignore the DKIM-Signature + header field and return PERMFAIL (signature missing required tag).</p> </li> <li> -<p>If "d=" tag is not same or parent domain of "i=" tag, the DKIM-Signature -header field MUST be ignored, and the Verifier should return PERMFAIL -(domain mismatch).</p> +<p>If "d=" tag is not same or parent domain of "i=" tag, the DKIM-Signature + header field MUST be ignored, and the Verifier should return PERMFAIL + (domain mismatch).</p> </li> <li> -<p>If the "h=" tag does not include the From header field, the Verifier -MUST ignore the DKIM-Signature header field and return PERMFAIL (From -field not signed).</p> +<p>If the "h=" tag does not include the From header field, the Verifier + MUST ignore the DKIM-Signature header field and return PERMFAIL (From + field not signed).</p> </li> <li> <p>Verifiers MAY ignore the DKIM-Signature header field and return -PERMFAIL (signature expired) if it contains an "x=" tag and the -signature has expired.</p> + PERMFAIL (signature expired) if it contains an "x=" tag and the + signature has expired.</p> </li> </ul> </div> </div> <div class="sect3"> -<h4 id="_get_the_public_key">6.1.2. Get the Public Key</h4> +<h4 id="_get_the_public_key">Get the Public Key</h4> <div class="ulist"> <ul> <li> <p>The Verifier MUST validate the key record and MUST ignore any public-key -records that are malformed.</p> + records that are malformed.</p> </li> </ul> </div> @@ -2277,87 +2286,87 @@ the same as performing them in the order indicated,</p> <div class="olist arabic"> <ol class="arabic"> <li> -<p>The Verifier retrieves the public key using the algorithm in the "q=" tag, -the domain from the "d=" tag, and the selector from the "s=" tag.</p> +<p>The Verifier retrieves the public key using the algorithm in the "q=" tag, + the domain from the "d=" tag, and the selector from the "s=" tag.</p> </li> <li> <p>If the query for the public key fails to respond, the Verifier MAY seek a -later verification attempt by returning TEMPFAIL (key unavailable).</p> + later verification attempt by returning TEMPFAIL (key unavailable).</p> </li> <li> <p>If the query for the public key fails because the corresponding -key record does not exist, the Verifier MUST immediately return -PERMFAIL (no key for signature).</p> + key record does not exist, the Verifier MUST immediately return + PERMFAIL (no key for signature).</p> </li> <li> <p>If the query for the public key returns multiple key records, the Verifier -can choose one of the key records or may cycle through the key records</p> + can choose one of the key records or may cycle through the key records</p> </li> <li> <p>If the result returned from the query does not adhere to the format defined -in this specification, the Verifier MUST ignore the key record and return -PERMFAIL (key syntax error).</p> + in this specification, the Verifier MUST ignore the key record and return + PERMFAIL (key syntax error).</p> </li> <li> -<p>If the "h=" tag exists in the public-key record and the hash algorithm -implied by the "a=" tag in the DKIM-Signature header field is not included -in the contents of the "h=" tag, the Verifier MUST ignore the key record -and return PERMFAIL (inappropriate hash algorithm).</p> +<p>If the "h=" tag exists in the public-key record and the hash algorithm + implied by the "a=" tag in the DKIM-Signature header field is not included + in the contents of the "h=" tag, the Verifier MUST ignore the key record + and return PERMFAIL (inappropriate hash algorithm).</p> </li> <li> -<p>If the public-key data (the "p=" tag) is empty, then this key has been -revoked and the Verifier MUST treat this as a failed signature check and -return PERMFAIL (key revoked).</p> +<p>If the public-key data (the "p=" tag) is empty, then this key has been + revoked and the Verifier MUST treat this as a failed signature check and + return PERMFAIL (key revoked).</p> </li> <li> <p>If the public-key data is not suitable for use with the algorithm and key -types defined by the "a=" and "k=" tags in the DKIM-Signature header field, -the Verifier MUST immediately return PERMFAIL (inappropriate key algorithm).</p> + types defined by the "a=" and "k=" tags in the DKIM-Signature header field, + the Verifier MUST immediately return PERMFAIL (inappropriate key algorithm).</p> </li> </ol> </div> </div> <div class="sect3"> -<h4 id="_compute_the_verification">6.1.3. Compute the Verification</h4> +<h4 id="_compute_the_verification">Compute the Verification</h4> <div class="olist arabic"> <ol class="arabic"> <li> -<p>Based on the algorithm defined in the "c=" tag, the body length specified -in the "l=" tag, and the header field names in the "h=" tag, prepare a -canonicalized version of the message. -Note that this canonicalized version does not actually replace the original -content.</p> +<p>Based on the algorithm defined in the "c=" tag, the body length specified + in the "l=" tag, and the header field names in the "h=" tag, prepare a + canonicalized version of the message. + Note that this canonicalized version does not actually replace the original + content.</p> </li> <li> -<p>Based on the algorithm indicated in the "a=" tag, compute the message -hashes from the canonical copy.</p> +<p>Based on the algorithm indicated in the "a=" tag, compute the message + hashes from the canonical copy.</p> </li> <li> <p>Verify that the hash of the canonicalized message body computed in the -previous step matches the hash value conveyed in the "bh=" tag.</p> + previous step matches the hash value conveyed in the "bh=" tag.</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> <p>If the hash does not match, the Verifier SHOULD ignore the signature and -return PERMFAIL (body hash did not verify).</p> + return PERMFAIL (body hash did not verify).</p> </li> </ol> </div> </li> <li> <p>Verifiers might treat a message that contains bytes beyond the indicated -body length with suspicion and can choose to treat the signature as if it -were invalid (e.g., by returning PERMFAIL (unsigned content)).</p> + body length with suspicion and can choose to treat the signature as if it + were invalid (e.g., by returning PERMFAIL (unsigned content)).</p> </li> <li> -<p>Using the signature conveyed in the "b=" tag, verify the signature against -the header hash using the mechanism appropriate for the public-key -algorithm described in the "a=" tag.</p> +<p>Using the signature conveyed in the "b=" tag, verify the signature against + the header hash using the mechanism appropriate for the public-key + algorithm described in the "a=" tag.</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> <p>If the signature does not validate, the Verifier SHOULD ignore the -signature and return PERMFAIL (signature did not verify).</p> + signature and return PERMFAIL (signature did not verify).</p> </li> </ol> </div> @@ -2370,24 +2379,24 @@ signature and return PERMFAIL (signature did not verify).</p> </div> </div> <div class="sect2"> -<h3 id="_communicate_verification_results">6.2. Communicate Verification Results</h3> +<h3 id="_communicate_verification_results">Communicate Verification Results</h3> <div class="ulist"> <ul> <li> <p>Implementations might choose to add an email header -"Authentication-Results" (RFC5451) field to the message before passing it -on.</p> + "Authentication-Results" (RFC5451) field to the message before passing it + on.</p> </li> <li> <p>Any such header field SHOULD be inserted before any existing DKIM-Signature -or preexisting authentication status header fields in the header field -block.</p> + or preexisting authentication status header fields in the header field + block.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_interpret_resultapply_local_policy">6.3. Interpret Result/Apply Local Policy</h3> +<h3 id="_interpret_result_apply_local_policy">Interpret Result/Apply Local Policy</h3> <div class="paragraph"> <p>It is beyond the scope of this specification to describe what actions an Identity Assessor can make, but mail carrying a validated SDID presents an @@ -2397,22 +2406,22 @@ opportunity to an Identity Assessor that unauthenticated email does not.</p> </div> </div> <div class="sect1"> -<h2 id="_security_considerations">7. Security Considerations</h2> +<h2 id="_security_considerations">Security Considerations</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_ascii_art_attacks">7.1. ASCII Art Attacks</h3> +<h3 id="_ascii_art_attacks">ASCII Art Attacks</h3> <div class="paragraph"> -<p>The "relaxed" body canonicalization algorithm may enable certain types of -extremely crude "ASCII Art" attacks where a message may be conveyed by +<p>The "relaxed" body canonicalization algorithm may enable certain types of +extremely crude "ASCII Art" attacks where a message may be conveyed by adjusting the spacing between words. -If this is a concern, the "simple" body canonicalization algorithm should be +If this is a concern, the "simple" body canonicalization algorithm should be used instead.</p> </div> </div> <div class="sect2"> -<h3 id="_misuse_of_body_length_limits_l_tag">7.2. Misuse of Body Length Limits ("l=" Tag)</h3> +<h3 id="_misuse_of_body_length_limits_l_tag">Misuse of Body Length Limits ("l=" Tag)</h3> <div class="paragraph"> -<p>Use of the "l=" tag might allow display of fraudulent content without +<p>Use of the "l=" tag might allow display of fraudulent content without appropriate warning to end users.</p> </div> <div class="paragraph"> @@ -2426,7 +2435,7 @@ and Assessors might wish to ignore signatures that use the tag.</p> </div> </div> <div class="sect2"> -<h3 id="_misappropriated_private_key">7.3. Misappropriated Private Key</h3> +<h3 id="_misappropriated_private_key">Misappropriated Private Key</h3> <div class="paragraph"> <p>Private keys issued to users, rather than one used by an ADministrative Management Domain (ADMD) itself, create the usual problem of securing data @@ -2439,25 +2448,25 @@ Authentication).</p> </div> </div> <div class="sect2"> -<h3 id="_key_server_denial_of_service_attacks">7.4. Key Server Denial-of-Service Attacks</h3> +<h3 id="_key_server_denial_of_service_attacks">Key Server Denial-of-Service Attacks</h3> <div class="paragraph"> <p>Given the low overhead of verification compared with handling of the email message itself, such an attack would be difficult to mount.</p> </div> </div> <div class="sect2"> -<h3 id="_attacks_against_the_dns">7.5. Attacks against the DNS</h3> +<h3 id="_attacks_against_the_dns">Attacks against the DNS</h3> <div class="paragraph"> <p>A DKIM Verifier, while verifying a DKIM-Signature header field, could be -prompted to retrieve a key record of an attacker’s choosing. +prompted to retrieve a key record of an attacker's choosing. This threat can be minimized by ensuring that name servers, including -recursive name servers, used by the Verifier enforce strict checking of "glue" +recursive name servers, used by the Verifier enforce strict checking of "glue" and other additional information in DNS responses and are therefore not vulnerable to this attack.</p> </div> </div> <div class="sect2"> -<h3 id="_replayspam_attacks">7.6. Replay/Spam Attacks</h3> +<h3 id="_replay_spam_attacks">Replay/Spam Attacks</h3> <div class="paragraph"> <p>A spammer sends a piece of spam through an MTA that signs it, banking on the reputation of the signing domain (e.g., a large popular mailbox provider) @@ -2476,18 +2485,17 @@ victim appear to be a spammer.</p> </div> </div> <div class="sect2"> -<h3 id="_limits_on_revoking_keys">7.7. Limits on Revoking Keys</h3> - +<h3 id="_limits_on_revoking_keys">Limits on Revoking Keys</h3> </div> <div class="sect2"> -<h3 id="_intentionally_malformed_key_records">7.8. Intentionally Malformed Key Records</h3> +<h3 id="_intentionally_malformed_key_records">Intentionally Malformed Key Records</h3> <div class="paragraph"> <p>Verifiers MUST thoroughly verify all key records retrieved from the DNS and be robust against intentionally as well as unintentionally malformed key records.</p> </div> </div> <div class="sect2"> -<h3 id="_intentionally_malformed_dkim_signature_header_fields">7.9. Intentionally Malformed DKIM-Signature Header Fields</h3> +<h3 id="_intentionally_malformed_dkim_signature_header_fields">Intentionally Malformed DKIM-Signature Header Fields</h3> <div class="paragraph"> <p>Verifiers MUST be prepared to receive messages with malformed DKIM-Signature header fields and thoroughly verify the header field before depending on any @@ -2495,17 +2503,17 @@ of its contents.</p> </div> </div> <div class="sect2"> -<h3 id="_information_leakage">7.10. Information Leakage</h3> +<h3 id="_information_leakage">Information Leakage</h3> <div class="paragraph"> <p>An attacker could determine when a particular signature was verified by using a per-message selector and then monitoring their DNS traffic for the key lookup. -This would act as the equivalent of a "web bug" for verification time rather +This would act as the equivalent of a "web bug" for verification time rather than the time the message was read.</p> </div> </div> <div class="sect2"> -<h3 id="_remote_timing_attacks">7.11. Remote Timing Attacks</h3> +<h3 id="_remote_timing_attacks">Remote Timing Attacks</h3> <div class="paragraph"> <p>In some cases, it may be possible to extract private keys using a remote timing attack [BONEH03]. @@ -2514,14 +2522,14 @@ attacks.</p> </div> </div> <div class="sect2"> -<h3 id="_reordered_header_fields">7.12. Reordered Header Fields</h3> +<h3 id="_reordered_header_fields">Reordered Header Fields</h3> <div class="paragraph"> <p>Signers that sign any existing DKIM-Signature fields run the risk of having messages incorrectly fail to verify.</p> </div> </div> <div class="sect2"> -<h3 id="_rsa_attacks">7.13. RSA Attacks</h3> +<h3 id="_rsa_attacks">RSA Attacks</h3> <div class="paragraph"> <p>Verifiers might avoid this attack by refusing to verify signatures that reference selectors with public keys having unreasonable exponents.</p> @@ -2529,11 +2537,16 @@ reference selectors with public keys having unreasonable exponents.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/DKIM_THREATS.html b/doc/DKIM_THREATS.html index 3f3b5a6a..c74c0c68 100644 --- a/doc/DKIM_THREATS.html +++ b/doc/DKIM_THREATS.html @@ -1,52 +1,60 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>Analysis of Threats Motivating DomainKeys Identified Mail (DKIM)</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>Analysis of Threats Motivating DomainKeys Identified Mail (DKIM)</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>Analysis of Threats Motivating DomainKeys Identified Mail (DKIM)</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>Analysis of Threats Motivating DomainKeys Identified Mail (DKIM)</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a> +<li><a href="#_introduction">Introduction</a> <ul class="sectlevel2"> -<li><a href="#_terminology_and_model">1.1. Terminology and Model</a></li> +<li><a href="#_terminology_and_model">Terminology and Model</a></li> </ul> </li> -<li><a href="#_the_bad_actors">2. The Bad Actors</a> +<li><a href="#_the_bad_actors">The Bad Actors</a> <ul class="sectlevel2"> -<li><a href="#_location">2.1. Location</a></li> +<li><a href="#_location">Location</a></li> </ul> </li> -<li><a href="#_representative_bad_acts">3. Representative Bad Acts</a> +<li><a href="#_representative_bad_acts">Representative Bad Acts</a> <ul class="sectlevel2"> -<li><a href="#_use_of_arbitrary_identities">3.1. Use of Arbitrary Identities</a></li> -<li><a href="#_use_of_specific_identities">3.2. Use of Specific Identities</a></li> +<li><a href="#_use_of_arbitrary_identities">Use of Arbitrary Identities</a></li> +<li><a href="#_use_of_specific_identities">Use of Specific Identities</a></li> </ul> </li> -<li><a href="#_attacks_on_message_signing">4. Attacks on Message Signing</a> +<li><a href="#_attacks_on_message_signing">Attacks on Message Signing</a> <ul class="sectlevel2"> -<li><a href="#_attacks_against_message_signatures">4.1. Attacks against Message Signatures</a></li> -<li><a href="#_attacks_against_message_signing_practices">4.2. Attacks against Message Signing Practices</a></li> -<li><a href="#_other_attacks">4.3. Other Attacks</a></li> +<li><a href="#_attacks_against_message_signatures">Attacks against Message Signatures</a></li> +<li><a href="#_attacks_against_message_signing_practices">Attacks against Message Signing Practices</a></li> +<li><a href="#_other_attacks">Other Attacks</a></li> </ul> </li> -<li><a href="#_derived_requirements">5. Derived Requirements</a></li> +<li><a href="#_derived_requirements">Derived Requirements</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -56,19 +64,19 @@ Motivating DomainKeys Identified Mail (DKIM).</p> </div> </div> <div class="sect1"> -<h2 id="_introduction">1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> <p>The DKIM protocol defines a mechanism by which email messages can be cryptographically signed by Message Submission Agent (MSA) based on domain name. -Recipients then can verify the signature by querying the signer’s domain +Recipients then can verify the signature by querying the signer's domain directly to retrieve the appropriate public key, and thereby confirm that the message was attested to by a party in possession of the private key for the signing domain.</p> </div> <div class="sect2"> -<h3 id="_terminology_and_model">1.1. Terminology and Model</h3> +<h3 id="_terminology_and_model">Terminology and Model</h3> <div class="paragraph"> <p>An administrative unit (AU) is the portion of the path of an email message that is under common administration.</p> @@ -94,14 +102,14 @@ that is under common administration.</p> +-----------+ | SIGNATURE VERIFICATION | | | | (Relaying or Delivering AU) | | KEY | | | - | QUERY +--->| Verify (Message, Domain, Key) | + | QUERY +--->| Verify (Message, Domain, Key) | | | | | +-----------+ +----------------+----------------+ | - Verified Domain +-----------+ V - [Report] | SENDER | +----------------+----------------+ | SIGNING | | | - | PRACTICES +--->| SIGNER EVALUATION | + | PRACTICES +--->| SIGNER EVALUATION | | QUERY | | | +-----------+ +---------------------------------+</pre> </div> @@ -156,7 +164,7 @@ a few users</p> </div> </div> <div class="sect1"> -<h2 id="_the_bad_actors">2. The Bad Actors</h2> +<h2 id="_the_bad_actors">The Bad Actors</h2> <div class="sectionbody"> <div class="paragraph"> <p>The bad actors are expected to have access to the following:</p> @@ -218,7 +226,7 @@ of DNS-based keys or signing practices.</p> </li> <li> <p>Access to significant computing resources, for example, through the -conscription of worm-infected "zombie" computers. +conscription of worm-infected "zombie" computers. This could allow the bad actor to perform various types of brute-force attacks.</p> </li> @@ -228,7 +236,7 @@ attacks.</p> </ul> </div> <div class="sect2"> -<h3 id="_location">2.1. Location</h3> +<h3 id="_location">Location</h3> <div class="paragraph"> <p>The bad actors can reside inside the AU or outside the AU.</p> </div> @@ -247,7 +255,7 @@ MSA.</p> </div> </div> <div class="sect1"> -<h2 id="_representative_bad_acts">3. Representative Bad Acts</h2> +<h2 id="_representative_bad_acts">Representative Bad Acts</h2> <div class="sectionbody"> <div class="paragraph"> <p>One of the most fundamental bad acts being attempted is the delivery @@ -255,7 +263,7 @@ of messages that are not intended to have been sent by the alleged originating domain.</p> </div> <div class="sect2"> -<h3 id="_use_of_arbitrary_identities">3.1. Use of Arbitrary Identities</h3> +<h3 id="_use_of_arbitrary_identities">Use of Arbitrary Identities</h3> <div class="paragraph"> <p>DKIM is not effective against the use of addresses controlled by bad actors.</p> </div> @@ -266,7 +274,7 @@ addresses and/or the likelihood that signed messages are desirable.</p> </div> </div> <div class="sect2"> -<h3 id="_use_of_specific_identities">3.2. Use of Specific Identities</h3> +<h3 id="_use_of_specific_identities">Use of Specific Identities</h3> <div class="paragraph"> <p>DKIM is not effective against the domains controlled by bad actors.</p> </div> @@ -277,7 +285,7 @@ The primary means for establishing this is the use of Sender Signing Practices (SSP).</p> </div> <div class="sect3"> -<h4 id="_exploitation_of_social_relationships">3.2.1. Exploitation of Social Relationships</h4> +<h4 id="_exploitation_of_social_relationships">Exploitation of Social Relationships</h4> <div class="paragraph"> <p>DKIM could be effective in mitigating these acts by limiting the scope of origin addresses for which a valid signature can be obtained when sending the @@ -285,7 +293,7 @@ messages from other locations.</p> </div> </div> <div class="sect3"> -<h4 id="_identity_related_fraud">3.2.2. Identity-Related Fraud</h4> +<h4 id="_identity_related_fraud">Identity-Related Fraud</h4> <div class="paragraph"> <p>DKIM is effective in defending against the fraudulent use of origin addresses on signed messages. @@ -296,16 +304,16 @@ messages.</p> </div> </div> <div class="sect3"> -<h4 id="_reputation_attacks">3.2.3. Reputation Attacks</h4> +<h4 id="_reputation_attacks">Reputation Attacks</h4> <div class="paragraph"> <p>It is for this reason that reputation systems must be based on an identity that is, in practice, fairly reliable.</p> </div> </div> <div class="sect3"> -<h4 id="_reflection_attacks">3.2.4. Reflection Attacks</h4> +<h4 id="_reflection_attacks">Reflection Attacks</h4> <div class="paragraph"> -<p>It is common and useful practice for a message’s return path not to correspond +<p>It is common and useful practice for a message's return path not to correspond to the origin address. For these reasons, DKIM is not effective against reflection attacks.</p> </div> @@ -314,193 +322,193 @@ For these reasons, DKIM is not effective against reflection attacks.</p> </div> </div> <div class="sect1"> -<h2 id="_attacks_on_message_signing">4. Attacks on Message Signing</h2> +<h2 id="_attacks_on_message_signing">Attacks on Message Signing</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_attacks_against_message_signatures">4.1. Attacks against Message Signatures</h3> +<h3 id="_attacks_against_message_signatures">Attacks against Message Signatures</h3> <div class="paragraph"> <p>The following is a summary of postulated attacks against DKIM signatures:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> -<col style="width: 80%;"> -<col style="width: 10%;"> -<col style="width: 10%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3334%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Attack Name</th> -<th class="tableblock halign-left valign-middle">Impact</th> -<th class="tableblock halign-left valign-middle">Likelihood</th> +<th class="tableblock halign-left valign-top">Impact</th> +<th class="tableblock halign-left valign-top">Likelihood</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Theft of private key for domain</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Theft of delegated private key</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Private key recovery via side channel attack</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Chosen message replay</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium/High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium/High</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Signed message replay</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Denial-of-service attack against verifier</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Denial-of-service attack against key service</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Canonicalization abuse</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Body length limit abuse</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Use of revoked key</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Compromise of key server</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Falsification of key service replies</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Publication of malformed key records and/or signatures</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Cryptographic weaknesses in signature generation</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Display name abuse</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> </tr> <tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">Compromised system within originator’s network</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Compromised system within originator's network</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Verification probe attack</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Key publication by higher-level domain</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> </tr> </tbody> </table> </div> <div class="sect2"> -<h3 id="_attacks_against_message_signing_practices">4.2. Attacks against Message Signing Practices</h3> +<h3 id="_attacks_against_message_signing_practices">Attacks against Message Signing Practices</h3> <div class="paragraph"> <p>The following is a summary of postulated attacks against signing practices:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> -<col style="width: 80%;"> -<col style="width: 10%;"> -<col style="width: 10%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3334%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Attack Name</th> -<th class="tableblock halign-left valign-middle">Impact</th> -<th class="tableblock halign-left valign-middle">Likelihood</th> +<th class="tableblock halign-left valign-top">Impact</th> +<th class="tableblock halign-left valign-top">Likelihood</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Look-alike domain names</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Internationalized domain name abuse</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Denial-of-service attack against signing practices</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Use of multiple From addresses</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Low</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Abuse of third-party signatures</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">High</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Falsification of Sender Signing Practices replies</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> </tbody> </table> </div> <div class="sect2"> -<h3 id="_other_attacks">4.3. Other Attacks</h3> +<h3 id="_other_attacks">Other Attacks</h3> <table class="tableblock frame-all grid-all stretch"> <colgroup> -<col style="width: 80%;"> -<col style="width: 10%;"> -<col style="width: 10%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3333%;"> +<col style="width: 33.3334%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Attack Name</th> -<th class="tableblock halign-left valign-middle">Impact</th> -<th class="tableblock halign-left valign-middle">Likelihood</th> +<th class="tableblock halign-left valign-top">Impact</th> +<th class="tableblock halign-left valign-top">Likelihood</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Packet amplification attacks via DNS</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">N/A</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">Medium</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">N/A</p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">Medium</p></td> </tr> </tbody> </table> @@ -508,7 +516,7 @@ practices:</p> </div> </div> <div class="sect1"> -<h2 id="_derived_requirements">5. Derived Requirements</h2> +<h2 id="_derived_requirements">Derived Requirements</h2> <div class="sectionbody"> <div class="paragraph"> <p>These requirements include:</p> @@ -539,11 +547,16 @@ expected cryptographic developments several years in the future.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/ESMTP_AUTH.adoc b/doc/ESMTP_AUTH.adoc index c1e06178..e550b7e8 100644 --- a/doc/ESMTP_AUTH.adoc +++ b/doc/ESMTP_AUTH.adoc @@ -1,7 +1,7 @@ = SMTP Service Extension for Authentication :author: Shulhan :email: <ms@kilabit.info> -:toc: left +:toc: :toclevels: 4 :sectnums: :stylesheet: style.css diff --git a/doc/ESMTP_AUTH.html b/doc/ESMTP_AUTH.html index 3ae59185..73a2408d 100644 --- a/doc/ESMTP_AUTH.html +++ b/doc/ESMTP_AUTH.html @@ -1,49 +1,57 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>SMTP Service Extension for Authentication</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article toc2 toc-left"> -<div id="header"> -<h1>SMTP Service Extension for Authentication</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc2"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>SMTP Service Extension for Authentication</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>SMTP Service Extension for Authentication</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_ehlo_extension">1. EHLO Extension</a> +<li><a href="#_ehlo_extension">EHLO Extension</a> <ul class="sectlevel2"> -<li><a href="#_common_response">1.1. Common Response</a></li> +<li><a href="#_common_response">Common Response</a></li> </ul> </li> -<li><a href="#_auth_command">2. AUTH Command</a> +<li><a href="#_auth_command">AUTH Command</a> <ul class="sectlevel2"> -<li><a href="#_direct_handshake">2.1. Direct Handshake</a></li> -<li><a href="#_indirect_handshake">2.2. Indirect Handshake</a></li> -<li><a href="#_response">2.3. Response</a> +<li><a href="#_direct_handshake">Direct Handshake</a></li> +<li><a href="#_indirect_handshake">Indirect Handshake</a></li> +<li><a href="#_response">Response</a> <ul class="sectlevel3"> -<li><a href="#_success_response">2.3.1. Success Response</a></li> -<li><a href="#_error_response">2.3.2. Error Response</a></li> +<li><a href="#_success_response">Success Response</a></li> +<li><a href="#_error_response">Error Response</a></li> </ul> </li> -<li><a href="#_canceling_auth">2.4. Canceling AUTH</a></li> +<li><a href="#_canceling_auth">Canceling AUTH</a></li> </ul> </li> -<li><a href="#_auth_parameter_for_mail_from_command">3. AUTH Parameter for MAIL FROM Command</a></li> -<li><a href="#_additional_requirements_on_servers">4. Additional Requirements on Servers</a></li> -<li><a href="#_security_considerations">5. Security Considerations</a></li> +<li><a href="#_auth_parameter_for_mail_from_command">AUTH Parameter for MAIL FROM Command</a></li> +<li><a href="#_additional_requirements_on_servers">Additional Requirements on Servers</a></li> +<li><a href="#_security_considerations">Security Considerations</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -53,23 +61,23 @@ Authentication.</p> </div> </div> <div class="sect1"> -<h2 id="_ehlo_extension">1. EHLO Extension</h2> +<h2 id="_ehlo_extension">EHLO Extension</h2> <div class="sectionbody"> <div class="paragraph"> -<p>The EHLO keyword associated with this extension is "AUTH".</p> +<p>The EHLO keyword associated with this extension is "AUTH".</p> </div> <div class="paragraph"> -<p>This extension provide one command "AUTH".</p> +<p>This extension provide one command "AUTH".</p> </div> <div class="paragraph"> -<p>This extension add one optional parameter to MAIL FROM command: "AUTH"</p> +<p>This extension add one optional parameter to MAIL FROM command: "AUTH"</p> </div> <div class="paragraph"> <p>This extension extends the maximum line length of the MAIL FROM command to 500 characters.</p> </div> <div class="sect2"> -<h3 id="_common_response">1.1. Common Response</h3> +<h3 id="_common_response">Common Response</h3> <div class="ulist"> <ul> <li> @@ -86,7 +94,7 @@ requested action.</p> </div> </div> <div class="sect1"> -<h2 id="_auth_command">2. AUTH Command</h2> +<h2 id="_auth_command">AUTH Command</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -102,7 +110,7 @@ initial-response = base64</pre> on mechanism.</p> </div> <div class="paragraph"> -<p>Initial-response "=" is response with zero length, to indicate that the +<p>Initial-response "=" is response with zero length, to indicate that the response is present.</p> </div> <div class="paragraph"> @@ -118,9 +126,9 @@ reply.</p> non-directly with initial-response in the second response.</p> </div> <div class="sect2"> -<h3 id="_direct_handshake">2.1. Direct Handshake</h3> +<h3 id="_direct_handshake">Direct Handshake</h3> <div class="paragraph"> -<p>In this mode, the $INITIAL_RESPONSE contains non empty text other than "=". +<p>In this mode, the $INITIAL_RESPONSE contains non empty text other than "=". This mode SHOULD be used when length of command line less than maximum (512 octets), to minimize round-trip to server.</p> </div> @@ -134,7 +142,7 @@ S: 235 2.7.0 Authentication successful</pre> </div> </div> <div class="sect2"> -<h3 id="_indirect_handshake">2.2. Indirect Handshake</h3> +<h3 id="_indirect_handshake">Indirect Handshake</h3> <div class="paragraph"> <p>In this mode, the $INITIAL_RESPONSE is empty, which cost client additional step. @@ -157,9 +165,9 @@ $MECHANISM.</p> </div> </div> <div class="sect2"> -<h3 id="_response">2.3. Response</h3> +<h3 id="_response">Response</h3> <div class="sect3"> -<h4 id="_success_response">2.3.1. Success Response</h4> +<h4 id="_success_response">Success Response</h4> <div class="literalblock"> <div class="content"> <pre>"235" SP "2.7.0 Authentication successful" CRLF</pre> @@ -171,7 +179,7 @@ SASL negotiation that results in the enabling of a security layer.</p> </div> </div> <div class="sect3"> -<h4 id="_error_response">2.3.2. Error Response</h4> +<h4 id="_error_response">Error Response</h4> <div class="ulist"> <ul> <li> @@ -262,9 +270,9 @@ presenting a password dialog box).</p> </div> </div> <div class="sect2"> -<h3 id="_canceling_auth">2.4. Canceling AUTH</h3> +<h3 id="_canceling_auth">Canceling AUTH</h3> <div class="paragraph"> -<p>Client can cancel authentication, for example when client can’t decode base64 +<p>Client can cancel authentication, for example when client can't decode base64 from server, by sending,</p> </div> <div class="literalblock"> @@ -279,11 +287,11 @@ from server, by sending,</p> </div> </div> <div class="sect1"> -<h2 id="_auth_parameter_for_mail_from_command">3. AUTH Parameter for MAIL FROM Command</h2> +<h2 id="_auth_parameter_for_mail_from_command">AUTH Parameter for MAIL FROM Command</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> -<pre>"AUTH=" (mailbox / "<>")</pre> +<pre>"AUTH=" (mailbox / "<>")</pre> </div> </div> <div class="paragraph"> @@ -304,7 +312,7 @@ the authenticated identity that resulted from the AUTH command.</p> <div class="paragraph"> <p>If the AUTH parameter is not supplied and the client has authenticated, and the server believes the message is an original submission, -the server MAY generate a <mailbox> from the user’s authenticated identity for +the server MAY generate a <mailbox> from the user's authenticated identity for use in an AUTH parameter when relaying the message to any server which supports the AUTH extension. The generated <mailbox> is implementation specific, but it MUST conform to the @@ -333,17 +341,17 @@ address when relaying the message to list subscribers.</p> </div> </div> <div class="sect1"> -<h2 id="_additional_requirements_on_servers">4. Additional Requirements on Servers</h2> +<h2 id="_additional_requirements_on_servers">Additional Requirements on Servers</h2> <div class="sectionbody"> <div class="paragraph"> -<p>Upon successful authentication, a server SHOULD use the "ESMTPA" or the -"ESMTPSA" [SMTP-TT] (when appropriate) keyword in the "with" clause of the +<p>Upon successful authentication, a server SHOULD use the "ESMTPA" or the +"ESMTPSA" [SMTP-TT] (when appropriate) keyword in the "with" clause of the Received header field.</p> </div> </div> </div> <div class="sect1"> -<h2 id="_security_considerations">5. Security Considerations</h2> +<h2 id="_security_considerations">Security Considerations</h2> <div class="sectionbody"> <div class="paragraph"> <p>Clients and servers MUST discard any knowledge obtained prior to the start of @@ -370,11 +378,16 @@ PLAIN mechanism.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/ESMTP_DSN.adoc b/doc/ESMTP_DSN.adoc index 9fb41447..fb8cf026 100644 --- a/doc/ESMTP_DSN.adoc +++ b/doc/ESMTP_DSN.adoc @@ -1,7 +1,7 @@ = Delivery Status Notification (DSN) :author: Shulhan :email: <ms@kilabit.info> -:toc: left +:toc: :toclevels: 4 :sectnums: :stylesheet: style.css diff --git a/doc/ESMTP_DSN.html b/doc/ESMTP_DSN.html index 53175b83..ae92da1d 100644 --- a/doc/ESMTP_DSN.html +++ b/doc/ESMTP_DSN.html @@ -1,57 +1,67 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>Delivery Status Notification (DSN)</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article toc2 toc-left"> -<div id="header"> -<h1>Delivery Status Notification (DSN)</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc2"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>Delivery Status Notification (DSN)</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>Delivery Status Notification (DSN)</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#SMTP-extension-DSN">1. Extension for DSN (RFC 3461)</a> +<li><a href="#SMTP-extension-DSN">Extension for DSN (RFC 3461)</a> <ul class="sectlevel2"> -<li><a href="#_relaying_to_other_confirming_smtp_server">1.1. Relaying to other confirming SMTP server</a></li> -<li><a href="#_relaying_to_non_conforming_smtp_server">1.2. Relaying to non-conforming SMTP server</a></li> -<li><a href="#_local_delivery">1.3. Local Delivery</a></li> -<li><a href="#_delays_in_delivery">1.4. Delays in delivery</a></li> -<li><a href="#_failure_on_delivery">1.5. Failure on delivery</a></li> -<li><a href="#_mailing_list">1.6. Mailing List</a></li> -<li><a href="#_mail_ret_parameter">1.7. MAIL RET Parameter</a></li> -<li><a href="#_mail_envid_parameter">1.8. MAIL ENVID Parameter</a></li> -<li><a href="#_rcpt_notify_parameter">1.9. RCPT NOTIFY Parameter</a></li> -<li><a href="#_rcpt_orcpt_parameter">1.10. RCPT ORCPT Parameter</a></li> -<li><a href="#_format_of_delivery_notifications">1.11. Format of delivery notifications</a></li> +<li><a href="#_relaying_to_other_confirming_smtp_server">Relaying to other confirming SMTP server</a></li> +<li><a href="#_relaying_to_non_conforming_smtp_server">Relaying to non-conforming SMTP server</a></li> +<li><a href="#_local_delivery">Local Delivery</a></li> +<li><a href="#_delays_in_delivery">Delays in delivery</a></li> +<li><a href="#_failure_on_delivery">Failure on delivery</a></li> +<li><a href="#_mailing_list">Mailing List</a></li> +<li><a href="#_mail_ret_parameter">MAIL RET Parameter</a></li> +<li><a href="#_mail_envid_parameter">MAIL ENVID Parameter</a></li> +<li><a href="#_rcpt_notify_parameter">RCPT NOTIFY Parameter</a></li> +<li><a href="#_rcpt_orcpt_parameter">RCPT ORCPT Parameter</a></li> +<li><a href="#_format_of_delivery_notifications">Format of delivery notifications</a></li> </ul> </li> -<li><a href="#_multipart_report_content_type_rfc_3462">2. Multipart-Report Content Type (RFC 3462)</a> +<li><a href="#_multipart_report_content_type_rfc_3462">Multipart-Report Content Type (RFC 3462)</a> <ul class="sectlevel2"> -<li><a href="#_the_textrfc822_headers_content_type">2.1. The text/rfc822-headers content-type</a></li> +<li><a href="#_the_text_rfc822_headers_content_type">The text/rfc822-headers content-type</a></li> </ul> </li> -<li><a href="#status-codes">3. Enhanced Mail System Status Codes (RFC 3463)</a> +<li><a href="#status-codes">Enhanced Mail System Status Codes (RFC 3463)</a> <ul class="sectlevel2"> -<li><a href="#_class">3.1. Class</a></li> -<li><a href="#_subject">3.2. Subject</a></li> +<li><a href="#_class">Class</a></li> +<li><a href="#_subject">Subject</a></li> </ul> </li> -<li><a href="#_message_format_for_dsn_rfc_3464">4. Message Format for DSN (RFC 3464)</a> +<li><a href="#_message_format_for_dsn_rfc_3464">Message Format for DSN (RFC 3464)</a> <ul class="sectlevel2"> -<li><a href="#_human_readable_explanation_of_the_dsn">4.1. Human readable explanation of the DSN</a></li> -<li><a href="#_machine_readable_explanation_of_dsn">4.2. Machine readable explanation of DSN</a> +<li><a href="#_human_readable_explanation_of_the_dsn">Human readable explanation of the DSN</a></li> +<li><a href="#_machine_readable_explanation_of_dsn">Machine readable explanation of DSN</a> <ul class="sectlevel3"> -<li><a href="#_format_for_message_fields">4.2.1. Format for message-fields</a></li> -<li><a href="#_format_for_recipient_fields">4.2.2. Format for recipient-fields</a> +<li><a href="#_format_for_message_fields">Format for message-fields</a></li> +<li><a href="#_format_for_recipient_fields">Format for recipient-fields</a> <ul class="sectlevel4"> <li><a href="#_original_recipient_and_final_recipient">Original-Recipient and Final-Recipient</a></li> <li><a href="#_action">Action</a></li> @@ -65,13 +75,11 @@ </li> </ul> </li> -<li><a href="#_original_message">4.3. Original message</a></li> +<li><a href="#_original_message">Original message</a></li> </ul> </li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -89,7 +97,7 @@ and a multipart container for the delivery report </div> </div> <div class="sect1"> -<h2 id="SMTP-extension-DSN">1. Extension for DSN (RFC 3461)</h2> +<h2 id="SMTP-extension-DSN">Extension for DSN (RFC 3461)</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -125,16 +133,16 @@ presence of valid parameters.</p> </div> <div class="paragraph"> <p>If the value is invalid or more than one ENVID or RET in MAIL command, -the server MUST issue the reply-code "501 syntax error in parameter".</p> +the server MUST issue the reply-code "501 syntax error in parameter".</p> </div> <div class="paragraph"> -<p>A DSN MUST NOT be returned to the sender if SMTP MAIL command was NULL ("<>"), -even if the sender’s address is available from other sources (e.g., the +<p>A DSN MUST NOT be returned to the sender if SMTP MAIL command was NULL ("<>"), +even if the sender's address is available from other sources (e.g., the message header). Instead, it SHOULD inform the local postmaster of delivery failures.</p> </div> <div class="sect2"> -<h3 id="_relaying_to_other_confirming_smtp_server">1.1. Relaying to other confirming SMTP server</h3> +<h3 id="_relaying_to_other_confirming_smtp_server">Relaying to other confirming SMTP server</h3> <div class="paragraph"> <p>Any DSN extension parameter that is received MUST also appear on MAIL and/or RCPT command which the message is relayed.</p> @@ -145,14 +153,14 @@ relayed using address from RCPT command.</p> </div> </div> <div class="sect2"> -<h3 id="_relaying_to_non_conforming_smtp_server">1.2. Relaying to non-conforming SMTP server</h3> +<h3 id="_relaying_to_non_conforming_smtp_server">Relaying to non-conforming SMTP server</h3> <div class="paragraph"> <p>If NOTIFY paramater contains SUCCESS and SMTP server return a success -(2xx) to RCPT command, client MUST issue a "relayed" DSN for that recipient.</p> +(2xx) to RCPT command, client MUST issue a "relayed" DSN for that recipient.</p> </div> <div class="paragraph"> -<p>If NOTIFY parameter contains "FAILURE" and SMTP server return a permanent -failure (5xx) to RCPT command, client MUST issue a "failed" DSN for that +<p>If NOTIFY parameter contains "FAILURE" and SMTP server return a permanent +failure (5xx) to RCPT command, client MUST issue a "failed" DSN for that recipient.</p> </div> <div class="paragraph"> @@ -162,7 +170,7 @@ recipient. Client MAY inform the local postmaster of the delivery failure.</p> </div> <div class="paragraph"> -<p>If NOTIFY parameter contains NEVER, client MAY use "<>" on +<p>If NOTIFY parameter contains NEVER, client MAY use "<>" on separate MAIL command.</p> </div> <div class="paragraph"> @@ -170,14 +178,14 @@ separate MAIL command.</p> DSN for that recipient.</p> </div> <div class="paragraph"> -<p>If no NOTIFY parameter, and server return 5xx, client MUST issue a "failed" +<p>If no NOTIFY parameter, and server return 5xx, client MUST issue a "failed" DSN for that recipient.</p> </div> </div> <div class="sect2"> -<h3 id="_local_delivery">1.3. Local Delivery</h3> +<h3 id="_local_delivery">Local Delivery</h3> <div class="paragraph"> -<p>If NOTIFY contains SUCCESS, MTA MUST issue "delivered" DSN for that +<p>If NOTIFY contains SUCCESS, MTA MUST issue "delivered" DSN for that recipient.</p> </div> <div class="paragraph"> @@ -186,20 +194,20 @@ for that recipient.</p> </div> </div> <div class="sect2"> -<h3 id="_delays_in_delivery">1.4. Delays in delivery</h3> +<h3 id="_delays_in_delivery">Delays in delivery</h3> <div class="paragraph"> -<p>If NOTIFY contains DELAY or no NOTIFY parameter, MTA MAY issue "delayed" DSN +<p>If NOTIFY contains DELAY or no NOTIFY parameter, MTA MAY issue "delayed" DSN for that recipient.</p> </div> <div class="paragraph"> <p>If NOTIFY parameter is issued without DELAY keyword, MTA MUST NOT issue -"delayed" DSN for that recipient.</p> +"delayed" DSN for that recipient.</p> </div> </div> <div class="sect2"> -<h3 id="_failure_on_delivery">1.5. Failure on delivery</h3> +<h3 id="_failure_on_delivery">Failure on delivery</h3> <div class="paragraph"> -<p>If NOTIFY parameter contains FAILURE or no NOTIFY parameter, a "failed" +<p>If NOTIFY parameter contains FAILURE or no NOTIFY parameter, a "failed" DSN MUST be issued.</p> </div> <div class="paragraph"> @@ -208,10 +216,10 @@ it MAY inform the local postmaster via mechanism that does not using DSN.</p> </div> </div> <div class="sect2"> -<h3 id="_mailing_list">1.6. Mailing List</h3> +<h3 id="_mailing_list">Mailing List</h3> <div class="paragraph"> -<p>If NOTIFY parameter contains SUCCESS, and the message is placed on list’s -mailbox or accepted by list’s server, a "delivered" DSN must be issued.</p> +<p>If NOTIFY parameter contains SUCCESS, and the message is placed on list's +mailbox or accepted by list's server, a "delivered" DSN must be issued.</p> </div> <div class="paragraph"> <p>When redistributed to members of mailing list,</p> @@ -235,14 +243,14 @@ original message.</p> </div> </div> <div class="sect2"> -<h3 id="_mail_ret_parameter">1.7. MAIL RET Parameter</h3> +<h3 id="_mail_ret_parameter">MAIL RET Parameter</h3> <div class="literalblock"> <div class="content"> <pre>"RET=" "FULL" / "HDRS"</pre> </div> </div> <div class="paragraph"> -<p><code>FULL</code> requests that the entire message be returned in any "failed" DSN issued +<p><code>FULL</code> requests that the entire message be returned in any "failed" DSN issued for this recipient.</p> </div> <div class="paragraph"> @@ -264,7 +272,7 @@ message SHOULD be returned.</p> </div> </div> <div class="sect2"> -<h3 id="_mail_envid_parameter">1.8. MAIL ENVID Parameter</h3> +<h3 id="_mail_envid_parameter">MAIL ENVID Parameter</h3> <div class="literalblock"> <div class="content"> <pre>"ENVID=" *xtext</pre> @@ -283,7 +291,7 @@ the US-ASCII.</p> </div> </div> <div class="sect2"> -<h3 id="_rcpt_notify_parameter">1.9. RCPT NOTIFY Parameter</h3> +<h3 id="_rcpt_notify_parameter">RCPT NOTIFY Parameter</h3> <div class="literalblock"> <div class="content"> <pre>"NOTIFY=" "NEVER" / ("SUCCESS" [ "," "FAILURE"] [ "," "DELAY" ])</pre> @@ -293,15 +301,15 @@ the US-ASCII.</p> <p>The NEVER keyword MUST appear by itself.</p> </div> <div class="paragraph"> -<p>"NEVER" requests that a DSN not be returned to the sender under any +<p>"NEVER" requests that a DSN not be returned to the sender under any conditions.</p> </div> <div class="paragraph"> -<p>"SUCCESS" or "FAILURE" value indicated that a DSN be issued on successful +<p>"SUCCESS" or "FAILURE" value indicated that a DSN be issued on successful delivery or delivery failure, respectively.</p> </div> <div class="paragraph"> -<p>"DELAY" indicates the sender’s willingness to receive "delayed" DSNs.</p> +<p>"DELAY" indicates the sender's willingness to receive "delayed" DSNs.</p> </div> <div class="paragraph"> <p>It MAY be up to 28 characters.</p> @@ -312,14 +320,14 @@ delivery or delivery failure, respectively.</p> </div> </div> <div class="sect2"> -<h3 id="_rcpt_orcpt_parameter">1.10. RCPT ORCPT Parameter</h3> +<h3 id="_rcpt_orcpt_parameter">RCPT ORCPT Parameter</h3> <div class="literalblock"> <div class="content"> <pre>"ORCPT=" addr-type ";" xtext</pre> </div> </div> <div class="paragraph"> -<p>ORCPT parameter is used to specify an "original" recipient address that +<p>ORCPT parameter is used to specify an "original" recipient address that corresponds to the actual recipient.</p> </div> <div class="paragraph"> @@ -339,9 +347,9 @@ the message.</p> </div> </div> <div class="sect2"> -<h3 id="_format_of_delivery_notifications">1.11. Format of delivery notifications</h3> +<h3 id="_format_of_delivery_notifications">Format of delivery notifications</h3> <div class="paragraph"> -<p>MAIL command argument MUST be a null ("<>").</p> +<p>MAIL command argument MUST be a null ("<>").</p> </div> <div class="paragraph"> <p>RCPT command argument is copied from the original message MAIL command.</p> @@ -352,22 +360,22 @@ The NOTIFY parameter MAY be used, with value MUST be NEVER. The ENVID and/or ORCPT parameter MAY be used.</p> </div> <div class="paragraph"> -<p>The MIME message is "multipart/report" with "report-type" is -"delivery-status".</p> +<p>The MIME message is "multipart/report" with "report-type" is +"delivery-status".</p> </div> </div> </div> </div> <div class="sect1"> -<h2 id="_multipart_report_content_type_rfc_3462">2. Multipart-Report Content Type (RFC 3462)</h2> +<h2 id="_multipart_report_content_type_rfc_3462">Multipart-Report Content Type (RFC 3462)</h2> <div class="sectionbody"> <div class="paragraph"> -<p>This section provide summary and notes on implementation of "multipart/report" +<p>This section provide summary and notes on implementation of "multipart/report" MIME type on SMTP protocol as defined in <a href="https://tools.ietf.org/html/rfc3462">RFC 3462</a>.</p> </div> <div class="paragraph"> <p>The Multipart/Report Multipurpose Internet Mail Extensions (MIME) content-type -is a general "family" or "container" type for electronic mail reports of any +is a general "family" or "container" type for electronic mail reports of any kind.</p> </div> <div class="paragraph"> @@ -398,7 +406,7 @@ the reported message handling event. The purpose of this body part is to provide a machine-readable description of the conditions that caused the report to be generated, along with details not present in the first body part that may be useful to human experts. An initial -body part, "message/delivery-status" is defined in RFC 3464 (see below).</p> +body part, "message/delivery-status" is defined in RFC 3464 (see below).</p> </li> <li> <p>(Optional) A body part containing the returned message or a portion @@ -407,7 +415,7 @@ thereof.</p> </ol> </div> <div class="sect2"> -<h3 id="_the_textrfc822_headers_content_type">2.1. The text/rfc822-headers content-type</h3> +<h3 id="_the_text_rfc822_headers_content_type">The text/rfc822-headers content-type</h3> <div class="paragraph"> <p>Format,</p> </div> @@ -424,7 +432,7 @@ from the message which caused the report.</p> </div> </div> <div class="sect1"> -<h2 id="status-codes">3. Enhanced Mail System Status Codes (RFC 3463)</h2> +<h2 id="status-codes">Enhanced Mail System Status Codes (RFC 3463)</h2> <div class="sectionbody"> <div class="paragraph"> <p>Syntax,</p> @@ -445,7 +453,7 @@ detail = 1*3digit</pre> zero digits.</p> </div> <div class="sect2"> -<h3 id="_class">3.1. Class</h3> +<h3 id="_class">Class</h3> <div class="ulist"> <ul> <li> @@ -461,14 +469,14 @@ zero digits.</p> </div> </div> <div class="sect2"> -<h3 id="_subject">3.2. Subject</h3> +<h3 id="_subject">Subject</h3> <div class="ulist"> <ul> <li> <p>X.0.XXX Other or Undefined Status</p> </li> <li> -<p>X.1.XXX Addressing Status. Problem on sender’s recipient address.</p> +<p>X.1.XXX Addressing Status. Problem on sender's recipient address.</p> <div class="ulist"> <ul> <li> @@ -493,10 +501,10 @@ zero digits.</p> <p>X.1.6 Mailbox has moved</p> </li> <li> -<p>X.1.7 Bad sender’s mailbox address syntax</p> +<p>X.1.7 Bad sender's mailbox address syntax</p> </li> <li> -<p>X.1.8 Bad sender’s system address</p> +<p>X.1.8 Bad sender's system address</p> </li> </ul> </div> @@ -663,14 +671,14 @@ zero digits.</p> </div> </div> <div class="sect1"> -<h2 id="_message_format_for_dsn_rfc_3464">4. Message Format for DSN (RFC 3464)</h2> +<h2 id="_message_format_for_dsn_rfc_3464">Message Format for DSN (RFC 3464)</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section provide summary and notes on implementation of DSN on SMTP protocol as defined in <a href="https://tools.ietf.org/html/rfc3464">RFC 3464</a>.</p> </div> <div class="paragraph"> -<p>A DSN is a "multipart/report" MIME message with three components,</p> +<p>A DSN is a "multipart/report" MIME message with three components,</p> </div> <div class="olist arabic"> <ol class="arabic"> @@ -686,15 +694,15 @@ protocol as defined in <a href="https://tools.ietf.org/html/rfc3464">RFC 3464</a </ol> </div> <div class="sect2"> -<h3 id="_human_readable_explanation_of_the_dsn">4.1. Human readable explanation of the DSN</h3> +<h3 id="_human_readable_explanation_of_the_dsn">Human readable explanation of the DSN</h3> <div class="paragraph"> <p>Format,</p> </div> <div class="literalblock"> <div class="content"> <pre>Date: {timestamp-with-zone} -From: Mail Delivery Subsystem <MAILER-DAEMON@CS.UTK.EDU> -To: <owner-info-mime@cs.utk.edu> +From: Mail Delivery Subsystem <MAILER-DAEMON@CS.UTK.EDU> +To: <owner-info-mime@cs.utk.edu> MIME-Version: 1.0 Content-Type: message/report; report-type=delivery-status; @@ -707,17 +715,17 @@ Subject: Returned mail: Cannot send message for 5 days </div> </div> <div class="paragraph"> -<p>The "From" field of message header of DSN SHOULD contain the address of human +<p>The "From" field of message header of DSN SHOULD contain the address of human who responsible at Reporting-MTA and SHOULD be chosen so that DSN will not generate mail loops.</p> </div> <div class="paragraph"> -<p>The "To" field of message header and "RCPT TO:" parameter is return-path from -"MAIL FROM:" command.</p> +<p>The "To" field of message header and "RCPT TO:" parameter is return-path from +"MAIL FROM:" command.</p> </div> </div> <div class="sect2"> -<h3 id="_machine_readable_explanation_of_dsn">4.2. Machine readable explanation of DSN</h3> +<h3 id="_machine_readable_explanation_of_dsn">Machine readable explanation of DSN</h3> <div class="paragraph"> <p>Header format,</p> </div> @@ -737,15 +745,15 @@ CRLF recipient-fields.</p> </div> <div class="paragraph"> -<p>Any header that start with "X-" are extension fields; such names are reserved +<p>Any header that start with "X-" are extension fields; such names are reserved for experimental use.</p> </div> <div class="paragraph"> <p>Each sender-specified recipient address SHOULD result in at most one -"delivered" or "failed" DSN for that recipient</p> +"delivered" or "failed" DSN for that recipient</p> </div> <div class="sect3"> -<h4 id="_format_for_message_fields">4.2.1. Format for message-fields</h4> +<h4 id="_format_for_message_fields">Format for message-fields</h4> <div class="literalblock"> <div class="content"> <pre>[ "Original-Envelope-Id:" SP envelope-id CRLF ] @@ -756,20 +764,20 @@ for experimental use.</p> </div> </div> <div class="paragraph"> -<p>The "Original-Envelope-ID" MUST be supplied if original message MAIL command -contains ENVID, except when a DSN is issued by the sender’s MTA itself (Sender +<p>The "Original-Envelope-ID" MUST be supplied if original message MAIL command +contains ENVID, except when a DSN is issued by the sender's MTA itself (Sender MTA = Reporting MTA)</p> </div> <div class="paragraph"> -<p>If no ENVID parameter, the "Original-Envelope-ID" field MUST NOT be supplied.</p> +<p>If no ENVID parameter, the "Original-Envelope-ID" field MUST NOT be supplied.</p> </div> <div class="paragraph"> -<p>The "envelope-id" is CASE-SENSITIVE. +<p>The "envelope-id" is CASE-SENSITIVE. The DSN MUST preserve the original case and spelling of the envelope-id.</p> </div> <div class="paragraph"> -<p>MTA-type MUST be "dns" if MTA is connected to internet, otherwise it SHOULD be -"x-local-hostname".</p> +<p>MTA-type MUST be "dns" if MTA is connected to internet, otherwise it SHOULD be +"x-local-hostname".</p> </div> <div class="paragraph"> <p>MTA-name are case sensitive. @@ -790,7 +798,7 @@ the Reporting MTA.</p> </div> </div> <div class="sect3"> -<h4 id="_format_for_recipient_fields">4.2.2. Format for recipient-fields</h4> +<h4 id="_format_for_recipient_fields">Format for recipient-fields</h4> <div class="literalblock"> <div class="content"> <pre>[ "Original-Recipient:" SP address-type ";" generic-address CRLF ] @@ -807,10 +815,10 @@ the Reporting MTA.</p> <div class="sect4"> <h5 id="_original_recipient_and_final_recipient">Original-Recipient and Final-Recipient</h5> <div class="paragraph"> -<p>address-type field is "rfc822".</p> +<p>address-type field is "rfc822".</p> </div> <div class="paragraph"> -<p>address-type field is "unknown" if the Reporting MTA cannot determine the type +<p>address-type field is "unknown" if the Reporting MTA cannot determine the type of the original recipient address from the message envelope.</p> </div> <div class="paragraph"> @@ -838,36 +846,36 @@ otherwise this field MUST NOT appear.</p> <div class="ulist"> <ul> <li> -<p>"failed" indicates that the message could not be delivered to the recipient.</p> +<p>"failed" indicates that the message could not be delivered to the recipient.</p> </li> <li> -<p>"delayed" indicates that the Reporting MTA has so far been unable +<p>"delayed" indicates that the Reporting MTA has so far been unable to deliver or relay the message, but it will continue to attempt to do so.</p> </li> <li> -<p>"delivered" indicates that the message was successfully delivered to +<p>"delivered" indicates that the message was successfully delivered to the recipient address specified by the sender. It does not indicate that the message has been read. This is a terminal state and no further DSN for this recipient should be expected.</p> </li> <li> -<p>"relayed" indicates that the message has been relayed or gateway-ed +<p>"relayed" indicates that the message has been relayed or gateway-ed into an environment that does not accept responsibility for generating DSNs upon successful delivery. This action-value SHOULD NOT be used unless the sender has requested notification of successful delivery for this recipient.</p> </li> <li> -<p>"expanded" indicates that the message has been successfully delivered to the +<p>"expanded" indicates that the message has been successfully delivered to the recipient address as specified by the sender, and forwarded by the Reporting-MTA beyond that destination to multiple additional recipient addresses. -An action-value of "expanded" differs from "delivered" in that "expanded" is +An action-value of "expanded" differs from "delivered" in that "expanded" is not a terminal state. -Further "failed" and/or "delayed" notifications may be provided. +Further "failed" and/or "delayed" notifications may be provided. This value SHOULD NOT be used with a DSN issued on delivery of a message to a -"mailing list".</p> +"mailing list".</p> </li> </ul> </div> @@ -894,7 +902,7 @@ via SMTP, the Remote-MTA field MUST be supplied for each of those recipients.</p <div class="paragraph"> <p>For DSNs resulting from attempts to relay a message to one or more recipients via SMTP, the Diagnostic-Code MUST be supplied for each of those recipients, -with diagnostic-type is set to "smtp".</p> +with diagnostic-type is set to "smtp".</p> </div> </div> <div class="sect4"> @@ -912,21 +920,21 @@ attempt are not available.</p> <div class="sect4"> <h5 id="_final_log_id">Final-Log-ID</h5> <div class="paragraph"> -<p>This can be useful as an index to the final-mta’s log entry for that delivery +<p>This can be useful as an index to the final-mta's log entry for that delivery attempt.</p> </div> </div> <div class="sect4"> <h5 id="_will_retry_until">Will-Retry-Until</h5> <div class="paragraph"> -<p>This header is for "delayed" status, which inform the final MTA the data and +<p>This header is for "delayed" status, which inform the final MTA the data and time when the message will be abandoned if delivery is keep failing.</p> </div> </div> </div> </div> <div class="sect2"> -<h3 id="_original_message">4.3. Original message</h3> +<h3 id="_original_message">Original message</h3> <div class="paragraph"> <p>This sub-part contains the original message headers and/or message data, depends on the value of RET parameter on RCPT command.</p> @@ -934,11 +942,16 @@ depends on the value of RET parameter on RCPT command.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/ESMTP_TLS.adoc b/doc/ESMTP_TLS.adoc index 0f7f8a8d..019479a4 100644 --- a/doc/ESMTP_TLS.adoc +++ b/doc/ESMTP_TLS.adoc @@ -1,7 +1,7 @@ = SMTP Service Extension for Secure SMTP over Transport Layer Security :author: Shulhan :email: <ms@kilabit.info> -:toc: left +:toc: :toclevels: 4 :sectnums: :stylesheet: style.css diff --git a/doc/ESMTP_TLS.html b/doc/ESMTP_TLS.html index 56ca0885..375bf58d 100644 --- a/doc/ESMTP_TLS.html +++ b/doc/ESMTP_TLS.html @@ -1,46 +1,54 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>SMTP Service Extension for Secure SMTP over Transport Layer Security</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article toc2 toc-left"> -<div id="header"> -<h1>SMTP Service Extension for Secure SMTP over Transport Layer Security</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc2"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>SMTP Service Extension for Secure SMTP over Transport Layer Security</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>SMTP Service Extension for Secure SMTP over Transport Layer Security</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_service_extension">1. Service Extension</a></li> -<li><a href="#_starttls_command">2. STARTTLS command</a> +<li><a href="#_service_extension">Service Extension</a></li> +<li><a href="#_starttls_command">STARTTLS command</a> <ul class="sectlevel2"> -<li><a href="#_request">2.1. Request</a> +<li><a href="#_request">Request</a> <ul class="sectlevel3"> -<li><a href="#_success_response">2.1.1. Success Response</a></li> -<li><a href="#_error_response">2.1.2. Error Response</a></li> +<li><a href="#_success_response">Success Response</a></li> +<li><a href="#_error_response">Error Response</a></li> </ul> </li> </ul> </li> -<li><a href="#_post_tls_handshake">3. Post TLS Handshake</a> +<li><a href="#_post_tls_handshake">Post TLS Handshake</a> <ul class="sectlevel2"> -<li><a href="#_client">3.1. Client</a></li> -<li><a href="#_server">3.2. Server</a></li> +<li><a href="#_client">Client</a></li> +<li><a href="#_server">Server</a></li> </ul> </li> -<li><a href="#_security_considerations">4. Security Considerations</a></li> +<li><a href="#_security_considerations">Security Considerations</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -51,14 +59,14 @@ defined in <a href="https://tools.ietf.org/html/rfc3207">RFC3207</a>.</p> </div> </div> <div class="sect1"> -<h2 id="_service_extension">1. Service Extension</h2> +<h2 id="_service_extension">Service Extension</h2> <div class="sectionbody"> <div class="paragraph"> -<p>The EHLO keyword value associated with the extension is "STARTTLS" with no +<p>The EHLO keyword value associated with the extension is "STARTTLS" with no parameter.</p> </div> <div class="paragraph"> -<p>A new SMTP command "STARTTLS" is defined.</p> +<p>A new SMTP command "STARTTLS" is defined.</p> </div> <div class="paragraph"> <p>A publicly-referenced SMTP server (on port 25) MUST NOT require use of the @@ -67,17 +75,17 @@ STARTTLS extension in order to deliver mail locally.</p> </div> </div> <div class="sect1"> -<h2 id="_starttls_command">2. STARTTLS command</h2> +<h2 id="_starttls_command">STARTTLS command</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_request">2.1. Request</h3> +<h3 id="_request">Request</h3> <div class="literalblock"> <div class="content"> <pre>"STARTTLS" CRLF</pre> </div> </div> <div class="sect3"> -<h4 id="_success_response">2.1.1. Success Response</h4> +<h4 id="_success_response">Success Response</h4> <div class="literalblock"> <div class="content"> <pre>"220" SP *text CRLF</pre> @@ -92,7 +100,7 @@ abort the connection.</p> </div> </div> <div class="sect3"> -<h4 id="_error_response">2.1.2. Error Response</h4> +<h4 id="_error_response">Error Response</h4> <div class="ulist"> <ul> <li> @@ -127,10 +135,10 @@ If the client and server are using the ENHANCEDSTATUSCODES ESMTP extension </div> </div> <div class="sect1"> -<h2 id="_post_tls_handshake">3. Post TLS Handshake</h2> +<h2 id="_post_tls_handshake">Post TLS Handshake</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_client">3.1. Client</h3> +<h3 id="_client">Client</h3> <div class="paragraph"> <p>The client MUST discard any knowledge obtained from the server, such as the list of SMTP service extensions, which was not obtained from the TLS @@ -149,7 +157,7 @@ active.</p> </div> </div> <div class="sect2"> -<h3 id="_server">3.2. Server</h3> +<h3 id="_server">Server</h3> <div class="paragraph"> <p>The server MUST discard any knowledge obtained from the client, such as the argument to the EHLO command, which was not obtained from the TLS negotiation @@ -163,7 +171,7 @@ received after a TLS handshake has completed.</p> </div> </div> <div class="sect1"> -<h2 id="_security_considerations">4. Security Considerations</h2> +<h2 id="_security_considerations">Security Considerations</h2> <div class="sectionbody"> <div class="paragraph"> <p>If the SMTP client decides that the level of authentication or privacy is not @@ -185,11 +193,16 @@ client (other than a QUIT command) with,</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/IMF.adoc b/doc/IMF.adoc index 1aa889e0..f4c6d2b0 100644 --- a/doc/IMF.adoc +++ b/doc/IMF.adoc @@ -1,7 +1,7 @@ = Internet Message Format (IMF) :author: Shulhan :email: <ms@kilabit.info> -:toc: left +:toc: :toclevels: 4 :sectnums: :stylesheet: style.css diff --git a/doc/IMF.html b/doc/IMF.html index 99f2dc9e..2defad66 100644 --- a/doc/IMF.html +++ b/doc/IMF.html @@ -1,56 +1,64 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>Internet Message Format (IMF)</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article toc2 toc-left"> -<div id="header"> -<h1>Internet Message Format (IMF)</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc2"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>Internet Message Format (IMF)</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>Internet Message Format (IMF)</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_syntax">1. Syntax</a> +<li><a href="#_syntax">Syntax</a> <ul class="sectlevel2"> -<li><a href="#_folding_white_space_and_comments">1.1. Folding White Space and Comments</a></li> -<li><a href="#_atom">1.2. Atom</a></li> -<li><a href="#_quoted_strings">1.3. Quoted Strings</a></li> -<li><a href="#_date_and_time_specification">1.4. Date and Time Specification</a></li> -<li><a href="#_address_specification">1.5. Address Specification</a></li> +<li><a href="#_folding_white_space_and_comments">Folding White Space and Comments</a></li> +<li><a href="#_atom">Atom</a></li> +<li><a href="#_quoted_strings">Quoted Strings</a></li> +<li><a href="#_date_and_time_specification">Date and Time Specification</a></li> +<li><a href="#_address_specification">Address Specification</a></li> </ul> </li> -<li><a href="#_header">2. Header</a> +<li><a href="#_header">Header</a> <ul class="sectlevel2"> -<li><a href="#_date_field">2.1. Date Field</a></li> -<li><a href="#_originator_fields">2.2. Originator Fields</a></li> -<li><a href="#_destination_fields">2.3. Destination Fields</a></li> -<li><a href="#_identification_field">2.4. Identification Field</a></li> -<li><a href="#_informational_fields">2.5. Informational Fields</a></li> -<li><a href="#_resent_fields">2.6. Resent Fields</a></li> -<li><a href="#_trace_fields">2.7. Trace Fields</a></li> -<li><a href="#_optional_fields">2.8. Optional Fields</a></li> +<li><a href="#_date_field">Date Field</a></li> +<li><a href="#_originator_fields">Originator Fields</a></li> +<li><a href="#_destination_fields">Destination Fields</a></li> +<li><a href="#_identification_field">Identification Field</a></li> +<li><a href="#_informational_fields">Informational Fields</a></li> +<li><a href="#_resent_fields">Resent Fields</a></li> +<li><a href="#_trace_fields">Trace Fields</a></li> +<li><a href="#_optional_fields">Optional Fields</a></li> </ul> </li> -<li><a href="#_obsolete_specification">3. Obsolete Specification</a> +<li><a href="#_obsolete_specification">Obsolete Specification</a> <ul class="sectlevel2"> -<li><a href="#_obsolete_date_and_time">3.1. Obsolete Date and Time</a></li> -<li><a href="#_obsolete_addressing">3.2. Obsolete Addressing</a></li> -<li><a href="#_obsolete_header_fields">3.3. Obsolete Header Fields</a></li> +<li><a href="#_obsolete_date_and_time">Obsolete Date and Time</a></li> +<li><a href="#_obsolete_addressing">Obsolete Addressing</a></li> +<li><a href="#_obsolete_header_fields">Obsolete Header Fields</a></li> </ul> </li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -60,7 +68,7 @@ Message Format as defined in <a href="https://tools.ietf.org/html/rfc5322">RFC 5 </div> </div> <div class="sect1"> -<h2 id="_syntax">1. Syntax</h2> +<h2 id="_syntax">Syntax</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -101,20 +109,20 @@ text = %d1-9 / ; Characters excluding CR </li> <li> <p>CR and LF MUST only occur together as CRLF; they MUST NOT appear -independently in the body.</p> + independently in the body.</p> </li> <li> <p>Each header field SHOULD be treated in its unfolded form for further -syntactic and semantic evaluation.</p> + syntactic and semantic evaluation.</p> </li> <li> -<p>"field-body" MUST NOT include CR and LF except when used in "folding" and -"unfolding".</p> +<p>"field-body" MUST NOT include CR and LF except when used in "folding" and + "unfolding".</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_folding_white_space_and_comments">1.1. Folding White Space and Comments</h3> +<h3 id="_folding_white_space_and_comments">Folding White Space and Comments</h3> <div class="literalblock"> <div class="content"> <pre>CFWS = (1*([FWS] comment) [FWS]) / FWS @@ -160,20 +168,20 @@ input.</p> <ul> <li> <p>An unfolded header field has no length restriction and therefore may be -indeterminately long.</p> + indeterminately long.</p> </li> <li> -<p>Any CRLF that appears in FWS is semantically "invisible".</p> +<p>Any CRLF that appears in FWS is semantically "invisible".</p> </li> <li> -<p>The "\" in any quoted-pair is semantically "invisible".</p> +<p>The "\" in any quoted-pair is semantically "invisible".</p> </li> <li> <p>Folding is permitted within the comment.</p> </li> <li> <p>The parentheses and backslash characters may appear in a comment, so long -as they appear as a quoted-pair.</p> + as they appear as a quoted-pair.</p> </li> <li> <p>Comment is not including the enclosing paretheses.</p> @@ -182,7 +190,7 @@ as they appear as a quoted-pair.</p> </div> </div> <div class="sect2"> -<h3 id="_atom">1.2. Atom</h3> +<h3 id="_atom">Atom</h3> <div class="literalblock"> <div class="content"> <pre>phrase = 1*word / obs-phrase @@ -198,7 +206,7 @@ dot-atom-text = 1*atext *("." 1*atext) atext = ALPHA / DIGIT / ; Printable US-ASCII "!" / "#" / ; characters not including "$" / "%" / ; specials. Used for atoms. - "&" / "'" / + "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / @@ -208,7 +216,7 @@ atext = ALPHA / DIGIT / ; Printable US-ASCII "~" specials = "(" / ")" / ; Special characters that do - "<" / ">" / ; not appear in atext + "<" / ">" / ; not appear in atext "[" / "]" / ":" / ";" / "@" / "\" / @@ -220,13 +228,13 @@ specials = "(" / ")" / ; Special characters that do <ul> <li> <p>The optional comments and FWS surrounding the rest of the characters are -not part of the atom.</p> + not part of the atom.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_quoted_strings">1.3. Quoted Strings</h3> +<h3 id="_quoted_strings">Quoted Strings</h3> <div class="literalblock"> <div class="content"> <pre>quoted-string = [CFWS] @@ -243,7 +251,7 @@ qtext = %d33 / ; Printable US-ASCII </div> </div> <div class="sect2"> -<h3 id="_date_and_time_specification">1.4. Date and Time Specification</h3> +<h3 id="_date_and_time_specification">Date and Time Specification</h3> <div class="paragraph"> <p>Syntax,</p> </div> @@ -284,13 +292,13 @@ zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone</pre> <p>The date and time-of-day SHOULD express local time.</p> </li> <li> -<p>The form "+0000" on zone SHOULD be used to indicate a time zone at -Universal Time.</p> +<p>The form "+0000" on zone SHOULD be used to indicate a time zone at + Universal Time.</p> </li> <li> -<p>The form "-0000" on zone indicate that the time was generated on a system -that may be in a local time zone other than Universal Time and that the -date-time contains no information about the local time zone.</p> +<p>The form "-0000" on zone indicate that the time was generated on a system + that may be in a local time zone other than Universal Time and that the + date-time contains no information about the local time zone.</p> </li> <li> <p>A date-time specification MUST be semantically valid.</p> @@ -300,11 +308,11 @@ date-time contains no information about the local time zone.</p> </li> <li> <p>The numeric day-of-month MUST be between 1 and the number of days allowed -for the specified month (in the specified year).</p> + for the specified month (in the specified year).</p> </li> <li> <p>The time-of-day MUST be in the range 00:00:00 through 23:59:60 (the number -of seconds allowing for a leap second.</p> + of seconds allowing for a leap second.</p> </li> <li> <p>The last two digits of the zone MUST be within the range 00 through 59.</p> @@ -313,7 +321,7 @@ of seconds allowing for a leap second.</p> </div> </div> <div class="sect2"> -<h3 id="_address_specification">1.5. Address Specification</h3> +<h3 id="_address_specification">Address Specification</h3> <div class="paragraph"> <p>An address may either be an individual mailbox, or a group of mailboxes.</p> </div> @@ -338,7 +346,7 @@ mailbox = name-addr / addr-spec name-addr = [display-name] angle-addr -angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / +angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr display-name = phrase @@ -365,8 +373,8 @@ dtext = %d33-90 / ; Printable US-ASCII <p>quoted-string form SHOULD NOT be used;</p> </li> <li> -<p>Comments and folding white space SHOULD NOT be used around the "@" in the -addr-spec.</p> +<p>Comments and folding white space SHOULD NOT be used around the "@" in the + addr-spec.</p> </li> </ul> </div> @@ -374,7 +382,7 @@ addr-spec.</p> </div> </div> <div class="sect1"> -<h2 id="_header">2. Header</h2> +<h2 id="_header">Header</h2> <div class="sectionbody"> <div class="paragraph"> <p>Format,</p> @@ -406,174 +414,53 @@ addr-spec.</p> optional-field)</pre> </div> </div> -<table class="tableblock frame-all grid-all stretch"> -<colgroup> -<col style="width: 20%;"> -<col style="width: 10%;"> -<col style="width: 10%;"> -<col style="width: 60%;"> -</colgroup> -<thead> -<tr> -<th class="tableblock halign-left valign-top">Field</th> -<th class="tableblock halign-left valign-middle">Min number</th> -<th class="tableblock halign-left valign-top">Max number</th> -<th class="tableblock halign-left valign-top">Notes</th> -</tr> -</thead> -<tbody> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">trace</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">Block prepended - see 3.6.7</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">resent-date</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">One per block, required if other resent fields are present - see 3.6.6</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">resent-from</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">One per block - see 3.6.6</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">resent-sender</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">One per block, MUST occur with multi-address resent-from - see 3.6.6</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">resent-to</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">One per block - see 3.6.6</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">resent-cc</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">One per block - see 3.6.6</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">resent-bcc</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">One per block - see 3.6.6</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">resent-msg-id</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">One per block - see 3.6.6</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">orig-date</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">from</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">See sender and 3.6.2</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">sender</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">MUST occur withmulti-address from - see 3.6.2</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">reply-to</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">to</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">cc</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">bcc</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">message-id</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">SHOULD be present - see 3.6.4</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">in-reply-to</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">SHOULD occur in some replies - see 3.6.4</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">references</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0*</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">SHOULD occur in some replies - see 3.6.4</p></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">subject</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">comments</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">keywords</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -<tr> -<td class="tableblock halign-left valign-top"><p class="tableblock">optional-field</p></td> -<td class="tableblock halign-left valign-middle"><p class="tableblock">0</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited</p></td> -<td class="tableblock halign-left valign-top"></td> -</tr> -</tbody> -</table> +<div class="paragraph"> +<p>|=== +| Field | Min number | Max number | Notes</p> +</div> +<div class="paragraph"> +<p>| trace | 0 | unlimited | Block prepended - see 3.6.7 +| resent-date | 0* | unlimited* | One per block, required if other resent fields are present - see 3.6.6 +| resent-from | 0 | unlimited* | One per block - see 3.6.6 +| resent-sender | 0* | unlimited* | One per block, MUST occur with multi-address resent-from - see 3.6.6 +| resent-to | 0 | unlimited* | One per block - see 3.6.6 +| resent-cc | 0 | unlimited* | One per block - see 3.6.6 +| resent-bcc | 0 | unlimited* | One per block - see 3.6.6 +| resent-msg-id | 0 | unlimited* | One per block - see 3.6.6 +| orig-date | 1 | 1 | +| from | 1 | 1 | See sender and 3.6.2 +| sender | 0* | 1 | MUST occur withmulti-address from - see 3.6.2 +| reply-to | 0 | 1 | +| to | 0 | 1 | +| cc | 0 | 1 | +| bcc | 0 | 1 | +| message-id | 0* | 1 | SHOULD be present - see 3.6.4 +| in-reply-to | 0* | 1 | SHOULD occur in some replies - see 3.6.4 +| references | 0* | 1 | SHOULD occur in some replies - see 3.6.4 +| subject | 0 | 1 | +| comments | 0 | unlimited | +| keywords | 0 | unlimited | +| optional-field | 0 | unlimited | +|===</p> +</div> <div class="ulist"> <ul> <li> <p>Header fields SHOULD NOT be reordered when a message is transported or -transformed.</p> + transformed.</p> </li> <li> <p>The trace header fields and resent header fields MUST NOT be -reordered, and SHOULD be kept in blocks prepended to the message.</p> + reordered, and SHOULD be kept in blocks prepended to the message.</p> </li> <li> -<p>The only required header fields are the "Date" field and the originator -address field(s) (which is "From", "Sender", and "Reply-To").</p> +<p>The only required header fields are the "Date" field and the originator + address field(s) (which is "From", "Sender", and "Reply-To").</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_date_field">2.1. Date Field</h3> +<h3 id="_date_field">Date Field</h3> <div class="paragraph"> <p>The date and time at which the creator of the message indicated that the message was completed, not the time the message transferred.</p> @@ -585,7 +472,7 @@ message was completed, not the time the message transferred.</p> </div> </div> <div class="sect2"> -<h3 id="_originator_fields">2.2. Originator Fields</h3> +<h3 id="_originator_fields">Originator Fields</h3> <div class="literalblock"> <div class="content"> <pre>from = "From:" mailbox-list CRLF @@ -598,33 +485,33 @@ reply-to = "Reply-To:" address-list CRLF</pre> <div class="ulist"> <ul> <li> -<p>If the "From:" field contains more than one mailbox, then the sender field -MUST appear in the message.</p> +<p>If the "From:" field contains more than one mailbox, then the sender field + MUST appear in the message.</p> </li> <li> <p>If the originator of the message can be indicated by a single mailbox and -the author and transmitter are identical, the "Sender:" field SHOULD NOT be -used. -Otherwise, both fields SHOULD appear.</p> + the author and transmitter are identical, the "Sender:" field SHOULD NOT be + used. + Otherwise, both fields SHOULD appear.</p> </li> <li> -<p>When the "Reply-To:" field is present, it indicates the address(es) to -which the author of the message suggests that replies be sent.</p> +<p>When the "Reply-To:" field is present, it indicates the address(es) to + which the author of the message suggests that replies be sent.</p> </li> <li> -<p>In the absence of the "Reply-To:" field, replies SHOULD by default be sent -to the mailbox(es) specified in the "From:" field unless otherwise -specified by the person composing the reply.</p> +<p>In the absence of the "Reply-To:" field, replies SHOULD by default be sent + to the mailbox(es) specified in the "From:" field unless otherwise + specified by the person composing the reply.</p> </li> <li> -<p>In all cases, the "From:" field SHOULD NOT contain any mailbox that does -not belong to the author(s) of the message.</p> +<p>In all cases, the "From:" field SHOULD NOT contain any mailbox that does + not belong to the author(s) of the message.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_destination_fields">2.3. Destination Fields</h3> +<h3 id="_destination_fields">Destination Fields</h3> <div class="literalblock"> <div class="content"> <pre>to = "To:" address-list CRLF @@ -635,53 +522,53 @@ bcc = "Bcc:" [address-list / CFWS] CRLF</pre> </div> </div> <div class="paragraph"> -<p>The "To:" field contains the address(es) of the primary recipient(s) of the +<p>The "To:" field contains the address(es) of the primary recipient(s) of the message.</p> </div> <div class="paragraph"> -<p>The "Cc:" field (where the "Cc" means "Carbon Copy" in the sense of making a +<p>The "Cc:" field (where the "Cc" means "Carbon Copy" in the sense of making a copy on a typewriter using carbon paper) contains the addresses of others who are to receive the message, though the content of the message may not be directed at them.</p> </div> <div class="paragraph"> -<p>The "Bcc:" field (where the "Bcc" means "Blind Carbon Copy") contains +<p>The "Bcc:" field (where the "Bcc" means "Blind Carbon Copy") contains addresses of recipients of the message whose addresses are not to be revealed to other recipients of the message.</p> </div> <div class="paragraph"> -<p>There are three ways in which the "Bcc:" field is used,</p> +<p>There are three ways in which the "Bcc:" field is used,</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> -<p>The "Bcc:" line is removed even though all of the recipients (including -those specified in the "Bcc:" field) are sent a copy of the message.</p> +<p>The "Bcc:" line is removed even though all of the recipients (including + those specified in the "Bcc:" field) are sent a copy of the message.</p> </li> <li> -<p>Recipients specified in the "To:" and "Cc:" lines each are sent -a copy of the message with the "Bcc:" line removed as above, but the -recipients on the "Bcc:" line get a separate copy of the message -containing a "Bcc:" line. (When there are multiple recipient -addresses in the "Bcc:" field, some implementations actually send a -separate copy of the message to each recipient with a "Bcc:" -containing only the address of that particular recipient.)</p> +<p>Recipients specified in the "To:" and "Cc:" lines each are sent + a copy of the message with the "Bcc:" line removed as above, but the + recipients on the "Bcc:" line get a separate copy of the message + containing a "Bcc:" line. (When there are multiple recipient + addresses in the "Bcc:" field, some implementations actually send a + separate copy of the message to each recipient with a "Bcc:" + containing only the address of that particular recipient.)</p> </li> <li> -<p>Since a "Bcc:" field may contain no addresses, a "Bcc:" field can be -sent without any addresses indicating to the recipients that blind -copies were sent to someone.</p> +<p>Since a "Bcc:" field may contain no addresses, a "Bcc:" field can be + sent without any addresses indicating to the recipients that blind + copies were sent to someone.</p> </li> </ol> </div> <div class="paragraph"> -<p>Which method to use with "Bcc:" fields is implementation dependent, but refer -to the "Security Considerations" section of this document for a discussion of +<p>Which method to use with "Bcc:" fields is implementation dependent, but refer +to the "Security Considerations" section of this document for a discussion of each.</p> </div> </div> <div class="sect2"> -<h3 id="_identification_field">2.4. Identification Field</h3> +<h3 id="_identification_field">Identification Field</h3> <div class="paragraph"> <p>Format,</p> </div> @@ -693,7 +580,7 @@ in-reply-to = "In-Reply-To:" 1*msg-id CRLF references = "References:" 1*msg-id CRLF -msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS] +msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS] id-left = dot-atom-text / obs-id-left @@ -705,10 +592,10 @@ no-fold-literal = "[" *dtext "]"</pre> <div class="ulist"> <ul> <li> -<p>Every message SHOULD have a "Message-ID:" field.</p> +<p>Every message SHOULD have a "Message-ID:" field.</p> </li> <li> -<p>Reply messages SHOULD have "In-Reply-To:" and "References:" fields.</p> +<p>Reply messages SHOULD have "In-Reply-To:" and "References:" fields.</p> </li> </ul> </div> @@ -721,14 +608,14 @@ humans.</p> RECOMMENDED.</p> </div> <div class="paragraph"> -<p>The "In-Reply-To:" and "References:" fields are used when creating a +<p>The "In-Reply-To:" and "References:" fields are used when creating a reply to a message. -"In-Reply-To:" field may be used to identify the message (or messages) to -which the new message is a reply (one or more parent), while the "References:" -field may be used to identify a "thread" of conversation.</p> +"In-Reply-To:" field may be used to identify the message (or messages) to +which the new message is a reply (one or more parent), while the "References:" +field may be used to identify a "thread" of conversation.</p> </div> <div class="paragraph"> -<p>Trying to form a "References:" field for a reply that has multiple parents is +<p>Trying to form a "References:" field for a reply that has multiple parents is discouraged.</p> </div> <div class="paragraph"> @@ -741,7 +628,7 @@ msg-id is what is contained between the two angle bracket characters.</p> </div> </div> <div class="sect2"> -<h3 id="_informational_fields">2.5. Informational Fields</h3> +<h3 id="_informational_fields">Informational Fields</h3> <div class="literalblock"> <div class="content"> <pre>subject = "Subject:" unstructured CRLF @@ -752,16 +639,16 @@ keywords = "Keywords:" phrase *("," phrase) CRLF</pre> </div> </div> <div class="paragraph"> -<p>When used in a reply, the "Subject" body MAY start with the string "Re: " (an -abbreviation of the Latin "in re", meaning "in the matter of") -followed by the contents of the "Subject:" field body of the original message. -If this is done, only one instance of the literal string "Re: " ought to be +<p>When used in a reply, the "Subject" body MAY start with the string "Re: " (an +abbreviation of the Latin "in re", meaning "in the matter of") +followed by the contents of the "Subject:" field body of the original message. +If this is done, only one instance of the literal string "Re: " ought to be used since use of other strings or more than one instance can lead to undesirable consequences.</p> </div> </div> <div class="sect2"> -<h3 id="_resent_fields">2.6. Resent Fields</h3> +<h3 id="_resent_fields">Resent Fields</h3> <div class="paragraph"> <p>Each of the resent fields corresponds to a particular field elsewhere in the syntax.</p> @@ -787,49 +674,49 @@ resent-msg-id = "Resent-Message-ID:" msg-id CRLF</pre> <ul> <li> <p>Resent fields SHOULD be added to any message that is reintroduced by -a user into the transport system.</p> + a user into the transport system.</p> </li> <li> <p>A separate set of resent fields SHOULD be added each time this is done.</p> </li> <li> <p>All of the resent fields corresponding to a particular resending of the -message SHOULD be grouped together.</p> + message SHOULD be grouped together.</p> </li> <li> <p>Each new set of resent fields is prepended to the message; that is, the -most recent set of resent fields appears earlier in the message.</p> + most recent set of resent fields appears earlier in the message.</p> </li> <li> <p>No other fields in the message are changed when resent fields are added.</p> </li> <li> -<p>When resent fields are used, the "Resent-From:" and "Resent-Date:" -fields MUST be sent.</p> +<p>When resent fields are used, the "Resent-From:" and "Resent-Date:" + fields MUST be sent.</p> </li> <li> -<p>The "Resent-Message-ID:" field SHOULD be sent.</p> +<p>The "Resent-Message-ID:" field SHOULD be sent.</p> </li> <li> -<p>"Resent-Sender:" SHOULD NOT be used if "Resent-Sender:" would be identical -to "Resent-From:".</p> +<p>"Resent-Sender:" SHOULD NOT be used if "Resent-Sender:" would be identical + to "Resent-From:".</p> </li> <li> -<p>The "Resent-Message-ID:" field provides a unique identifier for the resent -message.</p> +<p>The "Resent-Message-ID:" field provides a unique identifier for the resent + message.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_trace_fields">2.7. Trace Fields</h3> +<h3 id="_trace_fields">Trace Fields</h3> <div class="literalblock"> <div class="content"> <pre>trace = [return] 1*received return = "Return-Path:" path CRLF -path = angle-addr / ([CFWS] "<" [CFWS] ">" [CFWS]) +path = angle-addr / ([CFWS] "<" [CFWS] ">" [CFWS]) received = "Received:" *received-token ";" date-time CRLF @@ -838,7 +725,7 @@ received-token = word / angle-addr / addr-spec / domain</pre> </div> </div> <div class="sect2"> -<h3 id="_optional_fields">2.8. Optional Fields</h3> +<h3 id="_optional_fields">Optional Fields</h3> <div class="paragraph"> <p>The field names of any optional field MUST NOT be identical to any field name specified elsewhere in this document.</p> @@ -852,10 +739,10 @@ specified elsewhere in this document.</p> </div> </div> <div class="sect1"> -<h2 id="_obsolete_specification">3. Obsolete Specification</h2> +<h2 id="_obsolete_specification">Obsolete Specification</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_obsolete_date_and_time">3.1. Obsolete Date and Time</h3> +<h3 id="_obsolete_date_and_time">Obsolete Date and Time</h3> <div class="paragraph"> <p>The syntax for the obsolete date format allows</p> </div> @@ -877,12 +764,12 @@ interpreted as follows:</p> <ol class="arabic"> <li> <p>If a two digit year is encountered whose value is between 00 and 49, the -year is interpreted by adding 2000, ending up with a value between 2000 and -2049.</p> + year is interpreted by adding 2000, ending up with a value between 2000 and + 2049.</p> </li> <li> <p>If a two digit year is encountered with a value between 50 and 99, or any -three digit year is encountered, the year is interpreted by adding 1900.</p> + three digit year is encountered, the year is interpreted by adding 1900.</p> </li> </ol> </div> @@ -903,12 +790,12 @@ PST is semantically equivalent to -0800</pre> </div> <div class="paragraph"> <p>However, because of the error in [RFC0822], any time zones SHOULD all be -considered equivalent to "-0000" unless there is out-of-band information +considered equivalent to "-0000" unless there is out-of-band information confirming their meaning.</p> </div> </div> <div class="sect2"> -<h3 id="_obsolete_addressing">3.2. Obsolete Addressing</h3> +<h3 id="_obsolete_addressing">Obsolete Addressing</h3> <div class="paragraph"> <p>There are four primary differences in addressing.</p> </div> @@ -916,30 +803,30 @@ confirming their meaning.</p> <ol class="arabic"> <li> <p>mailbox addresses were allowed to have a route portion before the -addr-spec when enclosed in "<" and ">". -The route is simply a comma-separated list of domain names, each preceded -by "@", and the list terminated by a colon.</p> + addr-spec when enclosed in "<" and ">". + The route is simply a comma-separated list of domain names, each preceded + by "@", and the list terminated by a colon.</p> </li> <li> <p>CFWS were allowed between the period-separated elements of local-part and -domain (i.e., dot-atom was not used). -In addition, local-part is allowed to contain quoted-string in addition to -just atom.</p> + domain (i.e., dot-atom was not used). + In addition, local-part is allowed to contain quoted-string in addition to + just atom.</p> </li> <li> -<p>mailbox-list and address-list were allowed to have "null" members. -That is, there could be two or more commas in such a list with nothing in -between them, or commas at the beginning or end of the list.</p> +<p>mailbox-list and address-list were allowed to have "null" members. + That is, there could be two or more commas in such a list with nothing in + between them, or commas at the beginning or end of the list.</p> </li> <li> <p>US-ASCII control characters and quoted-pairs were allowed in domain -literals and are added here.</p> + literals and are added here.</p> </li> </ol> </div> </div> <div class="sect2"> -<h3 id="_obsolete_header_fields">3.3. Obsolete Header Fields</h3> +<h3 id="_obsolete_header_fields">Obsolete Header Fields</h3> <div class="ulist"> <ul> <li> @@ -949,19 +836,24 @@ literals and are added here.</p> <p>Fields may occur in any order.</p> </li> <li> -<p>Any amount of white space is allowed before the ":" at the end of the -field name.</p> +<p>Any amount of white space is allowed before the ":" at the end of the + field name.</p> </li> </ul> </div> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/MIME_II_MEDIA_TYPES.html b/doc/MIME_II_MEDIA_TYPES.html index 29d25f74..ac3db8da 100644 --- a/doc/MIME_II_MEDIA_TYPES.html +++ b/doc/MIME_II_MEDIA_TYPES.html @@ -1,107 +1,115 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>MIME Part Two: Media Types</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>MIME Part Two: Media Types</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>MIME Part Two: Media Types</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>MIME Part Two: Media Types</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a></li> -<li><a href="#_text_media_type">2. Text Media Type</a> +<li><a href="#_introduction">Introduction</a></li> +<li><a href="#_text_media_type">Text Media Type</a> <ul class="sectlevel2"> -<li><a href="#_plain_subtype">2.1. Plain Subtype</a></li> +<li><a href="#_plain_subtype">Plain Subtype</a></li> </ul> </li> -<li><a href="#_image_media_type">3. Image Media Type</a></li> -<li><a href="#_audio_media_type">4. Audio Media Type</a></li> -<li><a href="#_video_media_type">5. Video Media Type</a></li> -<li><a href="#_application_media_type">6. Application Media Type</a> +<li><a href="#_image_media_type">Image Media Type</a></li> +<li><a href="#_audio_media_type">Audio Media Type</a></li> +<li><a href="#_video_media_type">Video Media Type</a></li> +<li><a href="#_application_media_type">Application Media Type</a> <ul class="sectlevel2"> -<li><a href="#_octet_stream_subtype">6.1. Octet-Stream Subtype</a></li> -<li><a href="#_postscript_subtype">6.2. Postscript Subtype</a></li> +<li><a href="#_octet_stream_subtype">Octet-Stream Subtype</a></li> +<li><a href="#_postscript_subtype">Postscript Subtype</a></li> </ul> </li> -<li><a href="#_multipart_media_type">7. Multipart Media Type</a> +<li><a href="#_multipart_media_type">Multipart Media Type</a> <ul class="sectlevel2"> -<li><a href="#_common_syntax">7.1. Common Syntax</a></li> -<li><a href="#_mixed_subtype">7.2. Mixed Subtype</a></li> -<li><a href="#_alternative_subtype">7.3. Alternative Subtype</a></li> -<li><a href="#_digest_subtype">7.4. Digest Subtype</a></li> -<li><a href="#_parallel_subtype">7.5. Parallel Subtype</a></li> +<li><a href="#_common_syntax">Common Syntax</a></li> +<li><a href="#_mixed_subtype">Mixed Subtype</a></li> +<li><a href="#_alternative_subtype">Alternative Subtype</a></li> +<li><a href="#_digest_subtype">Digest Subtype</a></li> +<li><a href="#_parallel_subtype">Parallel Subtype</a></li> </ul> </li> -<li><a href="#_message_media_type">8. Message Media Type</a> +<li><a href="#_message_media_type">Message Media Type</a> <ul class="sectlevel2"> -<li><a href="#_rfc822_subtype">8.1. RFC822 Subtype</a></li> -<li><a href="#_partial_subtype">8.2. Partial Subtype</a></li> -<li><a href="#_external_body_subtype">8.3. External-Body Subtype</a></li> +<li><a href="#_rfc822_subtype">RFC822 Subtype</a></li> +<li><a href="#_partial_subtype">Partial Subtype</a></li> +<li><a href="#_external_body_subtype">External-Body Subtype</a></li> </ul> </li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> -<p>This document provide note and summary of <a href="https://tools.ietf.org/html/rfc2046" target="_blank" rel="noopener">RFC 2046</a>, +<p>This document provide note and summary of <a href="https://tools.ietf.org/html/rfc2046">RFC 2046^</a>, Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types.</p> </div> </div> </div> <div class="sect1"> -<h2 id="_introduction">1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> <p>There are two groups media type: discrete and composite. -Discrete media type are "text", "image", "audio", "video", and "application". -Composite media type are "multipart" and "message".</p> +Discrete media type are "text", "image", "audio", "video", and "application". +Composite media type are "multipart" and "message".</p> </div> </div> </div> <div class="sect1"> -<h2 id="_text_media_type">2. Text Media Type</h2> +<h2 id="_text_media_type">Text Media Type</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> -<p>Canonical form of any MIME "text" subtype MUST always represent a -line break as a CRLF sequence. -Use of CR and LF outside of line break sequences is forbidden.</p> +<p>Canonical form of any MIME "text" subtype MUST always represent a + line break as a CRLF sequence. + Use of CR and LF outside of line break sequences is forbidden.</p> </li> <li> -<p>Unrecognized subtypes of "text" should be treated as subtype "plain" -as long as the MIME implementation knows how to handle the charset.</p> +<p>Unrecognized subtypes of "text" should be treated as subtype "plain" + as long as the MIME implementation knows how to handle the charset.</p> </li> <li> <p>Unrecognized subtypes which also specify an unrecognized charset -should be treated as "application/octet-stream".</p> + should be treated as "application/octet-stream".</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_plain_subtype">2.1. Plain Subtype</h3> +<h3 id="_plain_subtype">Plain Subtype</h3> <div class="ulist"> <ul> <li> -<p>Subtype "plain" is seen simply as a linear sequence of characters, possibly -interrupted by line breaks or page breaks.</p> +<p>Subtype "plain" is seen simply as a linear sequence of characters, possibly + interrupted by line breaks or page breaks.</p> </li> <li> -<p>A "charset" parameter may be used to indicate the character set of the body</p> +<p>A "charset" parameter may be used to indicate the character set of the body</p> <div class="ulist"> <ul> <li> @@ -112,7 +120,7 @@ interrupted by line breaks or page breaks.</p> </li> <li> <p>It is strongly recommended that new user agents explicitly specify a -character set as a media type parameter in the Content-Type header field.</p> + character set as a media type parameter in the Content-Type header field.</p> </li> </ul> </div> @@ -123,108 +131,108 @@ character set as a media type parameter in the Content-Type header field.</p> </div> </div> <div class="sect1"> -<h2 id="_image_media_type">3. Image Media Type</h2> +<h2 id="_image_media_type">Image Media Type</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> -<p>A media type of "image" indicates that the body contains an image.</p> +<p>A media type of "image" indicates that the body contains an image.</p> </li> <li> <p>The subtype names the specific image format, defined in RFC 2048.</p> </li> <li> -<p>Unrecognized subtypes of "image" should at a minimum be treated as -"application/octet-stream".</p> +<p>Unrecognized subtypes of "image" should at a minimum be treated as + "application/octet-stream".</p> </li> </ul> </div> </div> </div> <div class="sect1"> -<h2 id="_audio_media_type">4. Audio Media Type</h2> +<h2 id="_audio_media_type">Audio Media Type</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> -<p>A media type of "audio" indicates that the body contains audio data.</p> +<p>A media type of "audio" indicates that the body contains audio data.</p> </li> <li> -<p>Unrecognized subtypes of "audio" should at a miniumum be treated as -"application/octet-stream".</p> +<p>Unrecognized subtypes of "audio" should at a miniumum be treated as + "application/octet-stream".</p> </li> </ul> </div> </div> </div> <div class="sect1"> -<h2 id="_video_media_type">5. Video Media Type</h2> +<h2 id="_video_media_type">Video Media Type</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> -<p>A media type of "video" indicates that the body contains a -time-varying-picture image, possibly with color and coordinated sound.</p> +<p>A media type of "video" indicates that the body contains a + time-varying-picture image, possibly with color and coordinated sound.</p> </li> <li> -<p>The subtype "mpeg" refers to video coded according to the MPEG standard -[MPEG].</p> +<p>The subtype "mpeg" refers to video coded according to the MPEG standard + [MPEG].</p> </li> <li> -<p>Unrecognized subtypes of "video" should at a minumum be treated as -"application/octet-stream".</p> +<p>Unrecognized subtypes of "video" should at a minumum be treated as + "application/octet-stream".</p> </li> </ul> </div> </div> </div> <div class="sect1"> -<h2 id="_application_media_type">6. Application Media Type</h2> +<h2 id="_application_media_type">Application Media Type</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> -<p>The "application" media type is to be used for discrete data which do -not fit in any of the other categories, and particularly for data to -be processed by some type of application program.</p> +<p>The "application" media type is to be used for discrete data which do + not fit in any of the other categories, and particularly for data to + be processed by some type of application program.</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_octet_stream_subtype">6.1. Octet-Stream Subtype</h3> +<h3 id="_octet_stream_subtype">Octet-Stream Subtype</h3> <div class="paragraph"> -<p>The "octet-stream" subtype is used to indicate that a body contains arbitrary +<p>The "octet-stream" subtype is used to indicate that a body contains arbitrary binary data. This subtype define the following optional parameters:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> -<p>TYPE — the general type or category of binary data. -This is intended as information for the human recipient rather than for -any automatic processing.</p> +<p>TYPE -- the general type or category of binary data. + This is intended as information for the human recipient rather than for + any automatic processing.</p> </li> <li> -<p>PADDING — the number of bits of padding that were appended to the -bit-stream comprising the actual contents to produce the enclosed 8bit -byte-oriented data. -This is useful for enclosing a bit-stream in a body when the total number -of bits is not a multiple of 8.</p> +<p>PADDING -- the number of bits of padding that were appended to the + bit-stream comprising the actual contents to produce the enclosed 8bit + byte-oriented data. + This is useful for enclosing a bit-stream in a body when the total number + of bits is not a multiple of 8.</p> </li> </ol> </div> </div> <div class="sect2"> -<h3 id="_postscript_subtype">6.2. Postscript Subtype</h3> +<h3 id="_postscript_subtype">Postscript Subtype</h3> <div class="paragraph"> -<p>A media type of "application/postscript" indicates a PostScript program.</p> +<p>A media type of "application/postscript" indicates a PostScript program.</p> </div> <div class="ulist"> <ul> <li> <p>The execution of general-purpose PostScript interpreters entails -serious security risks, and implementors are discouraged from simply -sending PostScript bodies to "off-the-shelf" interpreters.</p> + serious security risks, and implementors are discouraged from simply + sending PostScript bodies to "off-the-shelf" interpreters.</p> </li> </ul> </div> @@ -232,7 +240,7 @@ sending PostScript bodies to "off-the-shelf" interpreters.</p> </div> </div> <div class="sect1"> -<h2 id="_multipart_media_type">7. Multipart Media Type</h2> +<h2 id="_multipart_media_type">Multipart Media Type</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -270,54 +278,54 @@ body-part := MIME-part-headers [CRLF *OCTET] ; body-part differ from the semantics of a message, as ; described in the text. -OCTET := <any 0-255 octet value></pre> +OCTET := <any 0-255 octet value></pre> </div> </div> <div class="ulist"> <ul> <li> -<p>A "multipart" media type field MUST appear in the entity’s header.</p> +<p>A "multipart" media type field MUST appear in the entity's header.</p> </li> <li> <p>The body MUST then contain one or more body parts, each preceded by a -boundary delimiter line, and the last one followed by a closing boundary -delimiter line.</p> + boundary delimiter line, and the last one followed by a closing boundary + delimiter line.</p> <div class="ulist"> <ul> <li> <p>After its boundary delimiter line, each body part then consists of a -header area, a blank line, and a body area.</p> + header area, a blank line, and a body area.</p> </li> <li> <p>The boundary delimiter MUST NOT appear inside any of the encapsulated -parts, on a line by itself or as the prefix of any line.</p> + parts, on a line by itself or as the prefix of any line.</p> </li> </ul> </div> </li> <li> <p>A body part is an entity and hence is NOT to be interpreted as actually -being an RFC 822 message.</p> + being an RFC 822 message.</p> </li> <li> <p>NO header fields are actually required in body parts.</p> </li> <li> <p>The only header fields that have defined meaning for body parts are -those the names of which begin with "Content-". -All other header fields may be ignored in body parts.</p> + those the names of which begin with "Content-". + All other header fields may be ignored in body parts.</p> </li> <li> -<p>All present and future subtypes of the "multipart" type MUST use an -identical syntax.</p> +<p>All present and future subtypes of the "multipart" type MUST use an + identical syntax.</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_common_syntax">7.1. Common Syntax</h3> +<h3 id="_common_syntax">Common Syntax</h3> <div class="literalblock"> <div class="content"> -<pre>boundary := 0*69<bchars> bcharsnospace +<pre>boundary := 0*69<bchars> bcharsnospace bchars := bcharsnospace / " " @@ -330,28 +338,28 @@ bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / <ul> <li> <p>The Content-Type field for multipart entities requires one parameter, -"boundary".</p> + "boundary".</p> </li> <li> <p>The boundary delimiter line is then defined as a line consisting entirely -of two hyphen characters ("-", decimal value 45) followed by the boundary -parameter value, optional linear whitespace, and a terminating CRLF.</p> + of two hyphen characters ("-", decimal value 45) followed by the boundary + parameter value, optional linear whitespace, and a terminating CRLF.</p> </li> <li> <p>The boundary delimiter MUST occur at the beginning of a line</p> </li> <li> <p>The boundary may be followed by zero or more characters of linear -whitespace</p> + whitespace</p> </li> <li> <p>The CRLF preceding the boundary delimiter line is conceptually -attached to the boundary so that it is possible to have a part that -does not end with a CRLF</p> + attached to the boundary so that it is possible to have a part that + does not end with a CRLF</p> </li> <li> <p>Boundary MUST be no longer than 70 characters, not counting the two -leading hyphens.</p> + leading hyphens.</p> </li> <li> <p>Boundary with two hyphen at the end indicated the end of message body.</p> @@ -360,24 +368,24 @@ leading hyphens.</p> </div> </div> <div class="sect2"> -<h3 id="_mixed_subtype">7.2. Mixed Subtype</h3> +<h3 id="_mixed_subtype">Mixed Subtype</h3> <div class="ulist"> <ul> <li> -<p>The "mixed" subtype of "multipart" is intended for use when the body -parts are independent and need to be bundled in a particular order.</p> +<p>The "mixed" subtype of "multipart" is intended for use when the body + parts are independent and need to be bundled in a particular order.</p> </li> <li> -<p>Any "multipart" subtypes that an implementation does not recognize -MUST be treated as being of subtype "mixed".</p> +<p>Any "multipart" subtypes that an implementation does not recognize + MUST be treated as being of subtype "mixed".</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_alternative_subtype">7.3. Alternative Subtype</h3> +<h3 id="_alternative_subtype">Alternative Subtype</h3> <div class="paragraph"> -<p>In "multipart/alternative", each of the body parts is an "alternative" version +<p>In "multipart/alternative", each of the body parts is an "alternative" version of the same information.</p> </div> <div class="ulist"> @@ -387,36 +395,36 @@ of the same information.</p> </li> <li> <p>The best choice is the LAST part of a type supported by the recipient -system’s local environment.</p> + system's local environment.</p> </li> <li> -<p>User agents that compose "multipart/alternative" entities MUST place the -body parts in increasing order of preference, that is, with the preferred -format last.</p> +<p>User agents that compose "multipart/alternative" entities MUST place the + body parts in increasing order of preference, that is, with the preferred + format last.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_digest_subtype">7.4. Digest Subtype</h3> +<h3 id="_digest_subtype">Digest Subtype</h3> <div class="paragraph"> -<p>The "multipart/digest" Content-Type is intended to be used to send collections of messages.</p> +<p>The "multipart/digest" Content-Type is intended to be used to send collections of messages.</p> </div> <div class="ulist"> <ul> <li> <p>In a digest, the default Content-Type value for a body part is changed from -"text/plain" to "message/rfc822".</p> + "text/plain" to "message/rfc822".</p> </li> <li> -<p>If a "text/plain" part is needed, it should be included as a seperate -part of a "multipart/mixed" message.</p> +<p>If a "text/plain" part is needed, it should be included as a seperate + part of a "multipart/mixed" message.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_parallel_subtype">7.5. Parallel Subtype</h3> +<h3 id="_parallel_subtype">Parallel Subtype</h3> <div class="paragraph"> <p>in a parallel entity, the order of body parts is not significant.</p> </div> @@ -424,31 +432,31 @@ part of a "multipart/mixed" message.</p> </div> </div> <div class="sect1"> -<h2 id="_message_media_type">8. Message Media Type</h2> +<h2 id="_message_media_type">Message Media Type</h2> <div class="sectionbody"> <div class="paragraph"> <p>It is frequently desirable, in sending mail, to encapsulate another mail message. -A special media type, "message", is defined to encapsulate another mail +A special media type, "message", is defined to encapsulate another mail message. -The "rfc822" subtype of "message" is used to encapsulate RFC 822 messages.</p> +The "rfc822" subtype of "message" is used to encapsulate RFC 822 messages.</p> </div> <div class="sect2"> -<h3 id="_rfc822_subtype">8.1. RFC822 Subtype</h3> +<h3 id="_rfc822_subtype">RFC822 Subtype</h3> <div class="ulist"> <ul> <li> -<p>"message/rfc822" body must include a "From", "Date", and at least one -destination header is removed and replaced with the requirement that -at least one of "From", "Subject", or "Date" must be present.</p> +<p>"message/rfc822" body must include a "From", "Date", and at least one + destination header is removed and replaced with the requirement that + at least one of "From", "Subject", or "Date" must be present.</p> </li> <li> -<p>"message/rfc822" entity isn’t restricted to material in strict -conformance to RFC822, it could well be a News article or a MIME message.</p> +<p>"message/rfc822" entity isn't restricted to material in strict + conformance to RFC822, it could well be a News article or a MIME message.</p> </li> <li> -<p>No encoding other than "7bit", "8bit", or "binary" is permitted for the -body of a "message/rfc822" entity.</p> +<p>No encoding other than "7bit", "8bit", or "binary" is permitted for the + body of a "message/rfc822" entity.</p> </li> <li> <p>The message header fields are always US-ASCII in any cases.</p> @@ -457,31 +465,31 @@ body of a "message/rfc822" entity.</p> </div> </div> <div class="sect2"> -<h3 id="_partial_subtype">8.2. Partial Subtype</h3> +<h3 id="_partial_subtype">Partial Subtype</h3> <div class="paragraph"> -<p>The "partial" subtype is defined to allow large entities to be delivered as +<p>The "partial" subtype is defined to allow large entities to be delivered as several separate pieces of mail and automatically reassembled by a receiving user agent.</p> </div> <div class="ulist"> <ul> <li> -<p>Entities of type "message/partial" must always have a -content-transfer-encoding of 7bit (the default).</p> +<p>Entities of type "message/partial" must always have a + content-transfer-encoding of 7bit (the default).</p> </li> <li> -<p>The use of a content-transfer-encoding of "8bit" or "binary" is explicitly -prohibited.</p> +<p>The use of a content-transfer-encoding of "8bit" or "binary" is explicitly + prohibited.</p> </li> <li> -<p>When generating and reassembling the pieces of a "message/partial" -message, the headers of the encapsulated message must be merged with -the headers of the enclosing entities</p> +<p>When generating and reassembling the pieces of a "message/partial" + message, the headers of the encapsulated message must be merged with + the headers of the enclosing entities</p> <div class="ulist"> <ul> <li> <p>The result is always a complete MIME entity, which may have its own -Content-Type header field, and thus may contain any other data type.</p> + Content-Type header field, and thus may contain any other data type.</p> </li> </ul> </div> @@ -494,13 +502,13 @@ Content-Type header field, and thus may contain any other data type.</p> <div class="olist arabic"> <ol class="arabic"> <li> -<p><strong>"id"</strong>, is a unique identifier, as close to a world-unique identifier as -possible, to be used to match the fragments together. -In general, the identifier is essentially a message-id.</p> +<p><strong>"id"</strong>, is a unique identifier, as close to a world-unique identifier as + possible, to be used to match the fragments together. + In general, the identifier is essentially a message-id.</p> </li> <li> -<p><strong>"number"</strong>, an integer, is the fragment number, which indicates where this -fragment fits into the sequence of fragments.</p> +<p><strong>"number"</strong>, an integer, is the fragment number, which indicates where this + fragment fits into the sequence of fragments.</p> <div class="ulist"> <ul> <li> @@ -510,7 +518,7 @@ fragment fits into the sequence of fragments.</p> </div> </li> <li> -<p><strong>"total"</strong>, another integer, is the total number of fragments.</p> +<p><strong>"total"</strong>, another integer, is the total number of fragments.</p> </li> </ol> </div> @@ -525,19 +533,19 @@ observed:</p> </li> <li> <p>All of the header fields from the initial enclosing message, except those -that start with "Content-" and the specific header fields "Subject", -"Message-ID", "Encrypted", and "MIME-Version", must be copied, in order, -to the new message.</p> + that start with "Content-" and the specific header fields "Subject", + "Message-ID", "Encrypted", and "MIME-Version", must be copied, in order, + to the new message.</p> </li> <li> <p>All of the header fields from the second and any subsequent enclosing -messages are discarded by the reassembly process.</p> + messages are discarded by the reassembly process.</p> </li> </ol> </div> </div> <div class="sect2"> -<h3 id="_external_body_subtype">8.3. External-Body Subtype</h3> +<h3 id="_external_body_subtype">External-Body Subtype</h3> <div class="paragraph"> <p>The external-body subtype indicates that the actual body data are not included, but merely referenced. @@ -547,62 +555,62 @@ data.</p> <div class="ulist"> <ul> <li> -<p>"message/external-body" consists of a header, two consecutive CRLFs, and -the message header for the encapsulated message.</p> +<p>"message/external-body" consists of a header, two consecutive CRLFs, and + the message header for the encapsulated message.</p> </li> <li> <p>If another pair of consecutive CRLFs appears, this of course ends the -message header for the encapsulated message.</p> + message header for the encapsulated message.</p> </li> <li> -<p>Any text after encapsulated message header, also called "phantom body", is -ignored.</p> +<p>Any text after encapsulated message header, also called "phantom body", is + ignored.</p> <div class="ulist"> <ul> <li> <p>The only access-type defined in this document that uses the phantom body -is "mail-server"</p> + is "mail-server"</p> </li> </ul> </div> </li> <li> -<p>The encapsulated headers in ALL "message/external-body" entities MUST -include a Content-ID header field to give a unique identifier by -which to reference the data.</p> +<p>The encapsulated headers in ALL "message/external-body" entities MUST + include a Content-ID header field to give a unique identifier by + which to reference the data.</p> <div class="ulist"> <ul> <li> <p>This identifier may be used for caching mechanisms, and for recognizing -the receipt of the data when the access-type is "mail-server".</p> + the receipt of the data when the access-type is "mail-server".</p> </li> </ul> </div> </li> <li> <p>The tokens that describe external-body data, such as file names and mail -server commands, are required to be in the US-ASCII character set.</p> + server commands, are required to be in the US-ASCII character set.</p> </li> <li> -<p>MIME entities of type "message/external-body" MUST have a -content-transfer-encoding of 7bit (the default).</p> +<p>MIME entities of type "message/external-body" MUST have a + content-transfer-encoding of 7bit (the default).</p> </li> </ul> </div> <div class="paragraph"> -<p>The parameters that may be used with any "message/external-body" are:</p> +<p>The parameters that may be used with any "message/external-body" are:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> -<p>ACCESS-TYPE — A word indicating the supported access mechanism by which -the file or data may be obtained. -This word is not case sensitive.</p> +<p>ACCESS-TYPE -- A word indicating the supported access mechanism by which + the file or data may be obtained. + This word is not case sensitive.</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> -<p>Values include, but are not limited to, "FTP", "ANON-FTP", "TFTP", -"LOCAL-FILE", and "MAIL-SERVER".</p> +<p>Values include, but are not limited to, "FTP", "ANON-FTP", "TFTP", + "LOCAL-FILE", and "MAIL-SERVER".</p> </li> <li> <p>This parameter is unconditionally mandatory and MUST be present.</p> @@ -611,8 +619,8 @@ This word is not case sensitive.</p> </div> </li> <li> -<p>EXPIRATION — The date after which the existence of the external data is -not guaranteed.</p> +<p>EXPIRATION -- The date after which the existence of the external data is + not guaranteed.</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> @@ -622,9 +630,9 @@ not guaranteed.</p> </div> </li> <li> -<p>SIZE — The size (in octets) of the data in its canonical form, that is, -before any Content-Transfer-Encoding has been applied or after the data -have been decoded.</p> +<p>SIZE -- The size (in octets) of the data in its canonical form, that is, + before any Content-Transfer-Encoding has been applied or after the data + have been decoded.</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> @@ -638,11 +646,16 @@ have been decoded.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/MIME_I_FORMAT.html b/doc/MIME_I_FORMAT.html index 228172d9..85bf67b0 100644 --- a/doc/MIME_I_FORMAT.html +++ b/doc/MIME_I_FORMAT.html @@ -1,39 +1,47 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>MIME Part One: Format of Internet Message Bodies</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>MIME Part One: Format of Internet Message Bodies</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>MIME Part One: Format of Internet Message Bodies</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>MIME Part One: Format of Internet Message Bodies</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_mime_header_fields">1. MIME Header Fields</a></li> -<li><a href="#_mime_version_header_field">2. MIME Version Header Field</a></li> -<li><a href="#_content_type_header_field">3. Content-Type Header Field</a></li> -<li><a href="#_content_transfer_encoding_header_field">4. Content-Transfer-Encoding Header Field</a> +<li><a href="#_mime_header_fields">MIME Header Fields</a></li> +<li><a href="#_mime_version_header_field">MIME Version Header Field</a></li> +<li><a href="#_content_type_header_field">Content-Type Header Field</a></li> +<li><a href="#_content_transfer_encoding_header_field">Content-Transfer-Encoding Header Field</a> <ul class="sectlevel2"> -<li><a href="#_quoted_printable_content_transfer_encoding">4.1. Quoted-Printable Content-Transfer-Encoding</a></li> -<li><a href="#_base64_content_transfer_encoding">4.2. Base64 Content-Transfer-Encoding</a></li> +<li><a href="#_quoted_printable_content_transfer_encoding">Quoted-Printable Content-Transfer-Encoding</a></li> +<li><a href="#_base64_content_transfer_encoding">Base64 Content-Transfer-Encoding</a></li> </ul> </li> -<li><a href="#_content_id_header_field">5. Content-ID Header Field</a></li> -<li><a href="#_content_description_header_field">6. Content-Description Header Field</a></li> +<li><a href="#_content_id_header_field">Content-ID Header Field</a></li> +<li><a href="#_content_description_header_field">Content-Description Header Field</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -43,7 +51,7 @@ Extensions (MIME) Part One: Format of Internet Message Bodies.</p> </div> </div> <div class="sect1"> -<h2 id="_mime_header_fields">1. MIME Header Fields</h2> +<h2 id="_mime_header_fields">MIME Header Fields</h2> <div class="sectionbody"> <div class="paragraph"> <p>MIME header fields can occur in message header (RFC 5322) or in a MIME body @@ -68,7 +76,7 @@ entity-headers := [ content CRLF ] </div> </div> <div class="sect1"> -<h2 id="_mime_version_header_field">2. MIME Version Header Field</h2> +<h2 id="_mime_version_header_field">MIME Version Header Field</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -78,26 +86,26 @@ entity-headers := [ content CRLF ] <div class="ulist"> <ul> <li> -<p>Valid value is "1.0".</p> +<p>Valid value is "1.0".</p> </li> <li> <p>Comment strings that are present MUST be ignored.</p> </li> <li> <p>MIME-Version header field is required at the top level of a message. It is -not required for each body part of a multipart entity.</p> + not required for each body part of a multipart entity.</p> </li> <li> <p>In the absence of a MIME-Version field, a receiving mail user agent -MAY optionally choose to interpret the body of the message according to -local conventions.</p> + MAY optionally choose to interpret the body of the message according to + local conventions.</p> </li> </ul> </div> </div> </div> <div class="sect1"> -<h2 id="_content_type_header_field">3. Content-Type Header Field</h2> +<h2 id="_content_type_header_field">Content-Type Header Field</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -112,17 +120,17 @@ composite-type := "message" / "multipart" / extension-token extension-token := ietf-token / x-token -ietf-token := <An extension token defined by a standards-track RFC and - registered with IANA.> +ietf-token := <An extension token defined by a standards-track RFC and + registered with IANA.> -x-token := <The two characters "X-" or "x-" followed, with - no intervening white space, by any token> +x-token := <The two characters "X-" or "x-" followed, with + no intervening white space, by any token> subtype := extension-token / iana-token -iana-token := <A publicly-defined extension token. Tokens +iana-token := <A publicly-defined extension token. Tokens of this form must be registered with IANA - as specified in RFC 2048.> + as specified in RFC 2048.> parameter := attribute "=" value @@ -130,10 +138,10 @@ attribute := token value := token / quoted-string -token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials> +token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials> -tspecials := "(" / ")" / "<" / ">" / "@" / - "," / ";" / ":" / "\" / <"> +tspecials := "(" / ")" / "<" / ">" / "@" / + "," / ";" / ":" / "\" / <"> "/" / "[" / "]" / "?" / "="</pre> </div> </div> @@ -141,12 +149,16 @@ tspecials := "(" / ")" / "<" / ">" / "@" / <ul> <li> <p>Default value,</p> +</li> +</ul> +</div> <div class="literalblock"> <div class="content"> -<pre>Content-type: text/plain; charset=us-ascii</pre> +<pre> Content-type: text/plain; charset=us-ascii</pre> </div> </div> -</li> +<div class="ulist"> +<ul> <li> <p>Content-Type field is to describe the data contained in the body.</p> </li> @@ -164,26 +176,26 @@ tspecials := "(" / ")" / "<" / ">" / "@" / </li> <li> <p>Parameters may be required by their defining content type or subtype or -they may be optional.</p> + they may be optional.</p> </li> <li> <p>Special character MUST be in quoted-string, to use within parameter -values. -The quotation marks itself is not part of value.</p> + values. + The quotation marks itself is not part of value.</p> </li> <li> <p>Value may be case insensitive, depends on attribute name.</p> </li> <li> <p>Implementations MUST ignore any parameters whose names they do not -recognize.</p> + recognize.</p> </li> </ul> </div> </div> </div> <div class="sect1"> -<h2 id="_content_transfer_encoding_header_field">4. Content-Transfer-Encoding Header Field</h2> +<h2 id="_content_transfer_encoding_header_field">Content-Transfer-Encoding Header Field</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -197,71 +209,71 @@ mechanism := "7bit" / "8bit" / "binary" / <div class="ulist"> <ul> <li> -<p>Default value is "7bit"</p> +<p>Default value is "7bit"</p> </li> <li> <p>This value is case insensitive</p> </li> <li> -<p>Values "7bit", "8bit", and "binary" all mean that the identity (i.e. NO) -encoding transformation has been performed.</p> +<p>Values "7bit", "8bit", and "binary" all mean that the identity (i.e. NO) + encoding transformation has been performed.</p> <div class="ulist"> <ul> <li> -<p>"7bit" data refers to octets with decimal values greater than 127 -are not allowed and neither are NULs (octet with decimal value 0). -CR (decimal value 13) and LF (decimal value 10) octets only occur as -part of CRLF line separation sequences.</p> +<p>"7bit" data refers to octets with decimal values greater than 127 + are not allowed and neither are NULs (octet with decimal value 0). + CR (decimal value 13) and LF (decimal value 10) octets only occur as + part of CRLF line separation sequences.</p> </li> <li> -<p>"8bit" data allow octets with decimal values greater than 127. -CR and LF octets only occur as part of CRLF line separation sequences and -no NULs are allowed.</p> +<p>"8bit" data allow octets with decimal values greater than 127. + CR and LF octets only occur as part of CRLF line separation sequences and + no NULs are allowed.</p> </li> <li> -<p>"Binary data" refers to data where any sequence of octets whatsoever -is allowed.</p> +<p>"Binary data" refers to data where any sequence of octets whatsoever + is allowed.</p> </li> </ul> </div> </li> <li> <p>The proper Content-Transfer-Encoding label MUST always be used. -Labelling unencoded data containing 8bit characters as "7bit" is not -allowed, nor is labelling unencoded non-line-oriented data as anything -other than "binary" allowed.</p> + Labelling unencoded data containing 8bit characters as "7bit" is not + allowed, nor is labelling unencoded non-line-oriented data as anything + other than "binary" allowed.</p> </li> <li> <p>Mail transport for unencoded 8bit data is defined in RFC 6152.</p> </li> <li> -<p>Private values, MUST use an x-token, e.g. "Content-Type-Encoding: x-new".</p> +<p>Private values, MUST use an x-token, e.g. "Content-Type-Encoding: x-new".</p> </li> <li> <p>If the header field appears as part of a message header, it applies to the -entire body of that message. -If the header field appears as part of an entity’s headers, it applies only -to the body of that entity.</p> + entire body of that message. + If the header field appears as part of an entity's headers, it applies only + to the body of that entity.</p> </li> <li> -<p>It is EXPRESSLY FORBIDDEN to use any encodings other than "7bit", "8bit", -or "binary" with any composite media type. -Composite media types are "multipart" and "message".</p> +<p>It is EXPRESSLY FORBIDDEN to use any encodings other than "7bit", "8bit", + or "binary" with any composite media type. + Composite media types are "multipart" and "message".</p> </li> <li> <p>Any entity with an unrecognized Content-Transfer-Encoding MUST be -treated as "application/octet-stream", regardless of what the Content-Type -header field actually says.</p> + treated as "application/octet-stream", regardless of what the Content-Type + header field actually says.</p> </li> <li> <p>When converting from quoted-printable to base64, a hard line break in the -quoted-printable form represents a CRLF sequence in the canonical form of -the data. -It MUST therefore be converted to a corresponding encoded CRLF in the -base64 form of the data. -Similarly, a CRLF sequence in the canonical form of the data obtained after -base64 decoding MUST be converted to a quoted-printable hard line break, -but ONLY when converting text data.</p> + quoted-printable form represents a CRLF sequence in the canonical form of + the data. + It MUST therefore be converted to a corresponding encoded CRLF in the + base64 form of the data. + Similarly, a CRLF sequence in the canonical form of the data obtained after + base64 decoding MUST be converted to a quoted-printable hard line break, + but ONLY when converting text data.</p> </li> <li> <p>A canonical model for encoding is presented in RFC 2049.</p> @@ -269,7 +281,7 @@ but ONLY when converting text data.</p> </ul> </div> <div class="sect2"> -<h3 id="_quoted_printable_content_transfer_encoding">4.1. Quoted-Printable Content-Transfer-Encoding</h3> +<h3 id="_quoted_printable_content_transfer_encoding">Quoted-Printable Content-Transfer-Encoding</h3> <div class="literalblock"> <div class="content"> <pre>quoted-printable := qp-line *(CRLF qp-line) @@ -288,13 +300,13 @@ qp-section := [*(ptext / SPACE / TAB) ptext] ptext := hex-octet / safe-char hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F") - ; Octet must be used for characters > 127, =, + ; Octet must be used for characters > 127, =, ; SPACEs or TABs at the ends of lines, and is ; recommended for any character not listed in ; RFC 2049 as "mail-safe". -safe-char := <any octet with decimal value of 33 through - 60 inclusive, and 62 through 126> +safe-char := <any octet with decimal value of 33 through + 60 inclusive, and 62 through 126> ; Characters not listed as "mail-safe" in ; RFC 2049 are also not recommended. @@ -312,65 +324,69 @@ rules:</p> <ol class="arabic"> <li> <p>(General 8bit representation) Any octet, except a CRLF line break of the -canonical (standard) form of the data being encoded, may be represented by -an "=" followed by a two digit hexadecimal representation of the octet’s -value. -Uppercase letters MUST be used. -A way to get reasonably reliable transport through EBCDIC gateways is to -also quote the US-ASCII characters</p> + canonical (standard) form of the data being encoded, may be represented by + an "=" followed by a two digit hexadecimal representation of the octet's + value. + Uppercase letters MUST be used. + A way to get reasonably reliable transport through EBCDIC gateways is to + also quote the US-ASCII characters</p> +</li> +</ol> +</div> <div class="literalblock"> <div class="content"> <pre>!"#$@[\]^`{|}~</pre> </div> </div> -</li> +<div class="olist arabic"> +<ol class="arabic"> <li> <p>(Literal representation) Octets with decimal values of 33 through 60 -inclusive, and 62 through 126, inclusive, MAY be represented as the -US-ASCII characters.</p> + inclusive, and 62 through 126, inclusive, MAY be represented as the + US-ASCII characters.</p> </li> <li> <p>(White Space) Octets with values of 9 and 32 MAY be represented as US-ASCII -TAB (HT) and SPACE characters, but MUST NOT be so represented at the end -of an encoded line.</p> + TAB (HT) and SPACE characters, but MUST NOT be so represented at the end + of an encoded line.</p> <div class="ulist"> <ul> <li> <p>Any TAB (HT) or SPACE characters on an encoded line MUST thus be -followed on that line by a printable character.</p> + followed on that line by a printable character.</p> </li> <li> -<p>An "=" at the end of an encoded line, indicating a soft line break -(see rule #5) may follow one or more TAB (HT) or SPACE characters.</p> +<p>An "=" at the end of an encoded line, indicating a soft line break + (see rule #5) may follow one or more TAB (HT) or SPACE characters.</p> </li> <li> <p>When decoding a Quoted-Printable body, any trailing white space on a -line MUST be deleted</p> + line MUST be deleted</p> </li> </ul> </div> </li> <li> <p>(Line Breaks) A line break in a text body, represented as a CRLF sequence -in the text canonical form, MUST be represented by a (RFC 822) line break. -A CR or LF in binary data should be encoded as "=0D" and "=0A".</p> + in the text canonical form, MUST be represented by a (RFC 822) line break. + A CR or LF in binary data should be encoded as "=0D" and "=0A".</p> </li> <li> <p>(Soft Line Breaks) The Quoted-Printable encoding REQUIRES that encoded -lines be no more than 76 characters long. -If longer lines are to be encoded with the Quoted-Printable encoding, -"soft" line breaks MUST be used. -An equal sign as the last character on a encoded line indicates such a -non-significant ("soft") line break in the encoded text.</p> + lines be no more than 76 characters long. + If longer lines are to be encoded with the Quoted-Printable encoding, + "soft" line breaks MUST be used. + An equal sign as the last character on a encoded line indicates such a + non-significant ("soft") line break in the encoded text.</p> <div class="ulist"> <ul> <li> <p>The 76 character limit does not count the trailing CRLF, but counts all -other characters, including any equal signs.</p> + other characters, including any equal signs.</p> </li> <li> <p>A good strategy is to choose a boundary that includes a character sequence -such as "=_" which can never appear in a quoted-printable body.</p> + such as "=_" which can never appear in a quoted-printable body.</p> </li> </ul> </div> @@ -386,44 +402,44 @@ Such cases are,</p> <div class="olist arabic"> <ol class="arabic"> <li> -<p>An "=" followed by two hexadecimal digits, one or both of which are -lowercase letters in "abcdef", is formally illegal. -A robust implementation might choose to recognize them as the corresponding -uppercase letters.</p> +<p>An "=" followed by two hexadecimal digits, one or both of which are + lowercase letters in "abcdef", is formally illegal. + A robust implementation might choose to recognize them as the corresponding + uppercase letters.</p> </li> <li> -<p>An "=" followed by a character that is neither a hexadecimal digit -(including "abcdef") nor the CR character of a CRLF pair is illegal. -A reasonable approach by a robust implementation might be to include the -"=" character and the following character in the decoded data without any -transformation and, if possible, indicate to the user that proper decoding -was not possible at this point in the data.</p> +<p>An "=" followed by a character that is neither a hexadecimal digit + (including "abcdef") nor the CR character of a CRLF pair is illegal. + A reasonable approach by a robust implementation might be to include the + "=" character and the following character in the decoded data without any + transformation and, if possible, indicate to the user that proper decoding + was not possible at this point in the data.</p> </li> <li> -<p>An "=" cannot be the ultimate or penultimate character in an encoded -object.</p> +<p>An "=" cannot be the ultimate or penultimate character in an encoded + object.</p> </li> <li> <p>Control characters other than TAB, or CR and LF as parts of CRLF pairs, -MUST not appear. -The same is true for octets with decimal values greater than 126. -If decoder found it, a robust implementation might exclude them from the -decoded data and warn the user that illegal characters were discovered.</p> + MUST not appear. + The same is true for octets with decimal values greater than 126. + If decoder found it, a robust implementation might exclude them from the + decoded data and warn the user that illegal characters were discovered.</p> </li> <li> <p>If longer lines are found in encoded data, a robust implementation might -nevertheless decode the lines, and might report the erroneous encoding to -the user</p> + nevertheless decode the lines, and might report the erroneous encoding to + the user</p> </li> </ol> </div> </div> <div class="sect2"> -<h3 id="_base64_content_transfer_encoding">4.2. Base64 Content-Transfer-Encoding</h3> +<h3 id="_base64_content_transfer_encoding">Base64 Content-Transfer-Encoding</h3> <div class="paragraph"> <p>A 65-character subset of US-ASCII is used, enabling 6 bits to be represented per printable character. -(The extra 65th character, "=", is used to signify a special processing +(The extra 65th character, "=", is used to signify a special processing function.)</p> </div> <div class="literalblock"> @@ -457,36 +473,36 @@ per printable character. <ol class="arabic"> <li> <p>Text line breaks MUST be converted into CRLF sequences prior to base64 -encoding.</p> + encoding.</p> </li> <li> <p>The encoding process represents 24-bit groups of input bits as output -strings of 4 encoded characters.</p> + strings of 4 encoded characters.</p> </li> <li> <p>Proceeding from left to right, a 24-bit input group is formed by -concatenating 3 8bit input groups.</p> + concatenating 3 8bit input groups.</p> </li> <li> <p>These 24 bits are then treated as 4 concatenated 6-bit groups, each -of which is translated into a single digit in the base64 alphabet. -The following cases can arise:</p> + of which is translated into a single digit in the base64 alphabet. + The following cases can arise:</p> <div class="olist loweralpha"> <ol class="loweralpha" type="a"> <li> <p>The final quantum of encoding input is an integral multiple of 24 bits; -here, the final unit of encoded output will be an integral multiple of 4 -characters with no "=" padding</p> + here, the final unit of encoded output will be an integral multiple of 4 + characters with no "=" padding</p> </li> <li> <p>The final quantum of encoding input is exactly 8 bits; here, the final -unit of encoded output will be two characters followed by two "=" -padding characters</p> + unit of encoded output will be two characters followed by two "=" + padding characters</p> </li> <li> <p>The final quantum of encoding input is exactly 16 bits; here, the final -unit of encoded output will be three characters followed by one "=" -padding character.</p> + unit of encoded output will be three characters followed by one "=" + padding character.</p> </li> </ol> </div> @@ -500,16 +516,16 @@ padding character.</p> <ul> <li> <p>When encoding a bit stream via the base64 encoding, the bit stream -MUST be presumed to be ordered with the most-significant-bit first.</p> + MUST be presumed to be ordered with the most-significant-bit first.</p> </li> <li> <p>The encoded output stream MUST be represented in lines of no more -than 76 characters each.</p> + than 76 characters each.</p> </li> <li> <p>Other characters not found in Table 1 MUST be ignored by decoding software. -This probably indicate a transmission error, about which a warning message -or even a message rejection might be appropriate under some circumstances.</p> + This probably indicate a transmission error, about which a warning message + or even a message rejection might be appropriate under some circumstances.</p> </li> </ul> </div> @@ -517,7 +533,7 @@ or even a message rejection might be appropriate under some circumstances.</p> </div> </div> <div class="sect1"> -<h2 id="_content_id_header_field">5. Content-ID Header Field</h2> +<h2 id="_content_id_header_field">Content-ID Header Field</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -530,30 +546,30 @@ or even a message rejection might be appropriate under some circumstances.</p> <p>The Content-ID field allow one body to make reference to another.</p> </li> <li> -<p>Its syntactically identical to the "Message-ID" header field</p> +<p>Its syntactically identical to the "Message-ID" header field</p> </li> <li> <p>Content-ID values MUST be generated to be world-unique.</p> </li> <li> <p>The Content-ID value may be used for uniquely identifying MIME entities in -several contexts, particularly for caching data referenced by the -message/external-body mechanism.</p> + several contexts, particularly for caching data referenced by the + message/external-body mechanism.</p> </li> <li> <p>Its use is MANDATORY in implementations which generate data of the optional -MIME media type "message/external-body".</p> + MIME media type "message/external-body".</p> </li> <li> <p>The Content-ID value has special semantics in the case of the -multipart/alternative media type (see RFC 2046).</p> + multipart/alternative media type (see RFC 2046).</p> </li> </ul> </div> </div> </div> <div class="sect1"> -<h2 id="_content_description_header_field">6. Content-Description Header Field</h2> +<h2 id="_content_description_header_field">Content-Description Header Field</h2> <div class="sectionbody"> <div class="literalblock"> <div class="content"> @@ -569,11 +585,16 @@ multipart/alternative media type (see RFC 2046).</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/MIME_V_CONFORMANCE.html b/doc/MIME_V_CONFORMANCE.html index 016a13a3..e53a6e15 100644 --- a/doc/MIME_V_CONFORMANCE.html +++ b/doc/MIME_V_CONFORMANCE.html @@ -1,31 +1,39 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>MIME Part Five: Conformance Criteria and Examples</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>MIME Part Five: Conformance Criteria and Examples</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>MIME Part Five: Conformance Criteria and Examples</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>MIME Part Five: Conformance Criteria and Examples</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_mime_conformance">1. MIME Conformance</a></li> -<li><a href="#_guidelines_for_sending_email_data">2. Guidelines for Sending Email Data</a></li> -<li><a href="#_canonical_encoding_model">3. Canonical Encoding Model</a></li> +<li><a href="#_mime_conformance">MIME Conformance</a></li> +<li><a href="#_guidelines_for_sending_email_data">Guidelines for Sending Email Data</a></li> +<li><a href="#_canonical_encoding_model">Canonical Encoding Model</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -35,10 +43,10 @@ Extensions (MIME) Part Five: Conformance Criteria and Examples</p> </div> </div> <div class="sect1"> -<h2 id="_mime_conformance">1. MIME Conformance</h2> +<h2 id="_mime_conformance">MIME Conformance</h2> <div class="sectionbody"> <div class="paragraph"> -<p>The concept of "MIME-conformance" is to define a certain level of +<p>The concept of "MIME-conformance" is to define a certain level of implementation that allows the useful interworking of messages with content that differs from US-ASCII text.</p> </div> @@ -48,18 +56,18 @@ that differs from US-ASCII text.</p> <div class="olist arabic"> <ol class="arabic"> <li> -<p>Always generate "MIME-Version: 1.0" in header field</p> +<p>Always generate "MIME-Version: 1.0" in header field</p> </li> <li> <p>Enable to decode using quoted-printable or base64. -Sending non-7bit data without encoding MUST use content-transfer-encoding -8bit or binary, as appropriate. -If the underlying transport does not support 8bit or binary, sender must -encode and label data using quoted-printable or base64.</p> + Sending non-7bit data without encoding MUST use content-transfer-encoding + 8bit or binary, as appropriate. + If the underlying transport does not support 8bit or binary, sender must + encode and label data using quoted-printable or base64.</p> </li> <li> <p>Treat unrecognized Content-Transfer-Encoding as Content-Type of -"application/octet-stream", regardless their actual type.</p> + "application/octet-stream", regardless their actual type.</p> </li> <li> <p>Avoid showing users raw data when a Content-Type field other than text.</p> @@ -76,18 +84,18 @@ encode and label data using quoted-printable or base64.</p> <div class="olist lowerroman"> <ol class="lowerroman" type="i"> <li> -<p>Recognize and display "text" with "US-ASCII"</p> +<p>Recognize and display "text" with "US-ASCII"</p> </li> <li> <p>Recognize other charset, at least being able to inform the user about -charset the message uses</p> + charset the message uses</p> </li> <li> <p>For unrecognized subtypes in a known charset, offer to show the user the -"raw" version of data after conversion from canonical to local form</p> + "raw" version of data after conversion from canonical to local form</p> </li> <li> -<p>Treat material in an unknown charset as "application/octet-stream"</p> +<p>Treat material in an unknown charset as "application/octet-stream"</p> </li> </ol> </div> @@ -97,7 +105,7 @@ charset the message uses</p> <div class="olist lowerroman"> <ol class="lowerroman" type="i"> <li> -<p>Treat any unrecognized subtypes as "application/octet-stream"</p> +<p>Treat any unrecognized subtypes as "application/octet-stream"</p> </li> </ol> </div> @@ -108,7 +116,7 @@ charset the message uses</p> <ol class="lowerroman" type="i"> <li> <p>Offer the ability to remove encodings and put the resulting information -in a user file</p> + in a user file</p> </li> </ol> </div> @@ -121,15 +129,15 @@ in a user file</p> <p>Recognize the mixed subtype</p> </li> <li> -<p>Recognize the "alternative" subtype, and avoid showing the user redundant -parts.</p> +<p>Recognize the "alternative" subtype, and avoid showing the user redundant + parts.</p> </li> <li> -<p>Recognize the "digest" subtype, specifically using "message/rfc822" -rather than "text/plain" as the default media type for body parts</p> +<p>Recognize the "digest" subtype, specifically using "message/rfc822" + rather than "text/plain" as the default media type for body parts</p> </li> <li> -<p>Treat unrecognized subtypes as "mixed"</p> +<p>Treat unrecognized subtypes as "mixed"</p> </li> </ol> </div> @@ -142,7 +150,7 @@ rather than "text/plain" as the default media type for body parts</p> <p>Recognize and display RFC822 message encapsulation (message/rfc822)</p> </li> <li> -<p>Treat unrecognized subtypes as "application/octet-stream"</p> +<p>Treat unrecognized subtypes as "application/octet-stream"</p> </li> </ol> </div> @@ -151,24 +159,24 @@ rather than "text/plain" as the default media type for body parts</p> </div> </li> <li> -<p>Treat unrecognized Content-Type as "application/octet-stream"</p> +<p>Treat unrecognized Content-Type as "application/octet-stream"</p> </li> <li> <p>Using non-US-ASCII without a MIME-Version field is strongly discouraged.</p> </li> <li> -<p>Ensure that any string that begins with "=?" and ends with "?=" in field -body to be valid encoded-word.</p> +<p>Ensure that any string that begins with "=?" and ends with "?=" in field + body to be valid encoded-word.</p> </li> <li> -<p>Able to distinguish encoded-words from "text", "ctext", or "word"s</p> +<p>Able to distinguish encoded-words from "text", "ctext", or "word"s</p> </li> </ol> </div> </div> </div> <div class="sect1"> -<h2 id="_guidelines_for_sending_email_data">2. Guidelines for Sending Email Data</h2> +<h2 id="_guidelines_for_sending_email_data">Guidelines for Sending Email Data</h2> <div class="sectionbody"> <div class="paragraph"> <p>The list is NOT recommended practices for MTAs.</p> @@ -176,7 +184,7 @@ body to be valid encoded-word.</p> </div> </div> <div class="sect1"> -<h2 id="_canonical_encoding_model">3. Canonical Encoding Model</h2> +<h2 id="_canonical_encoding_model">Canonical Encoding Model</h2> <div class="sectionbody"> <div class="paragraph"> <p>Conversion steps from local to canonical form,</p> @@ -185,26 +193,26 @@ body to be valid encoded-word.</p> <ol class="arabic"> <li> <p>Creation of local form -The body to be transmitted is created in the system’s native format.</p> + The body to be transmitted is created in the system's native format.</p> </li> <li> <p>Conversion to canonical form. -The entire body, including "out-of-band" information such as record lengths -and possibly file attribute information, is converted to a universal -canonical form. -For example, in case of "text/plain", the text MUST be converted to a -supported charset and lines MUST be delimited with CRLF.</p> + The entire body, including "out-of-band" information such as record lengths + and possibly file attribute information, is converted to a universal + canonical form. + For example, in case of "text/plain", the text MUST be converted to a + supported charset and lines MUST be delimited with CRLF.</p> </li> <li> <p>Apply transfer encoding. -It may be appropriate to base the choice of base64 or quoted-printable on -character frequency counts.</p> + It may be appropriate to base the choice of base64 or quoted-printable on + character frequency counts.</p> </li> <li> <p>Insertion into entity. -The encoded body then inserted into MIME entity with appropriate headers. -The entity is then inserted into the body of higher-level entity (message -or multipart).</p> + The encoded body then inserted into MIME entity with appropriate headers. + The entity is then inserted into the body of higher-level entity (message + or multipart).</p> </li> </ol> </div> @@ -217,22 +225,27 @@ these steps.</p> </div> <div class="literalblock"> <div class="content"> -<pre>Content-type: text/foo; charset=bar -Content-Transfer-Encoding: base64</pre> +<pre> Content-type: text/foo; charset=bar + Content-Transfer-Encoding: base64</pre> </div> </div> <div class="paragraph"> -<p>MUST be first represented in the "text/foo" form, then represented in the -"bar" character set, and finally transformed via the base64 algorithm into +<p>MUST be first represented in the "text/foo" form, then represented in the +"bar" character set, and finally transformed via the base64 algorithm into mail-safe form.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/SASL.html b/doc/SASL.html index 506bf1a1..8c008cb5 100644 --- a/doc/SASL.html +++ b/doc/SASL.html @@ -1,46 +1,54 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>Simple Authentication and Security Layer (SASL)</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>Simple Authentication and Security Layer (SASL)</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>Simple Authentication and Security Layer (SASL)</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>Simple Authentication and Security Layer (SASL)</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a></li> -<li><a href="#_identity_concepts">2. Identity Concepts</a></li> -<li><a href="#_the_authentication_exchange">3. The Authentication Exchange</a> +<li><a href="#_introduction">Introduction</a></li> +<li><a href="#_identity_concepts">Identity Concepts</a></li> +<li><a href="#_the_authentication_exchange">The Authentication Exchange</a> <ul class="sectlevel2"> -<li><a href="#_mechanism_naming">3.1. Mechanism Naming</a></li> -<li><a href="#_security_layers">3.2. Security Layers</a></li> +<li><a href="#_mechanism_naming">Mechanism Naming</a></li> +<li><a href="#_security_layers">Security Layers</a></li> </ul> </li> -<li><a href="#_protocol_requirements">4. Protocol Requirements</a></li> -<li><a href="#_mechanism_specifications">5. Mechanism Specifications</a></li> -<li><a href="#_security_considerations">6. Security Considerations</a> +<li><a href="#_protocol_requirements">Protocol Requirements</a></li> +<li><a href="#_mechanism_specifications">Mechanism Specifications</a></li> +<li><a href="#_security_considerations">Security Considerations</a> <ul class="sectlevel2"> -<li><a href="#_active_attacks">6.1. Active Attacks</a></li> -<li><a href="#_passive_attacks">6.2. Passive Attacks</a></li> -<li><a href="#_re_keying">6.3. Re-keying</a></li> +<li><a href="#_active_attacks">Active Attacks</a></li> +<li><a href="#_passive_attacks">Passive Attacks</a></li> +<li><a href="#_re_keying">Re-keying</a></li> </ul> </li> -<li><a href="#_mechanism_registry">7. Mechanism Registry</a></li> +<li><a href="#_mechanism_registry">Mechanism Registry</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -50,7 +58,7 @@ Security Layer (SASL).</p> </div> </div> <div class="sect1"> -<h2 id="_introduction">1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> <p>SASL is conceptually a framework that provides an abstraction layer between @@ -70,7 +78,7 @@ protocols and mechanisms as illustrated in the following diagram.</p> </div> </div> <div class="sect1"> -<h2 id="_identity_concepts">2. Identity Concepts</h2> +<h2 id="_identity_concepts">Identity Concepts</h2> <div class="sectionbody"> <div class="paragraph"> <p>Authentication identity is an identity that is used on credential form that @@ -92,7 +100,7 @@ and authorization identity to be transferred by mechanism.</p> </div> </div> <div class="sect1"> -<h2 id="_the_authentication_exchange">3. The Authentication Exchange</h2> +<h2 id="_the_authentication_exchange">The Authentication Exchange</h2> <div class="sectionbody"> <div class="paragraph"> <p>The following illustration provides a high-level overview of an @@ -100,15 +108,15 @@ authentication exchange.</p> </div> <div class="literalblock"> <div class="content"> -<pre>C: Request available mechanism on server -S: List of available mechanism -<Client select the best and suitable mechanism> -C: Request authentication exchange -<Mechanism name + [ additional data ]> -S: Initial challenge -C: Initial response -<additional challenge/response messages> -S: Outcome of authentication exchange</pre> +<pre> C: Request available mechanism on server + S: List of available mechanism + <Client select the best and suitable mechanism> + C: Request authentication exchange + <Mechanism name + [ additional data ]> + S: Initial challenge + C: Initial response + <additional challenge/response messages> + S: Outcome of authentication exchange</pre> </div> </div> <div class="paragraph"> @@ -116,8 +124,8 @@ S: Outcome of authentication exchange</pre> </div> <div class="literalblock"> <div class="content"> -<pre>C: Request authentication exchange + Initial response -S: Outcome of authentication exchange</pre> +<pre> C: Request authentication exchange + Initial response + S: Outcome of authentication exchange</pre> </div> </div> <div class="paragraph"> @@ -141,7 +149,7 @@ credential, timeout, internal server error).</p> <p>Client or server may abort the authentication exchange any time.</p> </div> <div class="sect2"> -<h3 id="_mechanism_naming">3.1. Mechanism Naming</h3> +<h3 id="_mechanism_naming">Mechanism Naming</h3> <div class="literalblock"> <div class="content"> <pre>sasl-mech = 1*20mech-char @@ -157,7 +165,7 @@ UNDERSCORE = %x5F ; underscore (_)</pre> </div> </div> <div class="sect2"> -<h3 id="_security_layers">3.2. Security Layers</h3> +<h3 id="_security_layers">Security Layers</h3> <div class="paragraph"> <p>If use of a security layer is negotiated in the authentication protocol exchange, the layer is installed by the server after indicating the outcome of @@ -191,14 +199,14 @@ security layer, the original security layer remains in effect.</p> </div> </div> <div class="sect1"> -<h2 id="_protocol_requirements">4. Protocol Requirements</h2> +<h2 id="_protocol_requirements">Protocol Requirements</h2> <div class="sectionbody"> <div class="paragraph"> <p>In order for a protocol to offer SASL services, its specification MUST supply the following information:</p> </div> <div class="paragraph"> -<p>1) A service name, to be selected from registry of "service" elements for +<p>1) A service name, to be selected from registry of "service" elements for the Generic Security Service Application Program Interface (GSSAPI) host-based service name form.</p> </div> @@ -255,7 +263,7 @@ authorization state.</p> </div> </div> <div class="sect1"> -<h2 id="_mechanism_specifications">5. Mechanism Specifications</h2> +<h2 id="_mechanism_specifications">Mechanism Specifications</h2> <div class="sectionbody"> <div class="paragraph"> <p>SASL mechanism specifications MUST supply the following information:</p> @@ -292,7 +300,7 @@ identity string and an empty authorization identity.</p> <div class="paragraph"> <p>Mechanisms that are capable of transferring an authorization identity string MUST be capable of transferring arbitrary non-empty sequences of Unicode -characters, excluding those that contain the NUL (U+0000) character. +characters, excluding those that contain the NUL (U+0000) character. The specification MUST detail how any Unicode code points special to the mechanism that might appear in the authorization identity string are escaped to avoid ambiguity during decoding of the authorization identity string.</p> @@ -326,27 +334,27 @@ the authorization identity string be canonical.</p> </div> </div> <div class="sect1"> -<h2 id="_security_considerations">6. Security Considerations</h2> +<h2 id="_security_considerations">Security Considerations</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_active_attacks">6.1. Active Attacks</h3> +<h3 id="_active_attacks">Active Attacks</h3> <div class="paragraph"> <p>When use of a security layer is negotiated by the authentication protocol exchange, the receiver SHOULD handle gracefully any protected data buffer larger than the defined/negotiated maximal size. In particular, it MUST NOT blindly allocate the amount of memory specified in -the buffer size field, as this might cause the "out of memory" condition. +the buffer size field, as this might cause the "out of memory" condition. If the receiver detects a large block, it SHOULD close the connection.</p> </div> <div class="sect3"> -<h4 id="_hijack_attacks">6.1.1. Hijack Attacks</h4> +<h4 id="_hijack_attacks">Hijack Attacks</h4> <div class="paragraph"> <p>Implementations SHOULD close the connection security layer report protocol data lack of data integrity.</p> </div> </div> <div class="sect3"> -<h4 id="_downgrade_attacks">6.1.2. Downgrade Attacks</h4> +<h4 id="_downgrade_attacks">Downgrade Attacks</h4> <div class="paragraph"> <p>Implementations SHOULD NOT advertise mechanisms and/or features that cannot meet their minimum security requirements. @@ -364,14 +372,14 @@ transport connection.</p> </div> </div> <div class="sect3"> -<h4 id="_replay_attacks">6.1.3. Replay Attacks</h4> +<h4 id="_replay_attacks">Replay Attacks</h4> <div class="paragraph"> <p>Some mechanisms may be subject to replay attacks unless protected by external data security services (e.g., TLS).</p> </div> </div> <div class="sect3"> -<h4 id="_truncation_attacks">6.1.4. Truncation Attacks</h4> +<h4 id="_truncation_attacks">Truncation Attacks</h4> <div class="paragraph"> <p>A protocol can defend against these attacks by ensuring that each information exchange has a clear final result and that each protocol session has a @@ -380,7 +388,7 @@ graceful closure mechanism, and that these are integrity protected.</p> </div> </div> <div class="sect2"> -<h3 id="_passive_attacks">6.2. Passive Attacks</h3> +<h3 id="_passive_attacks">Passive Attacks</h3> <div class="paragraph"> <p>Many mechanisms are subject to various passive attacks, including simple eavesdropping of unprotected credential information as well as online and @@ -388,7 +396,7 @@ off-line dictionary attacks of protected credential information.</p> </div> </div> <div class="sect2"> -<h3 id="_re_keying">6.3. Re-keying</h3> +<h3 id="_re_keying">Re-keying</h3> <div class="paragraph"> <p>Re-keying (key renegotiation process) is a way of addressing the weakening of cryptographic keys. @@ -400,20 +408,25 @@ services.</p> </div> </div> <div class="sect1"> -<h2 id="_mechanism_registry">7. Mechanism Registry</h2> +<h2 id="_mechanism_registry">Mechanism Registry</h2> <div class="sectionbody"> <div class="paragraph"> <p>The SASL mechanism registry is maintained by IANA. The registry is currently available at -<a href="http://www.iana.org/assignments/sasl-mechanisms" class="bare">http://www.iana.org/assignments/sasl-mechanisms</a>.</p> +<http://www.iana.org/assignments/sasl-mechanisms>.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/SASL_PLAIN.html b/doc/SASL_PLAIN.html index 19d98eee..d8338a55 100644 --- a/doc/SASL_PLAIN.html +++ b/doc/SASL_PLAIN.html @@ -1,31 +1,39 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>The PLAIN Simple Authentication and Security Layer (SASL) Mechanism</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>The PLAIN Simple Authentication and Security Layer (SASL) Mechanism</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>The PLAIN Simple Authentication and Security Layer (SASL) Mechanism</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>The PLAIN Simple Authentication and Security Layer (SASL) Mechanism</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a></li> -<li><a href="#_mechanism">2. Mechanism</a></li> -<li><a href="#_security_considerations">3. Security Considerations</a></li> +<li><a href="#_introduction">Introduction</a></li> +<li><a href="#_mechanism">Mechanism</a></li> +<li><a href="#_security_considerations">Security Considerations</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -35,10 +43,10 @@ Authentication and Security Layer (SASL) Mechanism.</p> </div> </div> <div class="sect1"> -<h2 id="_introduction">1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> -<p>The name associated with this mechanism is "PLAIN".</p> +<p>The name associated with this mechanism is "PLAIN".</p> </div> <div class="paragraph"> <p>The PLAIN mechanism does not provide a security layer.</p> @@ -46,7 +54,7 @@ Authentication and Security Layer (SASL) Mechanism.</p> </div> </div> <div class="sect1"> -<h2 id="_mechanism">2. Mechanism</h2> +<h2 id="_mechanism">Mechanism</h2> <div class="sectionbody"> <div class="paragraph"> <p>The mechanism consists of a single message, a string of [UTF-8] encoded @@ -74,7 +82,7 @@ UTF0 = %x80-BF</pre> </div> <div class="paragraph"> <p>The form of the authorization identity (authzid) production is specific to the -application-level protocol’s. +application-level protocol's. The authentication identity (authcid) and password productions are form-free. Use of non-visible characters or characters that a user may be unable to enter on some keyboards is discouraged.</p> @@ -82,7 +90,7 @@ enter on some keyboards is discouraged.</p> </div> </div> <div class="sect1"> -<h2 id="_security_considerations">3. Security Considerations</h2> +<h2 id="_security_considerations">Security Considerations</h2> <div class="sectionbody"> <div class="paragraph"> <p>By default, implementations SHOULD NOT advertise and SHOULD NOT make use of @@ -91,15 +99,20 @@ generally through use of Transport Layer Security (TLS) service.</p> </div> <div class="paragraph"> <p>Clients are encouraged to have an operational mode where all mechanisms that -are likely to reveal the user’s password to the server are disabled.</p> +are likely to reveal the user's password to the server are disabled.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/SMTP.adoc b/doc/SMTP.adoc index 440d0c66..bb16499d 100644 --- a/doc/SMTP.adoc +++ b/doc/SMTP.adoc @@ -1,7 +1,7 @@ = Simple Mail Transfer Protocol (SMTP) :author: Shulhan :email: <ms@kilabit.info> -:toc: left +:toc: :toclevels: 4 :sectnums: :stylesheet: style.css diff --git a/doc/SMTP.html b/doc/SMTP.html index 765a7e9e..47578363 100644 --- a/doc/SMTP.html +++ b/doc/SMTP.html @@ -1,133 +1,141 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>Simple Mail Transfer Protocol (SMTP)</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article toc2 toc-left"> -<div id="header"> -<h1>Simple Mail Transfer Protocol (SMTP)</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc2"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>Simple Mail Transfer Protocol (SMTP)</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>Simple Mail Transfer Protocol (SMTP)</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_syntax">1. Syntax</a> +<li><a href="#_syntax">Syntax</a> <ul class="sectlevel2"> -<li><a href="#_format_of_request">1.1. Format of Request</a> +<li><a href="#_format_of_request">Format of Request</a> <ul class="sectlevel3"> -<li><a href="#_format_of_parameters">1.1.1. Format of Parameters</a></li> +<li><a href="#_format_of_parameters">Format of Parameters</a></li> </ul> </li> -<li><a href="#_format_of_response">1.2. Format of Response</a></li> -<li><a href="#_format_of_path">1.3. Format of Path</a></li> -<li><a href="#_format_of_domain">1.4. Format of Domain</a></li> -<li><a href="#_format_of_mailbox">1.5. Format of Mailbox</a></li> +<li><a href="#_format_of_response">Format of Response</a></li> +<li><a href="#_format_of_path">Format of Path</a></li> +<li><a href="#_format_of_domain">Format of Domain</a></li> +<li><a href="#_format_of_mailbox">Format of Mailbox</a></li> </ul> </li> -<li><a href="#_session_initiation">2. Session Initiation</a> +<li><a href="#_session_initiation">Session Initiation</a> <ul class="sectlevel2"> -<li><a href="#_request">2.1. Request</a></li> -<li><a href="#_success_response">2.2. Success Response</a></li> -<li><a href="#_error_response">2.3. Error Response</a></li> +<li><a href="#_request">Request</a></li> +<li><a href="#_success_response">Success Response</a></li> +<li><a href="#_error_response">Error Response</a></li> </ul> </li> -<li><a href="#_mail_transaction">3. Mail Transaction</a> +<li><a href="#_mail_transaction">Mail Transaction</a> <ul class="sectlevel2"> -<li><a href="#_heloehlo">3.1. HELO/EHLO</a> +<li><a href="#_helo_ehlo">HELO/EHLO</a> <ul class="sectlevel3"> -<li><a href="#_request_2">3.1.1. Request</a></li> -<li><a href="#_success_response_2">3.1.2. Success response</a></li> -<li><a href="#_error_responses">3.1.3. Error responses</a></li> +<li><a href="#_request_2">Request</a></li> +<li><a href="#_success_response_2">Success response</a></li> +<li><a href="#_error_responses">Error responses</a></li> </ul> </li> -<li><a href="#_mail">3.2. MAIL</a> +<li><a href="#_mail">MAIL</a> <ul class="sectlevel3"> -<li><a href="#_request_3">3.2.1. Request</a></li> -<li><a href="#_success_response_3">3.2.2. Success response</a></li> -<li><a href="#_error_response_2">3.2.3. Error response</a></li> +<li><a href="#_request_3">Request</a></li> +<li><a href="#_success_response_3">Success response</a></li> +<li><a href="#_error_response_2">Error response</a></li> </ul> </li> -<li><a href="#_rcpt">3.3. RCPT</a> +<li><a href="#_rcpt">RCPT</a> <ul class="sectlevel3"> -<li><a href="#_request_4">3.3.1. Request</a></li> -<li><a href="#_success_response_4">3.3.2. Success Response</a></li> -<li><a href="#_error_response_3">3.3.3. Error Response</a></li> +<li><a href="#_request_4">Request</a></li> +<li><a href="#_success_response_4">Success Response</a></li> +<li><a href="#_error_response_3">Error Response</a></li> </ul> </li> -<li><a href="#_data">3.4. DATA</a> +<li><a href="#_data">DATA</a> <ul class="sectlevel3"> -<li><a href="#_request_5">3.4.1. Request</a></li> -<li><a href="#_success_response_5">3.4.2. Success Response</a></li> -<li><a href="#_error_responses_2">3.4.3. Error Responses</a></li> +<li><a href="#_request_5">Request</a></li> +<li><a href="#_success_response_5">Success Response</a></li> +<li><a href="#_error_responses_2">Error Responses</a></li> </ul> </li> -<li><a href="#_message_data">3.5. Message Data</a> +<li><a href="#_message_data">Message Data</a> <ul class="sectlevel3"> -<li><a href="#_request_6">3.5.1. Request</a></li> -<li><a href="#_success_response_6">3.5.2. Success Response</a></li> -<li><a href="#_error_responses_3">3.5.3. Error Responses</a></li> +<li><a href="#_request_6">Request</a></li> +<li><a href="#_success_response_6">Success Response</a></li> +<li><a href="#_error_responses_3">Error Responses</a></li> </ul> </li> -<li><a href="#_rset">3.6. RSET</a> +<li><a href="#_rset">RSET</a> <ul class="sectlevel3"> -<li><a href="#_request_7">3.6.1. Request</a></li> -<li><a href="#_success_response_7">3.6.2. Success Response</a></li> -<li><a href="#_error_responses_4">3.6.3. Error responses,</a></li> +<li><a href="#_request_7">Request</a></li> +<li><a href="#_success_response_7">Success Response</a></li> +<li><a href="#_error_responses_4">Error responses,</a></li> </ul> </li> </ul> </li> -<li><a href="#_others_commands">4. Others Commands</a> +<li><a href="#_others_commands">Others Commands</a> <ul class="sectlevel2"> -<li><a href="#_vrfy">4.1. VRFY</a> +<li><a href="#_vrfy">VRFY</a> <ul class="sectlevel3"> -<li><a href="#_request_8">4.1.1. Request</a></li> -<li><a href="#_success_response_8">4.1.2. Success Response</a></li> -<li><a href="#_error_responses_5">4.1.3. Error Responses</a></li> +<li><a href="#_request_8">Request</a></li> +<li><a href="#_success_response_8">Success Response</a></li> +<li><a href="#_error_responses_5">Error Responses</a></li> </ul> </li> -<li><a href="#_expn">4.2. EXPN</a> +<li><a href="#_expn">EXPN</a> <ul class="sectlevel3"> -<li><a href="#_request_9">4.2.1. Request</a></li> -<li><a href="#_success_response_9">4.2.2. Success Response</a></li> -<li><a href="#_error_responses_6">4.2.3. Error Responses</a></li> +<li><a href="#_request_9">Request</a></li> +<li><a href="#_success_response_9">Success Response</a></li> +<li><a href="#_error_responses_6">Error Responses</a></li> </ul> </li> -<li><a href="#_help">4.3. HELP</a> +<li><a href="#_help">HELP</a> <ul class="sectlevel3"> -<li><a href="#_request_10">4.3.1. Request</a></li> -<li><a href="#_success_responses">4.3.2. Success Responses</a></li> -<li><a href="#_error_responses_7">4.3.3. Error Responses</a></li> +<li><a href="#_request_10">Request</a></li> +<li><a href="#_success_responses">Success Responses</a></li> +<li><a href="#_error_responses_7">Error Responses</a></li> </ul> </li> -<li><a href="#_noop">4.4. NOOP</a> +<li><a href="#_noop">NOOP</a> <ul class="sectlevel3"> -<li><a href="#_request_11">4.4.1. Request</a></li> -<li><a href="#_success_response_10">4.4.2. Success Response</a></li> +<li><a href="#_request_11">Request</a></li> +<li><a href="#_success_response_10">Success Response</a></li> </ul> </li> -<li><a href="#_quit">4.5. QUIT</a> +<li><a href="#_quit">QUIT</a> <ul class="sectlevel3"> -<li><a href="#_request_12">4.5.1. Request</a></li> -<li><a href="#_success_response_11">4.5.2. Success Response</a></li> +<li><a href="#_request_12">Request</a></li> +<li><a href="#_success_response_11">Success Response</a></li> </ul> </li> </ul> </li> -<li><a href="#_extensions">5. Extensions</a></li> -<li><a href="#_glossary">6. Glossary</a></li> +<li><a href="#_extensions">Extensions</a></li> +<li><a href="#_glossary">Glossary</a></li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -137,10 +145,10 @@ as defined in <a href="https://tools.ietf.org/html/rfc5321">RFC 5321</a>.</p> </div> </div> <div class="sect1"> -<h2 id="_syntax">1. Syntax</h2> +<h2 id="_syntax">Syntax</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_format_of_request">1.1. Format of Request</h3> +<h3 id="_format_of_request">Format of Request</h3> <div class="literalblock"> <div class="content"> <pre>Command [ SP argument [ SP parameters ]] CRLF</pre> @@ -154,7 +162,7 @@ as defined in <a href="https://tools.ietf.org/html/rfc5321">RFC 5321</a>.</p> convention.</p> </div> <div class="sect3"> -<h4 id="_format_of_parameters">1.1.1. Format of Parameters</h4> +<h4 id="_format_of_parameters">Format of Parameters</h4> <div class="paragraph"> <p>The parameters is only available for MAIL and RCPT commands.</p> </div> @@ -182,7 +190,7 @@ Argument = Atom</pre> </div> </div> <div class="sect2"> -<h3 id="_format_of_response">1.2. Format of Response</h3> +<h3 id="_format_of_response">Format of Response</h3> <div class="paragraph"> <p>Every request MUST generate one reply (section 4.2).</p> </div> @@ -209,7 +217,7 @@ Argument = Atom</pre> </div> </div> <div class="sect2"> -<h3 id="_format_of_path">1.3. Format of Path</h3> +<h3 id="_format_of_path">Format of Path</h3> <div class="paragraph"> <p>There are two type of path: Reverse-path and Forward-path. Reverse-path is used as an argument on MAIL command, while Forward-path is @@ -217,9 +225,9 @@ used as an argument on RCPT command.</p> </div> <div class="literalblock"> <div class="content"> -<pre>Reverse-path = Path / "<>" +<pre>Reverse-path = Path / "<>" Forward-path = Path -Path = "<" [ A-d-l ":" ] Mailbox ">" +Path = "<" [ A-d-l ":" ] Mailbox ">" A-d-l = At-domain *( "," At-domain ) ; Note that this form, the so-called "source @@ -230,14 +238,14 @@ At-domain = "@" Domain</pre> </div> </div> <div class="paragraph"> -<p>The use of source routes (The "A-d-l") is deprecated (RFC 5321, Appendix F.2), +<p>The use of source routes (The "A-d-l") is deprecated (RFC 5321, Appendix F.2), while servers MUST be prepared to receive and handle them. Clients SHOULD NOT transmit them and this section is included in the current specification only to provide context.</p> </div> </div> <div class="sect2"> -<h3 id="_format_of_domain">1.4. Format of Domain</h3> +<h3 id="_format_of_domain">Format of Domain</h3> <div class="literalblock"> <div class="content"> <pre>Domain = sub-domain *("." sub-domain) @@ -251,7 +259,7 @@ Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig</pre> </div> </div> <div class="sect2"> -<h3 id="_format_of_mailbox">1.5. Format of Mailbox</h3> +<h3 id="_format_of_mailbox">Format of Mailbox</h3> <div class="literalblock"> <div class="content"> <pre>Mailbox = Local-part "@" ( Domain / address-literal ) @@ -293,7 +301,7 @@ String = Atom / Quoted-string</pre> <pre> atext = ALPHA / DIGIT / ; Printable US-ASCII "!" / "#" / ; characters not including "$" / "%" / ; specials. Used for atoms. - "&" / "'" / + "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / @@ -309,7 +317,7 @@ String = Atom / Quoted-string</pre> dot-atom = [CFWS] dot-atom-text [CFWS] specials = "(" / ")" / ; Special characters that do - "<" / ">" / ; not appear in atext + "<" / ">" / ; not appear in atext "[" / "]" / ":" / ";" / "@" / "\" / @@ -342,12 +350,12 @@ possible.</p> <div class="paragraph"> <p>Systems MUST NOT define mailboxes in such a way as to require the use in SMTP of non-ASCII characters (octets with the high order bit set to one) or ASCII -"control characters" (decimal value 0-31 and 127). +"control characters" (decimal value 0-31 and 127). These characters MUST NOT be used in MAIL or RCPT commands or other commands that require mailbox names.</p> </div> <div class="paragraph"> -<p>Note that the backslash, "\", is a quote character, which is used to indicate +<p>Note that the backslash, "\", is a quote character, which is used to indicate that the next character is to be used literally (instead of its normal interpretation).</p> </div> @@ -366,16 +374,16 @@ by appropriate SMTP extensions).</p> </div> </div> <div class="sect1"> -<h2 id="_session_initiation">2. Session Initiation</h2> +<h2 id="_session_initiation">Session Initiation</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_request">2.1. Request</h3> +<h3 id="_request">Request</h3> <div class="paragraph"> <p>Client open a TCP connection to SMTP server on port 25 or 587 (with STARTTLS).</p> </div> </div> <div class="sect2"> -<h3 id="_success_response">2.2. Success Response</h3> +<h3 id="_success_response">Success Response</h3> <div class="paragraph"> <p>On success, server reply with 220,</p> </div> @@ -386,7 +394,7 @@ by appropriate SMTP extensions).</p> </div> </div> <div class="sect2"> -<h3 id="_error_response">2.3. Error Response</h3> +<h3 id="_error_response">Error Response</h3> <div class="paragraph"> <p>On failure, server will reply with 554,</p> </div> @@ -404,13 +412,13 @@ by appropriate SMTP extensions).</p> <div class="paragraph"> <p>A server that reply with 554 MUST still wait for the client to send a QUIT (see Section 4.1.1.10) before closing the connection and SHOULD respond to any -intervening commands with "503 bad sequence of commands".</p> +intervening commands with "503 bad sequence of commands".</p> </div> </div> </div> </div> <div class="sect1"> -<h2 id="_mail_transaction">3. Mail Transaction</h2> +<h2 id="_mail_transaction">Mail Transaction</h2> <div class="sectionbody"> <div class="paragraph"> <p>Mail transaction constructed by four commands, in sequence order, with message @@ -436,19 +444,19 @@ data and the end of transaction,</p> </ul> </div> <div class="sect2"> -<h3 id="_heloehlo">3.1. HELO/EHLO</h3> +<h3 id="_helo_ehlo">HELO/EHLO</h3> <div class="paragraph"> <p>Server MUST support HELO.</p> </div> <div class="paragraph"> -<p>Client SHOULD start a session by EHLO. If server return "command not -recognized", client SHOULD fall-back to HELO.</p> +<p>Client SHOULD start a session by EHLO. If server return "command not +recognized", client SHOULD fall-back to HELO.</p> </div> <div class="paragraph"> <p>Client MUST issue EHLO/HELO before starting a mail transaction.</p> </div> <div class="sect3"> -<h4 id="_request_2">3.1.1. Request</h4> +<h4 id="_request_2">Request</h4> <div class="literalblock"> <div class="content"> <pre>"HELO" SP Domain CRLF @@ -461,7 +469,7 @@ recognized", client SHOULD fall-back to HELO.</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_2">3.1.2. Success response</h4> +<h4 id="_success_response_2">Success response</h4> <div class="literalblock"> <div class="content"> <pre>( "250" SP Domain [ SP ehlo-greet ] CRLF ) @@ -472,7 +480,7 @@ recognized", client SHOULD fall-back to HELO.</p> ehlo-greet = string of any characters other than CR or LF ehlo-line = ehlo-keyword *( SP ehlo-param ) ehlo-keyword = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-") -ehlo-param = any CHAR excluding <SP> and all control characters +ehlo-param = any CHAR excluding <SP> and all control characters (US-ASCII 0-31 and 127 inclusive)</pre> </div> </div> @@ -487,7 +495,7 @@ ehlo-param = any CHAR excluding <SP> and all control characters </div> </div> <div class="sect3"> -<h4 id="_error_responses">3.1.3. Error responses</h4> +<h4 id="_error_responses">Error responses</h4> <div class="ulist"> <ul> <li> @@ -504,9 +512,9 @@ ehlo-param = any CHAR excluding <SP> and all control characters </div> </div> <div class="sect2"> -<h3 id="_mail">3.2. MAIL</h3> +<h3 id="_mail">MAIL</h3> <div class="sect3"> -<h4 id="_request_3">3.2.1. Request</h4> +<h4 id="_request_3">Request</h4> <div class="literalblock"> <div class="content"> <pre>"MAIL FROM:" Reverse-path [SP Mail-parameters] CRLF</pre> @@ -524,7 +532,7 @@ extension.</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_3">3.2.2. Success response</h4> +<h4 id="_success_response_3">Success response</h4> <div class="literalblock"> <div class="content"> <pre>250 [ SP text ] CRLF</pre> @@ -532,7 +540,7 @@ extension.</p> </div> </div> <div class="sect3"> -<h4 id="_error_response_2">3.2.3. Error response</h4> +<h4 id="_error_response_2">Error response</h4> <div class="ulist"> <ul> <li> @@ -566,13 +574,13 @@ mailbox syntax incorrect)</p> </div> </div> <div class="sect2"> -<h3 id="_rcpt">3.3. RCPT</h3> +<h3 id="_rcpt">RCPT</h3> <div class="sect3"> -<h4 id="_request_4">3.3.1. Request</h4> +<h4 id="_request_4">Request</h4> <div class="literalblock"> <div class="content"> -<pre>"RCPT TO:" ( "<Postmaster@" Domain ">" - / "<Postmaster>" +<pre>"RCPT TO:" ( "<Postmaster@" Domain ">" + / "<Postmaster>" / Forward-path ) [SP Rcpt-parameters] CRLF</pre> </div> </div> @@ -594,7 +602,7 @@ service extension offered by the server in its EHLO response.</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_4">3.3.2. Success Response</h4> +<h4 id="_success_response_4">Success Response</h4> <div class="literalblock"> <div class="content"> <pre>250 [ SP text ] CRLF</pre> @@ -602,7 +610,7 @@ service extension offered by the server in its EHLO response.</p> </div> </div> <div class="sect3"> -<h4 id="_error_response_3">3.3.3. Error Response</h4> +<h4 id="_error_response_3">Error Response</h4> <div class="ulist"> <ul> <li> @@ -623,7 +631,7 @@ mailbox busy or temporarily blocked for policy reasons)</p> </li> <li> <p>550 Requested action not taken: mailbox unavailable (e.g., mailbox -not found, no access, or command rejected for policy reasons)</p> + not found, no access, or command rejected for policy reasons)</p> </li> <li> <p>551 User not local; please try <forward-path> (See Section 3.4)</p> @@ -643,9 +651,9 @@ mailbox syntax incorrect)</p> </div> </div> <div class="sect2"> -<h3 id="_data">3.4. DATA</h3> +<h3 id="_data">DATA</h3> <div class="sect3"> -<h4 id="_request_5">3.4.1. Request</h4> +<h4 id="_request_5">Request</h4> <div class="literalblock"> <div class="content"> <pre>"DATA" CRLF</pre> @@ -653,7 +661,7 @@ mailbox syntax incorrect)</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_5">3.4.2. Success Response</h4> +<h4 id="_success_response_5">Success Response</h4> <div class="literalblock"> <div class="content"> <pre>"354" [ SP String ] CRLF</pre> @@ -661,7 +669,7 @@ mailbox syntax incorrect)</p> </div> </div> <div class="sect3"> -<h4 id="_error_responses_2">3.4.3. Error Responses</h4> +<h4 id="_error_responses_2">Error Responses</h4> <div class="ulist"> <ul> <li> @@ -669,19 +677,19 @@ mailbox syntax incorrect)</p> </li> <li> <p>554 Transaction failed (Or, in the case of a connection-opening -response, "No SMTP service here")</p> +response, "No SMTP service here")</p> </li> </ul> </div> </div> </div> <div class="sect2"> -<h3 id="_message_data">3.5. Message Data</h3> +<h3 id="_message_data">Message Data</h3> <div class="paragraph"> <p>Message data MUST NOT be send unless 354 reply code is received.</p> </div> <div class="sect3"> -<h4 id="_request_6">3.5.1. Request</h4> +<h4 id="_request_6">Request</h4> <div class="literalblock"> <div class="content"> <pre>(*text) @@ -692,7 +700,7 @@ CRLF</pre> </div> </div> <div class="sect3"> -<h4 id="_success_response_6">3.5.2. Success Response</h4> +<h4 id="_success_response_6">Success Response</h4> <div class="literalblock"> <div class="content"> <pre>250 [ SP text ] CRLF</pre> @@ -700,7 +708,7 @@ CRLF</pre> </div> </div> <div class="sect3"> -<h4 id="_error_responses_3">3.5.3. Error Responses</h4> +<h4 id="_error_responses_3">Error Responses</h4> <div class="ulist"> <ul> <li> @@ -722,14 +730,14 @@ not found, no access, or command rejected for policy reasons)</p> </li> <li> <p>554 Transaction failed (Or, in the case of a connection-opening -response, "No SMTP service here")</p> +response, "No SMTP service here")</p> </li> </ul> </div> </div> </div> <div class="sect2"> -<h3 id="_rset">3.6. RSET</h3> +<h3 id="_rset">RSET</h3> <div class="paragraph"> <p>This command clear the current buffer on MAIL, RCPT, and DATA, but not the EHLO/HELO buffer.</p> @@ -739,7 +747,7 @@ EHLO/HELO buffer.</p> RSET.</p> </div> <div class="sect3"> -<h4 id="_request_7">3.6.1. Request</h4> +<h4 id="_request_7">Request</h4> <div class="literalblock"> <div class="content"> <pre>"RSET" CRLF</pre> @@ -747,7 +755,7 @@ RSET.</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_7">3.6.2. Success Response</h4> +<h4 id="_success_response_7">Success Response</h4> <div class="literalblock"> <div class="content"> <pre>"250 OK" CRLF</pre> @@ -755,7 +763,7 @@ RSET.</p> </div> </div> <div class="sect3"> -<h4 id="_error_responses_4">3.6.3. Error responses,</h4> +<h4 id="_error_responses_4">Error responses,</h4> <div class="paragraph"> <p>Not available.</p> </div> @@ -764,18 +772,18 @@ RSET.</p> </div> </div> <div class="sect1"> -<h2 id="_others_commands">4. Others Commands</h2> +<h2 id="_others_commands">Others Commands</h2> <div class="sectionbody"> <div class="paragraph"> <p>The following commands does not affect mail transaction.</p> </div> <div class="sect2"> -<h3 id="_vrfy">4.1. VRFY</h3> +<h3 id="_vrfy">VRFY</h3> <div class="paragraph"> <p>This command is used to verify the existency of user in remote server.</p> </div> <div class="sect3"> -<h4 id="_request_8">4.1.1. Request</h4> +<h4 id="_request_8">Request</h4> <div class="literalblock"> <div class="content"> <pre>"VRFY" SP String CRLF</pre> @@ -786,10 +794,10 @@ RSET.</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_8">4.1.2. Success Response</h4> +<h4 id="_success_response_8">Success Response</h4> <div class="literalblock"> <div class="content"> -<pre>250 User name <local-part@domain> +<pre>250 User name <local-part@domain> / 250 local-part@domain</pre> </div> </div> @@ -801,13 +809,13 @@ list of ambigous name,</p> <div class="content"> <pre> "553" SP "User ambiguous" CRLF / "553-" Description CRLF - 1*("553-" [ user-name ] "<" local-part@domain ">" - "553 " [ user-name ] "<" local-part@domain ">"</pre> + 1*("553-" [ user-name ] "<" local-part@domain ">" + "553 " [ user-name ] "<" local-part@domain ">"</pre> </div> </div> </div> <div class="sect3"> -<h4 id="_error_responses_5">4.1.3. Error Responses</h4> +<h4 id="_error_responses_5">Error Responses</h4> <div class="ulist"> <ul> <li> @@ -828,12 +836,12 @@ not found, no access, or command rejected for policy reasons)</p> </div> </div> <div class="sect2"> -<h3 id="_expn">4.2. EXPN</h3> +<h3 id="_expn">EXPN</h3> <div class="paragraph"> <p>Command to identify mailing-list, if success, it will return list of members.</p> </div> <div class="sect3"> -<h4 id="_request_9">4.2.1. Request</h4> +<h4 id="_request_9">Request</h4> <div class="literalblock"> <div class="content"> <pre>"EXPN" SP String CRLF</pre> @@ -841,17 +849,17 @@ not found, no access, or command rejected for policy reasons)</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_9">4.2.2. Success Response</h4> +<h4 id="_success_response_9">Success Response</h4> <div class="literalblock"> <div class="content"> <pre> "250-" mailing-list name -1*("250-" [ member-name ] "<" member-address ">" - "250 " [ member-name ] "<" member-address ">"</pre> +1*("250-" [ member-name ] "<" member-address ">" + "250 " [ member-name ] "<" member-address ">"</pre> </div> </div> </div> <div class="sect3"> -<h4 id="_error_responses_6">4.2.3. Error Responses</h4> +<h4 id="_error_responses_6">Error Responses</h4> <div class="ulist"> <ul> <li> @@ -872,7 +880,7 @@ as command line too long)</p> </div> </div> <div class="sect2"> -<h3 id="_help">4.3. HELP</h3> +<h3 id="_help">HELP</h3> <div class="paragraph"> <p>Command to query information about server command.a</p> </div> @@ -881,7 +889,7 @@ as command line too long)</p> arguments.</p> </div> <div class="sect3"> -<h4 id="_request_10">4.3.1. Request</h4> +<h4 id="_request_10">Request</h4> <div class="literalblock"> <div class="content"> <pre>"HELP" [ SP String ] CRLF</pre> @@ -889,7 +897,7 @@ arguments.</p> </div> </div> <div class="sect3"> -<h4 id="_success_responses">4.3.2. Success Responses</h4> +<h4 id="_success_responses">Success Responses</h4> <div class="ulist"> <ul> <li> @@ -904,7 +912,7 @@ only to the human user)</p> </div> </div> <div class="sect3"> -<h4 id="_error_responses_7">4.3.3. Error Responses</h4> +<h4 id="_error_responses_7">Error Responses</h4> <div class="ulist"> <ul> <li> @@ -918,9 +926,9 @@ only to the human user)</p> </div> </div> <div class="sect2"> -<h3 id="_noop">4.4. NOOP</h3> +<h3 id="_noop">NOOP</h3> <div class="sect3"> -<h4 id="_request_11">4.4.1. Request</h4> +<h4 id="_request_11">Request</h4> <div class="literalblock"> <div class="content"> <pre>"NOOP" [ SP String ] CRLF</pre> @@ -931,7 +939,7 @@ only to the human user)</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_10">4.4.2. Success Response</h4> +<h4 id="_success_response_10">Success Response</h4> <div class="ulist"> <ul> <li> @@ -942,7 +950,7 @@ only to the human user)</p> </div> </div> <div class="sect2"> -<h3 id="_quit">4.5. QUIT</h3> +<h3 id="_quit">QUIT</h3> <div class="paragraph"> <p>Command to issue closing the session.</p> </div> @@ -958,7 +966,7 @@ QUIT command, and it SHOULD wait until it receives the reply.</p> <p>Any current uncompleted mail transaction will be aborted.</p> </div> <div class="sect3"> -<h4 id="_request_12">4.5.1. Request</h4> +<h4 id="_request_12">Request</h4> <div class="literalblock"> <div class="content"> <pre>"QUIT" CRLF</pre> @@ -966,7 +974,7 @@ QUIT command, and it SHOULD wait until it receives the reply.</p> </div> </div> <div class="sect3"> -<h4 id="_success_response_11">4.5.2. Success Response</h4> +<h4 id="_success_response_11">Success Response</h4> <div class="literalblock"> <div class="content"> <pre>"221" [ SP String ] CRLF</pre> @@ -977,7 +985,7 @@ QUIT command, and it SHOULD wait until it receives the reply.</p> </div> </div> <div class="sect1"> -<h2 id="_extensions">5. Extensions</h2> +<h2 id="_extensions">Extensions</h2> <div class="sectionbody"> <div class="ulist"> <ul> @@ -996,7 +1004,7 @@ Layer Security (RFC3207)</a></p> </div> </div> <div class="sect1"> -<h2 id="_glossary">6. Glossary</h2> +<h2 id="_glossary">Glossary</h2> <div class="sectionbody"> <div class="dlist"> <dl> @@ -1012,11 +1020,16 @@ Layer Security (RFC3207)</a></p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/SPF.html b/doc/SPF.html index 33dffbe5..8bdfef10 100644 --- a/doc/SPF.html +++ b/doc/SPF.html @@ -1,120 +1,128 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<meta name="author" content="Shulhan"> -<title>Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1</title> -<link rel="stylesheet" href="./style.css"> -</head> -<body class="article"> -<div id="header"> -<h1>Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1</h1> -<div class="details"> -<span id="author" class="author">Shulhan</span><br> -<span id="email" class="email"><<a href="mailto:ms@kilabit.info">ms@kilabit.info</a>></span><br> -</div> -<div id="toc" class="toc"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1</title> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1</h1> + <div id="toc" class="toc"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> -<li><a href="#_introduction">1. Introduction</a></li> -<li><a href="#_operational_overview">2. Operational Overview</a> +<li><a href="#_introduction">Introduction</a></li> +<li><a href="#_operational_overview">Operational Overview</a> <ul class="sectlevel2"> -<li><a href="#_publishing_authorization">2.1. Publishing Authorization</a></li> -<li><a href="#_checking_authorization">2.2. Checking Authorization</a></li> -<li><a href="#_the_helo_identity">2.3. The "HELO" Identity</a></li> -<li><a href="#_the_mail_from_identity">2.4. The "MAIL FROM" Identity</a></li> -<li><a href="#_location_of_checks">2.5. Location of Checks</a></li> -<li><a href="#_results_of_evaluation">2.6. Results of Evaluation</a></li> +<li><a href="#_publishing_authorization">Publishing Authorization</a></li> +<li><a href="#_checking_authorization">Checking Authorization</a></li> +<li><a href="#_the_helo_identity">The "HELO" Identity</a></li> +<li><a href="#_the_mail_from_identity">The "MAIL FROM" Identity</a></li> +<li><a href="#_location_of_checks">Location of Checks</a></li> +<li><a href="#_results_of_evaluation">Results of Evaluation</a></li> </ul> </li> -<li><a href="#_spf_records">3. SPF Records</a> +<li><a href="#_spf_records">SPF Records</a> <ul class="sectlevel2"> -<li><a href="#_dns_resource_record">3.1. DNS Resource Record</a></li> -<li><a href="#_multiple_dns_records">3.2. Multiple DNS Records</a></li> -<li><a href="#_multiple_strings_in_a_single_dns_record">3.3. Multiple Strings in a Single DNS Record</a></li> -<li><a href="#_record_size">3.4. Record Size</a></li> -<li><a href="#_wildcard_records">3.5. Wildcard Records</a></li> +<li><a href="#_dns_resource_record">DNS Resource Record</a></li> +<li><a href="#_multiple_dns_records">Multiple DNS Records</a></li> +<li><a href="#_multiple_strings_in_a_single_dns_record">Multiple Strings in a Single DNS Record</a></li> +<li><a href="#_record_size">Record Size</a></li> +<li><a href="#_wildcard_records">Wildcard Records</a></li> </ul> </li> -<li><a href="#_the_check_host_function">4. The check_host() Function</a> +<li><a href="#_the_check_host_function">The check_host() Function</a> <ul class="sectlevel2"> -<li><a href="#_arguments">4.1. Arguments</a></li> -<li><a href="#_results">4.2. Results</a></li> -<li><a href="#_initial_processing">4.3. Initial Processing</a></li> -<li><a href="#_record_lookup">4.4. Record Lookup</a></li> -<li><a href="#_selecting_records">4.5. Selecting Records</a></li> -<li><a href="#_record_evaluation">4.6. Record Evaluation</a></li> -<li><a href="#_default_result">4.7. Default Result</a></li> -<li><a href="#_domain_specification">4.8. Domain Specification</a></li> +<li><a href="#_arguments">Arguments</a></li> +<li><a href="#_results">Results</a></li> +<li><a href="#_initial_processing">Initial Processing</a></li> +<li><a href="#_record_lookup">Record Lookup</a></li> +<li><a href="#_selecting_records">Selecting Records</a></li> +<li><a href="#_record_evaluation">Record Evaluation</a></li> +<li><a href="#_default_result">Default Result</a></li> +<li><a href="#_domain_specification">Domain Specification</a></li> </ul> </li> -<li><a href="#_mechanism_definitions">5. Mechanism Definitions</a> +<li><a href="#_mechanism_definitions">Mechanism Definitions</a> <ul class="sectlevel2"> -<li><a href="#_all">5.1. "all"</a></li> -<li><a href="#_include">5.2. "include"</a></li> -<li><a href="#_a">5.3. "a"</a></li> -<li><a href="#_mx">5.4. "mx"</a></li> -<li><a href="#_mechanism_ptr">5.5. "ptr" (do not use)</a></li> -<li><a href="#_ip4_and_ip6">5.6. "ip4" and "ip6"</a></li> -<li><a href="#_exist">5.7. "exist"</a></li> +<li><a href="#__all">"all"</a></li> +<li><a href="#__include">"include"</a></li> +<li><a href="#__a">"a"</a></li> +<li><a href="#__mx">"mx"</a></li> +<li><a href="#_mechanism_ptr">"ptr" (do not use)</a></li> +<li><a href="#__ip4_and_ip6">"ip4" and "ip6"</a></li> +<li><a href="#__exist">"exist"</a></li> </ul> </li> -<li><a href="#_modifier_definitions">6. Modifier Definitions</a> +<li><a href="#_modifier_definitions">Modifier Definitions</a> <ul class="sectlevel2"> -<li><a href="#_redirect_redirected_query">6.1. redirect: Redirected Query</a></li> -<li><a href="#_exp_explanation">6.2. exp: Explanation</a></li> +<li><a href="#_redirect_redirected_query">redirect: Redirected Query</a></li> +<li><a href="#_exp_explanation">exp: Explanation</a></li> </ul> </li> -<li><a href="#_macros">7. Macros</a> +<li><a href="#_macros">Macros</a> <ul class="sectlevel2"> -<li><a href="#_formal_specification">7.1. Formal Specification</a></li> -<li><a href="#_macro_definitions">7.2. Macro Definitions</a></li> -<li><a href="#_macro_processing_details">7.3. Macro Processing Details</a></li> -<li><a href="#_expansion_examples">7.4. Expansion Examples</a></li> +<li><a href="#_formal_specification">Formal Specification</a></li> +<li><a href="#_macro_definitions">Macro Definitions</a></li> +<li><a href="#_macro_processing_details">Macro Processing Details</a></li> +<li><a href="#_expansion_examples">Expansion Examples</a></li> </ul> </li> -<li><a href="#_result_handling">8. Result Handling</a> +<li><a href="#_result_handling">Result Handling</a> <ul class="sectlevel2"> -<li><a href="#_none">8.1. None</a></li> -<li><a href="#_neutral">8.2. Neutral</a></li> -<li><a href="#_pass">8.3. Pass</a></li> -<li><a href="#_fail">8.4. Fail</a></li> -<li><a href="#_softfail">8.5. Softfail</a></li> -<li><a href="#_temperror">8.6. Temperror</a></li> -<li><a href="#_permerror">8.7. Permerror</a></li> +<li><a href="#_none">None</a></li> +<li><a href="#_neutral">Neutral</a></li> +<li><a href="#_pass">Pass</a></li> +<li><a href="#_fail">Fail</a></li> +<li><a href="#_softfail">Softfail</a></li> +<li><a href="#_temperror">Temperror</a></li> +<li><a href="#_permerror">Permerror</a></li> </ul> </li> -<li><a href="#_recording_the_result">9. Recording the Result</a> +<li><a href="#_recording_the_result">Recording the Result</a> <ul class="sectlevel2"> -<li><a href="#_the_received_spf_header_field">9.1. The Received-SPF Header Field</a></li> -<li><a href="#_spf_results_in_the_authentication_results_header_field">9.2. SPF Results in the Authentication-Results Header Field</a></li> +<li><a href="#_the_received_spf_header_field">The Received-SPF Header Field</a></li> +<li><a href="#_spf_results_in_the_authentication_results_header_field">SPF Results in the Authentication-Results Header Field</a></li> </ul> </li> -<li><a href="#_effects_on_infrastructure">10. Effects on Infrastructure</a> +<li><a href="#_effects_on_infrastructure">Effects on Infrastructure</a> <ul class="sectlevel2"> -<li><a href="#_sending_domains">10.1. Sending Domains</a></li> -<li><a href="#_receivers">10.2. Receivers</a></li> -<li><a href="#_mediator">10.3. Mediator</a></li> +<li><a href="#_sending_domains">Sending Domains</a></li> +<li><a href="#_receivers">Receivers</a></li> +<li><a href="#_mediator">Mediator</a></li> </ul> </li> -<li><a href="#_security_considerations">11. Security Considerations</a> +<li><a href="#_security_considerations">Security Considerations</a> <ul class="sectlevel2"> -<li><a href="#_processing_limits">11.1. Processing Limits</a></li> -<li><a href="#_spf_authorized_email_may_contain_other_false_identities">11.2. SPF-Authorized Email May Contain Other False Identities</a></li> -<li><a href="#_spoofed_dns_and_ip_data">11.3. Spoofed DNS and IP Data</a></li> -<li><a href="#_cross_user_forgery">11.4. Cross-User Forgery</a></li> -<li><a href="#_untrusted_information_sources">11.5. Untrusted Information Sources</a></li> -<li><a href="#_privacy_exposure">11.6. Privacy Exposure</a></li> -<li><a href="#_delivering_mail_producing_a_fail_result">11.7. Delivering Mail Producing a "Fail" Result</a></li> +<li><a href="#_processing_limits">Processing Limits</a></li> +<li><a href="#_spf_authorized_email_may_contain_other_false_identities">SPF-Authorized Email May Contain Other False Identities</a></li> +<li><a href="#_spoofed_dns_and_ip_data">Spoofed DNS and IP Data</a></li> +<li><a href="#_cross_user_forgery">Cross-User Forgery</a></li> +<li><a href="#_untrusted_information_sources">Untrusted Information Sources</a></li> +<li><a href="#_privacy_exposure">Privacy Exposure</a></li> +<li><a href="#_delivering_mail_producing_a_fail_result">Delivering Mail Producing a "Fail" Result</a></li> </ul> </li> </ul> </div> -</div> -<div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> @@ -128,28 +136,28 @@ The content of this document are merged with errata that are reported before </div> </div> <div class="sect1"> -<h2 id="_introduction"><a class="anchor" href="#_introduction"></a>1. Introduction</h2> +<h2 id="_introduction">Introduction</h2> <div class="sectionbody"> <div class="paragraph"> <p>This document defines a protocol by which ADministrative Management Domains -(ADMD) can authorize hosts to use their domain names in the "MAIL FROM" or -"HELO" identities. +(ADMD) can authorize hosts to use their domain names in the "MAIL FROM" or +"HELO" identities. Compliant ADMDs publish Sender Policy Framework (SPF) records in the DNS specifying which hosts are permitted to use their names, and compliant mail receivers use the published SPF records to test the authorization of sending -Mail Transfer Agents (MTAs) using a given "HELO" or "MAIL FROM" identity +Mail Transfer Agents (MTAs) using a given "HELO" or "MAIL FROM" identity during a mail transaction.</p> </div> </div> </div> <div class="sect1"> -<h2 id="_operational_overview"><a class="anchor" href="#_operational_overview"></a>2. Operational Overview</h2> +<h2 id="_operational_overview">Operational Overview</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_publishing_authorization"><a class="anchor" href="#_publishing_authorization"></a>2.1. Publishing Authorization</h3> +<h3 id="_publishing_authorization">Publishing Authorization</h3> <div class="paragraph"> <p>An SPF-compliant domain publishes valid SPF records to authorize the use of -the relevant domain names in the "HELO" and "MAIL FROM" identities by the MTAs +the relevant domain names in the "HELO" and "MAIL FROM" identities by the MTAs specified therein.</p> </div> <div class="paragraph"> @@ -157,7 +165,7 @@ specified therein.</p> and negative (source is not authorized) determinations. If ADMDs choose to publish SPF records and want to support receivers making negative authorization determinations, it is necessary for them to publish -records that end in "-all", or redirect to other records that do; +records that end in "-all", or redirect to other records that do; otherwise, no definitive determination of authorization can be made.</p> </div> <div class="paragraph"> @@ -167,7 +175,7 @@ email can reasonably expect to have been checked.</p> </div> </div> <div class="sect2"> -<h3 id="_checking_authorization"><a class="anchor" href="#_checking_authorization"></a>2.2. Checking Authorization</h3> +<h3 id="_checking_authorization">Checking Authorization</h3> <div class="paragraph"> <p>A mail receiver can perform a set of SPF checks for each mail message it receives. @@ -179,7 +187,7 @@ available and reliable.</p> <p>Without explicit approval of the publishing ADMD, checking other identities against SPF version 1 records is NOT RECOMMENDED because there are cases that are known to give incorrect results. -For example, almost all mailing lists rewrite the "MAIL FROM" identity, but +For example, almost all mailing lists rewrite the "MAIL FROM" identity, but some do not change any other identities in the message. Documents that define other identities will have to define the method for explicit approval.</p> @@ -189,9 +197,9 @@ explicit approval.</p> </div> <div class="paragraph"> <p>Although invalid, malformed, or non-existent domains cause SPF checks to -return "none" because no SPF record can be found, it has long been the policy +return "none" because no SPF record can be found, it has long been the policy of many MTAs to reject email from such domains, especially in the case of -invalid "MAIL FROM". +invalid "MAIL FROM". Rejecting email will prevent one method of circumventing of SPF records.</p> </div> <div class="paragraph"> @@ -203,40 +211,40 @@ These archaic features have been maliciously used to bypass security systems.</p </div> </div> <div class="sect2"> -<h3 id="_the_helo_identity"><a class="anchor" href="#_the_helo_identity"></a>2.3. The "HELO" Identity</h3> +<h3 id="_the_helo_identity">The "HELO" Identity</h3> <div class="paragraph"> -<p>It is RECOMMENDED that SPF verifiers not only check the "MAIL FROM" identity -but also separately check the "HELO" identity by applying the check_host() -function (Section 4) to the "HELO" identity as the <sender>. +<p>It is RECOMMENDED that SPF verifiers not only check the "MAIL FROM" identity +but also separately check the "HELO" identity by applying the check_host() +function (Section 4) to the "HELO" identity as the <sender>. If a conclusive determination about the message can be made based on a check -of "HELO", then the use of DNS resources to process the typically more complex -"MAIL FROM" can be avoided. -Additionally, since SPF records published for "HELO" identities refer to a +of "HELO", then the use of DNS resources to process the typically more complex +"MAIL FROM" can be avoided. +Additionally, since SPF records published for "HELO" identities refer to a single host, when available, they are a very reliable source of host authorization status. -Checking "HELO" before "MAIL FROM" is the RECOMMENDED sequence if both are +Checking "HELO" before "MAIL FROM" is the RECOMMENDED sequence if both are checked.</p> </div> <div class="paragraph"> -<p>This SPF check can only be performed when the "HELO" string is a valid, +<p>This SPF check can only be performed when the "HELO" string is a valid, multi-label domain name.</p> </div> </div> <div class="sect2"> -<h3 id="_the_mail_from_identity"><a class="anchor" href="#_the_mail_from_identity"></a>2.4. The "MAIL FROM" Identity</h3> +<h3 id="_the_mail_from_identity">The "MAIL FROM" Identity</h3> <div class="paragraph"> -<p>SPF verifiers MUST check the "MAIL FROM" identity if a "HELO" check either has +<p>SPF verifiers MUST check the "MAIL FROM" identity if a "HELO" check either has not been performed or has not reached a definitive policy result by applying -the check_host() function to the "MAIL FROM" identity as the <sender>.</p> +the check_host() function to the "MAIL FROM" identity as the <sender>.</p> </div> <div class="paragraph"> -<p>If the reverse-path is null, this document defines the "MAIL FROM" identity to -be the mailbox composed of the local-part "postmaster" and the "HELO" identity +<p>If the reverse-path is null, this document defines the "MAIL FROM" identity to +be the mailbox composed of the local-part "postmaster" and the "HELO" identity (which might or might not have been checked separately before).</p> </div> </div> <div class="sect2"> -<h3 id="_location_of_checks"><a class="anchor" href="#_location_of_checks"></a>2.5. Location of Checks</h3> +<h3 id="_location_of_checks">Location of Checks</h3> <div class="paragraph"> <p>The authorization check is performed during the SMTP transaction at the time of the MAIL command, and uses the MAIL FROM value and the client IP address. @@ -247,25 +255,25 @@ such as the following:</p> <ul> <li> <p>It might be difficult to accurately extract the required information from -potentially deceptive headers.</p> + potentially deceptive headers.</p> </li> <li> -<p>Legitimate email might fail the authorization check because the sender’s -policy has since changed.</p> +<p>Legitimate email might fail the authorization check because the sender's + policy has since changed.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_results_of_evaluation"><a class="anchor" href="#_results_of_evaluation"></a>2.6. Results of Evaluation</h3> +<h3 id="_results_of_evaluation">Results of Evaluation</h3> <div class="paragraph"> -<p>Moved to <a href="#_results">section 4.2</a>.</p> +<p>Moved to <a href="##_results">section 4.2</a>.</p> </div> </div> </div> </div> <div class="sect1"> -<h2 id="_spf_records"><a class="anchor" href="#_spf_records"></a>3. SPF Records</h2> +<h2 id="_spf_records">SPF Records</h2> <div class="sectionbody"> <div class="paragraph"> <p>The SPF record is expressed as a single string of text found in the RDATA of a @@ -273,7 +281,7 @@ single DNS TXT resource record; multiple SPF records are not permitted for the same owner name.</p> </div> <div class="sect2"> -<h3 id="_dns_resource_record"><a class="anchor" href="#_dns_resource_record"></a>3.1. DNS Resource Record</h3> +<h3 id="_dns_resource_record">DNS Resource Record</h3> <div class="paragraph"> <p>SPF records MUST be published as a DNS TXT (type 16) Resource Record (RR) only. @@ -281,14 +289,14 @@ The character content of the record is encoded as [US-ASCII].</p> </div> </div> <div class="sect2"> -<h3 id="_multiple_dns_records"><a class="anchor" href="#_multiple_dns_records"></a>3.2. Multiple DNS Records</h3> +<h3 id="_multiple_dns_records">Multiple DNS Records</h3> <div class="paragraph"> <p>A domain name MUST NOT have multiple records that would cause an authorization check to select more than one record.</p> </div> </div> <div class="sect2"> -<h3 id="_multiple_strings_in_a_single_dns_record"><a class="anchor" href="#_multiple_strings_in_a_single_dns_record"></a>3.3. Multiple Strings in a Single DNS Record</h3> +<h3 id="_multiple_strings_in_a_single_dns_record">Multiple Strings in a Single DNS Record</h3> <div class="paragraph"> <p>If a published record contains multiple character-strings, then the record MUST be treated as if those strings are concatenated together without adding @@ -297,7 +305,7 @@ For example:</p> </div> <div class="listingblock"> <div class="content"> -<pre>IN TXT "v=spf1 .... first" "second string..."</pre> +<pre>IN TXT "v=spf1 .... first" "second string..."</pre> </div> </div> <div class="paragraph"> @@ -305,12 +313,12 @@ For example:</p> </div> <div class="listingblock"> <div class="content"> -<pre>IN TXT "v=spf1 .... firstsecond string..."</pre> +<pre>IN TXT "v=spf1 .... firstsecond string..."</pre> </div> </div> </div> <div class="sect2"> -<h3 id="_record_size"><a class="anchor" href="#_record_size"></a>3.4. Record Size</h3> +<h3 id="_record_size">Record Size</h3> <div class="paragraph"> <p>If the size of the DNS message, the combined length of the DNS name and the text of all the records of a given type is under 450 octets, then DNS answers @@ -328,7 +336,7 @@ evaluated to fit in a single 512-octet UDP packet.</p> </div> </div> <div class="sect2"> -<h3 id="_wildcard_records"><a class="anchor" href="#_wildcard_records"></a>3.5. Wildcard Records</h3> +<h3 id="_wildcard_records">Wildcard Records</h3> <div class="paragraph"> <p>Use of wildcard records for publishing is discouraged, and care has to be taken if they are used.</p> @@ -342,7 +350,7 @@ in order to cover all domains in use in outgoing mail.</p> </div> </div> <div class="sect1"> -<h2 id="_the_check_host_function"><a class="anchor" href="#_the_check_host_function"></a>4. The check_host() Function</h2> +<h2 id="_the_check_host_function">The check_host() Function</h2> <div class="sectionbody"> <div class="paragraph"> <p>The <code>check_host()</code> function fetches SPF records, parses them, and @@ -352,7 +360,7 @@ Receiving ADMDs that perform this check MUST correctly evaluate the <code>check_host()</code> function as described here.</p> </div> <div class="sect2"> -<h3 id="_arguments"><a class="anchor" href="#_arguments"></a>4.1. Arguments</h3> +<h3 id="_arguments">Arguments</h3> <div class="paragraph"> <p>The <code>check_host()</code> function takes these arguments:</p> </div> @@ -360,21 +368,21 @@ Receiving ADMDs that perform this check MUST correctly evaluate the <ul> <li> <p><code><ip></code>: the IP address of the SMTP client that is emitting the mail, either -IPv4 or IPv6.</p> + IPv4 or IPv6.</p> </li> <li> <p><code><domain></code>: the domain that provides the sought-after authorization -information; initially, the domain portion of the "MAIL FROM" or "HELO" -identity.</p> + information; initially, the domain portion of the "MAIL FROM" or "HELO" + identity.</p> </li> <li> -<p><code><sender></code>: the "MAIL FROM" or "HELO" identity.</p> +<p><code><sender></code>: the "MAIL FROM" or "HELO" identity.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_results"><a class="anchor" href="#_results"></a>4.2. Results</h3> +<h3 id="_results">Results</h3> <div class="paragraph"> <p>This section enumerates and briefly defines the possible outputs of <code>check_host()</code> function.</p> @@ -382,12 +390,12 @@ identity.</p> <div class="ulist"> <ul> <li> -<p>"none": means either,</p> +<p>"none": means either,</p> <div class="ulist"> <ul> <li> <p>no syntactically valid DNS domain name was extracted from the SMTP session -that could be used as the one to be authorized, or</p> + that could be used as the one to be authorized, or</p> </li> <li> <p>no SPF records were retrieved from the DNS.</p> @@ -396,52 +404,52 @@ that could be used as the one to be authorized, or</p> </div> </li> <li> -<p>"neutral": means the ADMD has explicitly stated that it is not asserting -whether the IP address is authorized.</p> +<p>"neutral": means the ADMD has explicitly stated that it is not asserting + whether the IP address is authorized.</p> </li> <li> -<p>"pass": an explicit statement that the client is authorized to inject mail -with the given identity.</p> +<p>"pass": an explicit statement that the client is authorized to inject mail + with the given identity.</p> </li> <li> -<p>"fail": an explicit statement that the client is not authorized to use the -domain in the given identity.</p> +<p>"fail": an explicit statement that the client is not authorized to use the + domain in the given identity.</p> </li> <li> -<p>"softfail": a weak statement by the publishing ADMD that the host is -probably not authorized. -It has not published a stronger, more definitive policy that results in a -"fail".</p> +<p>"softfail": a weak statement by the publishing ADMD that the host is + probably not authorized. + It has not published a stronger, more definitive policy that results in a + "fail".</p> </li> <li> -<p>"temperror": the SPF verifier encountered a transient (generally DNS) -error while performing the check. -A later retry may succeed without further DNS operator action.</p> +<p>"temperror": the SPF verifier encountered a transient (generally DNS) + error while performing the check. + A later retry may succeed without further DNS operator action.</p> </li> <li> -<p>"permerror": the domain’s published records could not be correctly -interpreted. -This signals an error condition that definitely requires DNS operator -intervention to be resolved.</p> +<p>"permerror": the domain's published records could not be correctly + interpreted. + This signals an error condition that definitely requires DNS operator + intervention to be resolved.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_initial_processing"><a class="anchor" href="#_initial_processing"></a>4.3. Initial Processing</h3> +<h3 id="_initial_processing">Initial Processing</h3> <div class="paragraph"> <p>If the <domain> is malformed (e.g., label longer than 63 characters, zero-length label not at the end, etc.) or is not a multi-label domain name, -or if the DNS lookup returns "Name Error" (RCODE 3, also known as "NXDOMAIN" -[RFC2308]), check_host() immediately returns the result "none".</p> +or if the DNS lookup returns "Name Error" (RCODE 3, also known as "NXDOMAIN" +[RFC2308]), check_host() immediately returns the result "none".</p> </div> <div class="paragraph"> -<p>If the <sender> has no local-part, substitute the string "postmaster" for the +<p>If the <sender> has no local-part, substitute the string "postmaster" for the local-part.</p> </div> </div> <div class="sect2"> -<h3 id="_record_lookup"><a class="anchor" href="#_record_lookup"></a>4.4. Record Lookup</h3> +<h3 id="_record_lookup">Record Lookup</h3> <div class="paragraph"> <p>A DNS query needs to be made for the <domain> name, querying for type TXT only.</p> @@ -449,38 +457,38 @@ only.</p> <div class="paragraph"> <p>If the DNS lookup returns a server failure (RCODE 2) or some other error (RCODE other than 0 or 3), or if the lookup times out, then <code>check_host()</code> -terminates immediately with the result "temperror".</p> +terminates immediately with the result "temperror".</p> </div> </div> <div class="sect2"> -<h3 id="_selecting_records"><a class="anchor" href="#_selecting_records"></a>4.5. Selecting Records</h3> +<h3 id="_selecting_records">Selecting Records</h3> <div class="paragraph"> <p>Records begin with a version section:</p> </div> <div class="listingblock"> <div class="content"> <pre>record = version terms *SP -version = "v=spf1"</pre> +version = "v=spf1"</pre> </div> </div> <div class="paragraph"> <p>If the resultant record set includes no records, <code>check_host()</code> produces the -"none" result. +"none" result. If the resultant record set includes more than one record, <code>check_host()</code> -produces the "permerror" result.</p> +produces the "permerror" result.</p> </div> </div> <div class="sect2"> -<h3 id="_record_evaluation"><a class="anchor" href="#_record_evaluation"></a>4.6. Record Evaluation</h3> +<h3 id="_record_evaluation">Record Evaluation</h3> <div class="paragraph"> <p>The <code>check_host()</code> function parses and interprets the SPF record to find a result for the current test. if there are any syntax errors anywhere in the record, <code>check_host()</code> returns -immediately with the result "permerror", without further interpretation or +immediately with the result "permerror", without further interpretation or evaluation.</p> </div> <div class="sect3"> -<h4 id="_term_evaluation"><a class="anchor" href="#_term_evaluation"></a>4.6.1. Term Evaluation</h4> +<h4 id="_term_evaluation">Term Evaluation</h4> <div class="paragraph"> <p>There are two types of terms: mechanisms and modifiers.</p> </div> @@ -489,32 +497,32 @@ evaluation.</p> <pre>terms = *( 1*SP ( directive / modifier ) ) directive = [ qualifier ] mechanism -qualifier = "+" / "-" / "?" / "~" +qualifier = "+" / "-" / "?" / "~" mechanism = ( all / include / a / mx / ptr / ip4 / ip6 / exists ) modifier = redirect / explanation / unknown-modifier -unknown-modifier = name "=" macro-string +unknown-modifier = name "=" macro-string ; where name is not any known modifier -name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )</pre> +name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )</pre> </div> </div> <div class="paragraph"> -<p>Most mechanisms allow a ":" or "/" character after the name.</p> +<p>Most mechanisms allow a ":" or "/" character after the name.</p> </div> <div class="paragraph"> -<p>Modifiers always contain an equals ('=') character immediately after the name, -and before any ":" or "/" characters that might be part of the macro-string.</p> +<p>Modifiers always contain an equals ('=') character immediately after the name, +and before any ":" or "/" characters that might be part of the macro-string.</p> </div> <div class="paragraph"> -<p>Terms that do not contain any of "=", ":", or "/" are mechanisms.</p> +<p>Terms that do not contain any of "=", ":", or "/" are mechanisms.</p> </div> <div class="paragraph"> <p>Mechanism and modifier names are case-insensitive.</p> </div> </div> <div class="sect3"> -<h4 id="_mechanisms"><a class="anchor" href="#_mechanisms"></a>4.6.2. Mechanisms</h4> +<h4 id="_mechanisms">Mechanisms</h4> <div class="paragraph"> <p>Each mechanism is considered in turn from left to right. If there are no more mechanisms, the result is the default result.</p> @@ -536,64 +544,64 @@ are as follows:</p> </div> <div class="listingblock"> <div class="content"> -<pre>"+" pass -"-" fail -"~" softfail -"?" neutral</pre> +<pre>"+" pass +"-" fail +"~" softfail +"?" neutral</pre> </div> </div> <div class="paragraph"> -<p>The qualifier is optional and defaults to "+".</p> +<p>The qualifier is optional and defaults to "+".</p> </div> <div class="paragraph"> -<p>When a mechanism matches and the qualifier is "-", then a "fail" result is +<p>When a mechanism matches and the qualifier is "-", then a "fail" result is returned.</p> </div> </div> <div class="sect3"> -<h4 id="_modifiers"><a class="anchor" href="#_modifiers"></a>4.6.3. Modifiers</h4> +<h4 id="_modifiers">Modifiers</h4> <div class="paragraph"> <p>Modifiers are not mechanisms. They do not return match or not-match. Instead, they provide additional information. Although modifiers do not directly affect the evaluation of the record, the -"redirect" modifier has an effect after all the mechanisms have been +"redirect" modifier has an effect after all the mechanisms have been evaluated.</p> </div> </div> <div class="sect3"> -<h4 id="_dns_lookup_limits"><a class="anchor" href="#_dns_lookup_limits"></a>4.6.4. DNS Lookup Limits</h4> +<h4 id="_dns_lookup_limits">DNS Lookup Limits</h4> <div class="paragraph"> -<p>The following terms cause DNS queries: the "include", "a", "mx", "ptr", and -"exists" mechanisms, and the "redirect" modifier.</p> +<p>The following terms cause DNS queries: the "include", "a", "mx", "ptr", and +"exists" mechanisms, and the "redirect" modifier.</p> </div> <div class="paragraph"> <p>SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation, to avoid unreasonable load on the DNS. -If this limit is exceeded, the implementation MUST return "permerror".</p> +If this limit is exceeded, the implementation MUST return "permerror".</p> </div> <div class="paragraph"> -<p>The other terms — the "all", "ip4", and "ip6" mechanisms, and the "exp" -modifier — do not cause DNS queries at the time of SPF evaluation (the -"exp" modifier only causes a lookup at a later time), and their use is not +<p>The other terms -- the "all", "ip4", and "ip6" mechanisms, and the "exp" +modifier -- do not cause DNS queries at the time of SPF evaluation (the +"exp" modifier only causes a lookup at a later time), and their use is not subject to this limit.</p> </div> <div class="paragraph"> -<p>When evaluating the "mx" mechanism, the number of "MX" resource records +<p>When evaluating the "mx" mechanism, the number of "MX" resource records queried is included in the overall limit of 10 mechanisms/modifiers that cause DNS lookups as described above. -In addition to that limit, the evaluation of each "MX" record MUST NOT result -in querying more than 10 address records — either "A" or "AAAA" resource +In addition to that limit, the evaluation of each "MX" record MUST NOT result +in querying more than 10 address records -- either "A" or "AAAA" resource records. -If this limit is exceeded, the "mx" mechanism MUST produce a "permerror" +If this limit is exceeded, the "mx" mechanism MUST produce a "permerror" result.</p> </div> <div class="paragraph"> -<p>When evaluating the "ptr" mechanism or the %{p} macro, the number of "PTR" +<p>When evaluating the "ptr" mechanism or the %{p} macro, the number of "PTR" resource records queried is included in the overall limit of 10 mechanisms/modifiers that cause DNS lookups as described above. -In addition to that limit, the evaluation of each "PTR" record MUST NOT result -in querying more than 10 address records — either "A" or "AAAA" resource +In addition to that limit, the evaluation of each "PTR" record MUST NOT result +in querying more than 10 address records -- either "A" or "AAAA" resource records. If this limit is exceeded, all records other than the first 10 MUST be ignored.</p> @@ -601,33 +609,33 @@ ignored.</p> <div class="paragraph"> <p>The <code>check_host()</code> elapsed time SHOULD have limited to least 20 seconds. If such a limit is exceeded, the result of authorization SHOULD be -"temperror".</p> +"temperror".</p> </div> <div class="paragraph"> -<p>There may be cases where it is useful to limit the number of "terms" for which +<p>There may be cases where it is useful to limit the number of "terms" for which DNS queries return either a positive answer (RCODE 0) with an answer count of -0, or a "Name Error" (RCODE 3) answer. -These are sometimes collectively referred to as "void lookups". -SPF implementations SHOULD limit "void lookups" to two. +0, or a "Name Error" (RCODE 3) answer. +These are sometimes collectively referred to as "void lookups". +SPF implementations SHOULD limit "void lookups" to two. An implementation MAY choose to make such a limit configurable. In this case, a default of two is RECOMMENDED. -Exceeding the limit produces a "permerror" result.</p> +Exceeding the limit produces a "permerror" result.</p> </div> </div> </div> <div class="sect2"> -<h3 id="_default_result"><a class="anchor" href="#_default_result"></a>4.7. Default Result</h3> +<h3 id="_default_result">Default Result</h3> <div class="paragraph"> -<p>If none of the mechanisms match and there is no "redirect" modifier, then the -check_host() returns a result of "neutral", just as if "?all" were specified +<p>If none of the mechanisms match and there is no "redirect" modifier, then the +check_host() returns a result of "neutral", just as if "?all" were specified as the last directive.</p> </div> <div class="paragraph"> -<p>If there is a "redirect" modifier, check_host() proceeds as defined in Section +<p>If there is a "redirect" modifier, check_host() proceeds as defined in Section 6.1.</p> </div> <div class="paragraph"> -<p>It is better to use either a "redirect" modifier or an "all" mechanism to +<p>It is better to use either a "redirect" modifier or an "all" mechanism to explicitly terminate processing. For example:</p> </div> @@ -646,7 +654,7 @@ For example:</p> </div> </div> <div class="sect2"> -<h3 id="_domain_specification"><a class="anchor" href="#_domain_specification"></a>4.8. Domain Specification</h3> +<h3 id="_domain_specification">Domain Specification</h3> <div class="paragraph"> <p>The <domain-spec> string is subject to macro expansion (see Section 7). The resulting string is the common presentation form of a fully qualified DNS @@ -657,23 +665,23 @@ This domain is called the <target-name> in the rest of this document.</p> <p>For several mechanisms, the <domain-spec> is optional. If it is not provided, the <domain> from the check_host() arguments (see Section 4.1) is used as the <target-name>. -"domain" and <domain-spec> are syntactically identical after macro expansion. -"domain" is an input value for check_host(), while <domain-spec> is computed +"domain" and <domain-spec> are syntactically identical after macro expansion. +"domain" is an input value for check_host(), while <domain-spec> is computed by check_host().</p> </div> <div class="paragraph"> <p>The result of evaluating check_host() with a syntactically invalid domain is undefined. -Examples include names with empty labels, such as "foo..example.com", and +Examples include names with empty labels, such as "foo..example.com", and labels that are longer than 63 characters. Some implementations choose to treat such errors as not-match and therefore -ignore such names, while others return a "permerror" exception.</p> +ignore such names, while others return a "permerror" exception.</p> </div> </div> </div> </div> <div class="sect1"> -<h2 id="_mechanism_definitions"><a class="anchor" href="#_mechanism_definitions"></a>5. Mechanism Definitions</h2> +<h2 id="_mechanism_definitions">Mechanism Definitions</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section defines two types of mechanisms: basic language framework @@ -719,31 +727,31 @@ high-order bits of <ip> and the IP address are compared for equality.</p> </div> <div class="paragraph"> <p>When any mechanism fetches host addresses to compare with <ip>, when <ip> is -an IPv4, "A" records are fetched; when <ip> is an IPv6 address, "AAAA" records +an IPv4, "A" records are fetched; when <ip> is an IPv6 address, "AAAA" records are fetched. -SPF implementations on IPv6 servers need to handle both "AAAA" and "A" +SPF implementations on IPv6 servers need to handle both "AAAA" and "A" records, for clients on IPv4-mapped IPv6 addresses [RFC4291]. -IPv4 <ip> addresses are only listed in an SPF record using the "ip4" +IPv4 <ip> addresses are only listed in an SPF record using the "ip4" mechanism.</p> </div> <div class="paragraph"> <p>Several mechanisms rely on information fetched from the DNS. For these DNS queries, except where noted, if the DNS server returns an error (RCODE other than 0 or 3) or the query times out, the mechanism stops and the -topmost check_host() returns "temperror". -If the server returns "Name Error" (RCODE 3), then evaluation of the mechanism +topmost check_host() returns "temperror". +If the server returns "Name Error" (RCODE 3), then evaluation of the mechanism continues as if the server returned no error (RCODE 0) and zero answer records.</p> </div> <div class="sect2"> -<h3 id="_all"><a class="anchor" href="#_all"></a>5.1. "all"</h3> +<h3 id="__all">"all"</h3> <div class="listingblock"> <div class="content"> -<pre>all = "all"</pre> +<pre>all = "all"</pre> </div> </div> <div class="paragraph"> -<p>The "all" mechanism is a test that always matches. +<p>The "all" mechanism is a test that always matches. It is used as the rightmost mechanism in a record to provide an explicit default. For example:</p> @@ -754,22 +762,22 @@ For example:</p> </div> </div> <div class="paragraph"> -<p>Mechanisms after "all" will never be tested and MUST be ignored.</p> +<p>Mechanisms after "all" will never be tested and MUST be ignored.</p> </div> <div class="paragraph"> -<p>Any "redirect" modifier MUST be ignored when there is an "all" mechanism in +<p>Any "redirect" modifier MUST be ignored when there is an "all" mechanism in the record, regardless of the relative ordering of the terms.</p> </div> </div> <div class="sect2"> -<h3 id="_include"><a class="anchor" href="#_include"></a>5.2. "include"</h3> +<h3 id="__include">"include"</h3> <div class="listingblock"> <div class="content"> -<pre>include = "include" ":" domain-spec</pre> +<pre>include = "include" ":" domain-spec</pre> </div> </div> <div class="paragraph"> -<p>The "include" mechanism triggers a recursive evaluation of <code>check_host()</code>.</p> +<p>The "include" mechanism triggers a recursive evaluation of <code>check_host()</code>.</p> </div> <div class="olist arabic"> <ol class="arabic"> @@ -778,43 +786,43 @@ the record, regardless of the relative ordering of the terms.</p> </li> <li> <p><code>check_host()</code> is evaluated with the resulting string as the <code><domain></code>. -The <code><ip></code> and <code><sender></code> arguments remain the same as in the current -evaluation of <code>check_host()</code>.</p> + The <code><ip></code> and <code><sender></code> arguments remain the same as in the current + evaluation of <code>check_host()</code>.</p> </li> <li> <p>The recursive evaluation returns match, not-match, or an error.</p> </li> <li> -<p>If it returns match, then the appropriate result for the "include" -mechanism is used (e.g., "include" or "+include" produces a "pass" result -and "-include" produces "fail").</p> +<p>If it returns match, then the appropriate result for the "include" + mechanism is used (e.g., "include" or "+include" produces a "pass" result + and "-include" produces "fail").</p> </li> <li> <p>If it returns not-match or an error, the parent <code>check_host()</code> resumes -processing as per the table below, with the previous value of <code><domain></code> -restored.</p> + processing as per the table below, with the previous value of <code><domain></code> + restored.</p> </li> </ol> </div> <div class="paragraph"> -<p>The "include" mechanism makes it possible for one domain to designate +<p>The "include" mechanism makes it possible for one domain to designate multiple administratively independent domains. -For example, a vanity domain "example.net" might send mail using the servers -of administratively independent domains "example.com" and "example.org".</p> +For example, a vanity domain "example.net" might send mail using the servers +of administratively independent domains "example.com" and "example.org".</p> </div> <div class="paragraph"> <p>Example.net could say</p> </div> <div class="listingblock"> <div class="content"> -<pre>IN TXT "v=spf1 include:example.com include:example.org -all"</pre> +<pre>IN TXT "v=spf1 include:example.com include:example.org -all"</pre> </div> </div> <div class="paragraph"> <p>This would direct <code>check_host()</code> to, in effect, check the records of -"example.com" and "example.org" for a "pass" result. +"example.com" and "example.org" for a "pass" result. Only if the host were not permitted for either of those domains would the -result be "fail".</p> +result be "fail".</p> </div> <div class="paragraph"> <p>Whether this mechanism matches, does not match, or returns an exception @@ -828,7 +836,7 @@ depends on the result of the recursive evaluation of <code>check_host()</code>:< <thead> <tr> <th class="tableblock halign-left valign-top">A recursive check_host() result of:</th> -<th class="tableblock halign-left valign-top">Causes the "include" mechanism to:</th> +<th class="tableblock halign-left valign-top">Causes the "include" mechanism to:</th> </tr> </thead> <tbody> @@ -863,19 +871,19 @@ depends on the result of the recursive evaluation of <code>check_host()</code>:< </tbody> </table> <div class="paragraph"> -<p>The "include" mechanism is intended for crossing administrative boundaries.</p> +<p>The "include" mechanism is intended for crossing administrative boundaries.</p> </div> <div class="paragraph"> -<p>When remaining within one administrative authority, "include" is usually +<p>When remaining within one administrative authority, "include" is usually not the best choice. For example, if example.com and example.org were managed by the same entity, and if the permitted set of hosts for both domains was -"mx:example.com", it would be possible for example.org to specify -"include:example.com", but it would be preferable to specify -"redirect=example.com" or even "mx:example.com".</p> +"mx:example.com", it would be possible for example.org to specify +"include:example.com", but it would be preferable to specify +"redirect=example.com" or even "mx:example.com".</p> </div> <div class="paragraph"> -<p>The "redirect" modifier is more suitable for consolidating both authorizations +<p>The "redirect" modifier is more suitable for consolidating both authorizations and policy into a common set to be shared within an ADMD. Redirect is much more like a common code element to be shared among records in a single ADMD. @@ -884,15 +892,15 @@ number of domains from a single record.</p> </div> </div> <div class="sect2"> -<h3 id="_a"><a class="anchor" href="#_a"></a>5.3. "a"</h3> +<h3 id="__a">"a"</h3> <div class="listingblock"> <div class="content"> -<pre>a = "a" [ ":" domain-spec ] [ dual-cidr-length ]</pre> +<pre>a = "a" [ ":" domain-spec ] [ dual-cidr-length ]</pre> </div> </div> <div class="paragraph"> -<p>This mechanism matches if <ip> is one of the <target-name>'s IP addresses. -For clarity, this means the "a" mechanism also matches AAAA records.</p> +<p>This mechanism matches if <ip> is one of the <target-name>'s IP addresses. +For clarity, this means the "a" mechanism also matches AAAA records.</p> </div> <div class="paragraph"> <p>An address lookup is done on the <target-name> using the type of lookup (A or @@ -902,7 +910,7 @@ If any address matches, the mechanism matches.</p> </div> </div> <div class="sect2"> -<h3 id="_mx"><a class="anchor" href="#_mx"></a>5.4. "mx"</h3> +<h3 id="__mx">"mx"</h3> <div class="paragraph"> <p>This mechanism matches if <ip> is one of the MX hosts for a domain name.</p> @@ -920,11 +928,11 @@ name.</p> <ul> <li> <p>To prevent denial-of-service (DoS) attacks, the processing limits -defined in Section 4.6.4 MUST be followed.</p> + defined in Section 4.6.4 MUST be followed.</p> </li> <li> -<p>If the MX lookup limit is exceeded, then "permerror" is returned -and the evaluation is terminated.</p> +<p>If the MX lookup limit is exceeded, then "permerror" is returned + and the evaluation is terminated.</p> </li> </ul> </div> @@ -940,43 +948,43 @@ and the evaluation is terminated.</p> </li> <li> <p>If the <target-name> has no MX record, check_host() MUST NOT apply -the implicit MX rules of [RFC5321] by querying for an A or AAAA -record for the same name.</p> + the implicit MX rules of [RFC5321] by querying for an A or AAAA + record for the same name.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_mechanism_ptr"><a class="anchor" href="#_mechanism_ptr"></a>5.5. "ptr" (do not use)</h3> +<h3 id="_mechanism_ptr">"ptr" (do not use)</h3> <div class="paragraph"> <p>This mechanism tests whether the DNS reverse-mapping for <ip> exists and correctly points to a domain name within a particular domain. This mechanism SHOULD NOT be published.</p> </div> <div class="paragraph"> -<p>The <ip>'s name is looked up using this procedure:</p> +<p>The <ip>'s name is looked up using this procedure:</p> </div> <div class="ulist"> <ul> <li> <p>Perform a DNS reverse-mapping for <ip>: Look up the corresponding -PTR record in "in-addr.arpa." if the address is an IPv4 address -and in "ip6.arpa." if it is an IPv6 address.</p> + PTR record in "in-addr.arpa." if the address is an IPv4 address + and in "ip6.arpa." if it is an IPv6 address.</p> </li> <li> <p>Check all domain names to see if they either match the <target-name> domain -or are a subdomain of the <target-name> domain.</p> + or are a subdomain of the <target-name> domain.</p> </li> <li> <p>If any do, this domain name can be validated.</p> </li> <li> <p>If no domain name can be found, or if none of the domain names match or -are a subdomain of the <target-name>, this mechanism fails to match.</p> + are a subdomain of the <target-name>, this mechanism fails to match.</p> </li> <li> <p>If a DNS error occurs while doing the PTR RR lookup, then this mechanism -fails to match.</p> + fails to match.</p> </li> </ul> </div> @@ -994,8 +1002,8 @@ fails to match.</p> </ul> </div> <div class="paragraph"> -<p>For example, "mail.example.com" is within the domain "example.com", -but "mail.bad-example.com" is not.</p> +<p>For example, "mail.example.com" is within the domain "example.com", +but "mail.bad-example.com" is not.</p> </div> <div class="paragraph"> <p>The domain names received must also be validated for the mechanism to match.</p> @@ -1004,15 +1012,15 @@ but "mail.bad-example.com" is not.</p> <ul> <li> <p>For each matched record, validate the domain name by looking up -its IP addresses. -To prevent DoS attacks, the PTR processing limits defined in Section 4.6.4 -MUST be applied. -If they are exceeded, processing is terminated and the mechanism does not -match.</p> + its IP addresses. + To prevent DoS attacks, the PTR processing limits defined in Section 4.6.4 + MUST be applied. + If they are exceeded, processing is terminated and the mechanism does not + match.</p> </li> <li> <p>If <ip> is among the returned IP addresses, then that domain name is -validated.</p> + validated.</p> </li> </ul> </div> @@ -1029,8 +1037,8 @@ validating prevents needless DNS queries being performed.</p> <div class="paragraph"> <p>Note: This mechanism is not as reliable as other mechanisms in cases of DNS errors. -If used, proper PTR records have to be in place for the domain’s hosts and the -"ptr" mechanism SHOULD be one of the last mechanisms checked. +If used, proper PTR records have to be in place for the domain's hosts and the +"ptr" mechanism SHOULD be one of the last mechanisms checked. After many years of SPF deployment experience, it has been concluded that it is unnecessary and more reliable alternatives should be used instead. It is, however, still in use as part of the SPF protocol, so compliant @@ -1038,7 +1046,7 @@ check_host() implementations MUST support it.</p> </div> </div> <div class="sect2"> -<h3 id="_ip4_and_ip6"><a class="anchor" href="#_ip4_and_ip6"></a>5.6. "ip4" and "ip6"</h3> +<h3 id="__ip4_and_ip6">"ip4" and "ip6"</h3> <div class="paragraph"> <p>These mechanisms test whether <ip> is contained within a given IP network.</p> </div> @@ -1059,7 +1067,7 @@ qnum = DIGIT ; 0-9 / "25" %x30-35 ; 250-255 ; as per conventional dotted-quad notation, e.g., 192.0.2.0 -ip6-network = <as per Section 2.2 of [RFC4291]> +ip6-network = <as per Section 2.2 of [RFC4291]> ; e.g., 2001:db8::cd30</pre> </div> </div> @@ -1072,21 +1080,21 @@ ip6-network = <as per Section 2.2 of [RFC4291]> <p>If CIDR prefix length high-order bits match, the mechanism matches.</p> </li> <li> -<p>If ip4-cidr-length is omitted, it is taken to be "/32".</p> +<p>If ip4-cidr-length is omitted, it is taken to be "/32".</p> </li> <li> -<p>If ip6-cidr-length is omitted, it is taken to be "/128".</p> +<p>If ip6-cidr-length is omitted, it is taken to be "/128".</p> </li> <li> <p>It is not permitted to omit parts of the IP address instead of using CIDR -notations. -That is, use 192.0.2.0/24 instead of 192.0.2.</p> + notations. + That is, use 192.0.2.0/24 instead of 192.0.2.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_exist"><a class="anchor" href="#_exist"></a>5.7. "exist"</h3> +<h3 id="__exist">"exist"</h3> <div class="paragraph"> <p>This mechanism is used to construct an arbitrary domain name that is used for a DNS A record query. @@ -1102,14 +1110,14 @@ envelope to determine what is permitted.</p> <ul> <li> <p>The resulting domain name is used for a DNS A RR lookup (even when the -connection type is IPv6).</p> + connection type is IPv6).</p> </li> <li> <p>If any A record is returned, this mechanism matches.</p> </li> <li> <p>Domains can use this mechanism to specify arbitrarily complex queries. -For example, suppose example.com publishes the record:</p> + For example, suppose example.com publishes the record:</p> </li> </ul> </div> @@ -1119,7 +1127,7 @@ For example, suppose example.com publishes the record:</p> </div> </div> <div class="paragraph"> -<p>The <target-name> might expand to "1.2.0.192.someuser._spf.example.com". +<p>The <target-name> might expand to "1.2.0.192.someuser._spf.example.com". This makes fine-grained decisions possible at the level of the user and client IP address.</p> </div> @@ -1127,7 +1135,7 @@ IP address.</p> </div> </div> <div class="sect1"> -<h2 id="_modifier_definitions"><a class="anchor" href="#_modifier_definitions"></a>6. Modifier Definitions</h2> +<h2 id="_modifier_definitions">Modifier Definitions</h2> <div class="sectionbody"> <div class="paragraph"> <p>Modifiers are name/value pairs that provide additional information.</p> @@ -1135,32 +1143,32 @@ IP address.</p> <div class="ulist"> <ul> <li> -<p>Modifiers always have an "=" separating the name and the value.</p> +<p>Modifiers always have an "=" separating the name and the value.</p> </li> <li> -<p>The modifiers defined in this document ("redirect" and "exp") SHOULD appear -at the end of the record, after all mechanisms, though syntactically they -can appear anywhere in the record.</p> +<p>The modifiers defined in this document ("redirect" and "exp") SHOULD appear + at the end of the record, after all mechanisms, though syntactically they + can appear anywhere in the record.</p> </li> <li> <p>Ordering of these two modifiers does not matter.</p> </li> <li> <p>These two modifiers MUST NOT appear in a record more than once each. -If they do, then check_host() exits with a result of "permerror".</p> + If they do, then check_host() exits with a result of "permerror".</p> </li> <li> <p>Unrecognized modifiers MUST be ignored no matter where, or how often, -they appear in a record. -This allows implementations conforming to this document to gracefully -handle records with modifiers that are defined in other specifications.</p> + they appear in a record. + This allows implementations conforming to this document to gracefully + handle records with modifiers that are defined in other specifications.</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_redirect_redirected_query"><a class="anchor" href="#_redirect_redirected_query"></a>6.1. redirect: Redirected Query</h3> +<h3 id="_redirect_redirected_query">redirect: Redirected Query</h3> <div class="paragraph"> -<p>The "redirect" modifier is intended for consolidating both authorizations and +<p>The "redirect" modifier is intended for consolidating both authorizations and policy into a common set to be shared within a single ADMD.</p> </div> <div class="literalblock"> @@ -1171,24 +1179,24 @@ policy into a common set to be shared within a single ADMD.</p> <div class="ulist"> <ul> <li> -<p>For clarity, any "redirect" modifier SHOULD appear as the very last -term in a record.</p> +<p>For clarity, any "redirect" modifier SHOULD appear as the very last + term in a record.</p> </li> <li> -<p>Any "redirect" modifier MUST be ignored if there is an "all" mechanism -anywhere in the record.</p> +<p>Any "redirect" modifier MUST be ignored if there is an "all" mechanism + anywhere in the record.</p> </li> </ul> </div> <div class="paragraph"> -<p>If all mechanisms fail to match, and a "redirect" modifier is present, then +<p>If all mechanisms fail to match, and a "redirect" modifier is present, then processing proceeds as follows:</p> </div> <div class="ulist"> <ul> <li> <p>The <domain-spec> portion of the redirect section is expanded as per -the macro rules in Section 7.</p> + the macro rules in Section 7.</p> <div class="ulist"> <ul> <li> @@ -1196,16 +1204,16 @@ the macro rules in Section 7.</p> </li> <li> <p>The <ip> and <sender> arguments remain the same as in the current -evaluation of check_host().</p> + evaluation of check_host().</p> </li> </ul> </div> </li> <li> <p>The result of this new evaluation of check_host() is then considered -the result of the current evaluation with the exception that if no -SPF record is found, or if the <target-name> is malformed, the result -is a "permerror" rather than "none".</p> + the result of the current evaluation with the exception that if no + SPF record is found, or if the <target-name> is malformed, the result + is a "permerror" rather than "none".</p> </li> <li> <p>Note that the newly queried domain can itself specify redirect processing.</p> @@ -1230,82 +1238,82 @@ record. This can be an administrative advantage.</p> </div> <div class="paragraph"> -<p>Note: In general, the domain "A" cannot reliably use a redirect to another -domain "B" not under the same administrative control. +<p>Note: In general, the domain "A" cannot reliably use a redirect to another +domain "B" not under the same administrative control. Since the <sender> stays the same, there is no guarantee that the record at -domain "B" will correctly work for mailboxes in domain "A", especially if -domain "B" uses mechanisms involving local-parts. -An "include" directive will generally be more appropriate.</p> +domain "B" will correctly work for mailboxes in domain "A", especially if +domain "B" uses mechanisms involving local-parts. +An "include" directive will generally be more appropriate.</p> </div> </div> <div class="sect2"> -<h3 id="_exp_explanation"><a class="anchor" href="#_exp_explanation"></a>6.2. exp: Explanation</h3> +<h3 id="_exp_explanation">exp: Explanation</h3> <div class="literalblock"> <div class="content"> <pre>explanation = "exp" "=" domain-spec</pre> </div> </div> <div class="paragraph"> -<p>If check_host() results in a "fail" due to a mechanism match (such as "-all"), -and the "exp" modifier is present, then the explanation string returned is +<p>If check_host() results in a "fail" due to a mechanism match (such as "-all"), +and the "exp" modifier is present, then the explanation string returned is computed as described below.</p> </div> <div class="paragraph"> -<p>If no "exp" modifier is present, then either a default explanation string or +<p>If no "exp" modifier is present, then either a default explanation string or an empty explanation string MUST be returned to the calling application.</p> </div> <div class="ulist"> <ul> <li> <p>The <domain-spec> is macro expanded (see Section 7) and becomes the -<target-name>.</p> + <target-name>.</p> </li> <li> <p>The DNS TXT RRset for the <target-name> is fetched.</p> </li> <li> <p>If there are any DNS processing errors (any RCODE other than 0), or -if no records are returned, or if more than one record is returned, -or if there are syntax errors in the explanation string, then proceed -as if no "exp" modifier was given.</p> + if no records are returned, or if more than one record is returned, + or if there are syntax errors in the explanation string, then proceed + as if no "exp" modifier was given.</p> </li> <li> -<p>The fetched TXT record’s strings are concatenated with no spaces, and -then treated as an explain-string, which is macro-expanded. -This final result is the explanation string.</p> +<p>The fetched TXT record's strings are concatenated with no spaces, and + then treated as an explain-string, which is macro-expanded. + This final result is the explanation string.</p> </li> <li> <p>Implementations MAY limit the length of the resulting explanation string to -allow for other protocol constraints and/or reasonable processing limits.</p> + allow for other protocol constraints and/or reasonable processing limits.</p> </li> <li> <p>Since the explanation string is intended for an SMTP response and Section -2.4 of [RFC5321] says that responses are in [US-ASCII], the explanation -string MUST be limited to [US-ASCII].</p> + 2.4 of [RFC5321] says that responses are in [US-ASCII], the explanation + string MUST be limited to [US-ASCII].</p> </li> <li> <p>Software evaluating check_host() can use this string to communicate -information from the publishing domain in the form of a short message -or URL.</p> + information from the publishing domain in the form of a short message + or URL.</p> </li> <li> <p>Software SHOULD make it clear that the explanation string comes from a -third party. -For example, it can prepend the macro string "%{o} explains: " to the -explanation.</p> + third party. + For example, it can prepend the macro string "%{o} explains: " to the + explanation.</p> </li> <li> -<p>During recursion into an "include" mechanism, an "exp" modifier -from the <target-name> MUST NOT be used. -This is because "include" is meant to cross administrative boundaries and -the explanation provided should be the one from the receiving ADMD.</p> +<p>During recursion into an "include" mechanism, an "exp" modifier + from the <target-name> MUST NOT be used. + This is because "include" is meant to cross administrative boundaries and + the explanation provided should be the one from the receiving ADMD.</p> </li> <li> -<p>In contrast, when executing a "redirect" modifier, an "exp" modifier from -the original domain MUST NOT be used. -"redirect" is meant to operate as a tool to consolidate policy records -within an ADMD so the redirected explanation is the one that ought to have -priority.</p> +<p>In contrast, when executing a "redirect" modifier, an "exp" modifier from + the original domain MUST NOT be used. + "redirect" is meant to operate as a tool to consolidate policy records + within an ADMD so the redirected explanation is the one that ought to have + priority.</p> </li> </ul> </div> @@ -1319,7 +1327,7 @@ explain._spf.example.com:</p> </div> </div> <div class="paragraph"> -<p> — a simple, constant message</p> +<p>-- a simple, constant message</p> </div> <div class="literalblock"> <div class="content"> @@ -1327,16 +1335,16 @@ explain._spf.example.com:</p> </div> </div> <div class="paragraph"> -<p> — a message with a little more information, including the IP address that +<p>-- a message with a little more information, including the IP address that failed the check</p> </div> <div class="literalblock"> <div class="content"> -<pre>"See http://%{d}/why.html?s=%{S}&i=%{I}"</pre> +<pre>"See http://%{d}/why.html?s=%{S}&i=%{I}"</pre> </div> </div> <div class="paragraph"> -<p> — a complicated example that constructs a URL with the arguments to +<p>-- a complicated example that constructs a URL with the arguments to check_host() so that a web page can be generated with detailed, custom instructions</p> </div> @@ -1344,10 +1352,10 @@ instructions</p> </div> </div> <div class="sect1"> -<h2 id="_macros"><a class="anchor" href="#_macros"></a>7. Macros</h2> +<h2 id="_macros">Macros</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_formal_specification"><a class="anchor" href="#_formal_specification"></a>7.1. Formal Specification</h3> +<h3 id="_formal_specification">Formal Specification</h3> <div class="literalblock"> <div class="content"> <pre>domain-spec = macro-string domain-end @@ -1383,36 +1391,36 @@ delimiter = "." / "-" / "+" / "," / "/" / "_" / "="</pre> <div class="ulist"> <ul> <li> -<p>A literal "%" is expressed by "%%".</p> +<p>A literal "%" is expressed by "%%".</p> </li> <li> -<p>"%_" expands to a single " " space.</p> +<p>"%_" expands to a single " " space.</p> </li> <li> -<p>"%-" expands to a URL-encoded space, viz., "%20".</p> +<p>"%-" expands to a URL-encoded space, viz., "%20".</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_macro_definitions"><a class="anchor" href="#_macro_definitions"></a>7.2. Macro Definitions</h3> +<h3 id="_macro_definitions">Macro Definitions</h3> <div class="paragraph"> <p>The following macro letters are expanded in term arguments:</p> </div> <div class="literalblock"> <div class="content"> -<pre>s = <sender> -l = local-part of <sender> -o = domain of <sender> -d = <domain> -i = <ip> -p = the validated domain name of <ip> (do not use) -v = the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6 +<pre>s = <sender> +l = local-part of <sender> +o = domain of <sender> +d = <domain> +i = <ip> +p = the validated domain name of <ip> (do not use) +v = the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6 h = HELO/EHLO domain</pre> </div> </div> <div class="paragraph"> -<p>The following macro letters are allowed only in "exp" text:</p> +<p>The following macro letters are allowed only in "exp" text:</p> </div> <div class="literalblock"> <div class="content"> @@ -1423,9 +1431,9 @@ t = current timestamp</pre> </div> </div> <div class="sect2"> -<h3 id="_macro_processing_details"><a class="anchor" href="#_macro_processing_details"></a>7.3. Macro Processing Details</h3> +<h3 id="_macro_processing_details">Macro Processing Details</h3> <div class="paragraph"> -<p>A '%' character not followed by a '{', '%', '-', or '_' character is a syntax +<p>A '%' character not followed by a '{', '%', '-', or '_' character is a syntax error. So:</p> </div> @@ -1435,7 +1443,7 @@ So:</p> </div> </div> <div class="paragraph"> -<p>is incorrect and will cause check_host() to yield a "permerror". +<p>is incorrect and will cause check_host() to yield a "permerror". Instead, the following is legal:</p> </div> <div class="literalblock"> @@ -1461,34 +1469,34 @@ Instead, the following is legal:</p> letter is split into parts separated by one or more of the specified delimiter characters. After performing any reversal operation and/or removal of left-hand parts, the -parts are rejoined using "." and not the original splitting characters.</p> +parts are rejoined using "." and not the original splitting characters.</p> </div> <div class="ulist"> <ul> <li> -<p>By default, strings are split on "." (dots).</p> +<p>By default, strings are split on "." (dots).</p> </li> <li> <p>Note that no special treatment is given to leading, trailing, or -consecutive delimiters in input strings, and so the list of parts might -contain empty strings.</p> + consecutive delimiters in input strings, and so the list of parts might + contain empty strings.</p> </li> <li> <p>Some older implementations of SPF prohibit trailing dots in domain names, -so trailing dots SHOULD NOT be published, although they MUST be accepted by -implementations conforming to this document.</p> + so trailing dots SHOULD NOT be published, although they MUST be accepted by + implementations conforming to this document.</p> </li> <li> -<p>Macros can specify delimiter characters that are used instead of ".".</p> +<p>Macros can specify delimiter characters that are used instead of ".".</p> </li> <li> -<p>The "r" transformer indicates a reversal operation: if the client IP -address were 192.0.2.1, the macro %{i} would expand to "192.0.2.1" -and the macro %{ir} would expand to "1.2.0.192".</p> +<p>The "r" transformer indicates a reversal operation: if the client IP + address were 192.0.2.1, the macro %{i} would expand to "192.0.2.1" + and the macro %{ir} would expand to "1.2.0.192".</p> </li> <li> <p>The DIGIT transformer indicates the number of right-hand parts to use, -after optional reversal.</p> + after optional reversal.</p> <div class="ulist"> <ul> <li> @@ -1496,60 +1504,60 @@ after optional reversal.</p> </li> <li> <p>If no DIGITs are specified, or if the value specifies more parts than are -available, all the available parts are used.</p> + available, all the available parts are used.</p> </li> <li> <p>If the DIGIT was 5, and only 3 parts were available, the macro -interpreter would pretend the DIGIT was 3.</p> + interpreter would pretend the DIGIT was 3.</p> </li> <li> <p>Implementations MUST support at least a value of 127, as that is the -maximum number of labels in a domain name (less the zero-length label at -the end).</p> + maximum number of labels in a domain name (less the zero-length label at + the end).</p> </li> </ul> </div> </li> <li> -<p>The "s" macro expands to the <sender> argument. -It is an email address with a local-part, an "@" character, and a domain.</p> +<p>The "s" macro expands to the <sender> argument. + It is an email address with a local-part, an "@" character, and a domain.</p> </li> <li> -<p>The "l" macro expands to just the local-part.</p> +<p>The "l" macro expands to just the local-part.</p> </li> <li> -<p>The "o" macro expands to just the domain part.</p> +<p>The "o" macro expands to just the domain part.</p> </li> <li> -<p>Note that "s", "l", and "o" values remain the same during recursive and -chained evaluations due to "include" and/or "redirect".</p> +<p>Note that "s", "l", and "o" values remain the same during recursive and + chained evaluations due to "include" and/or "redirect".</p> </li> <li> <p>If the original <sender> had no local-part, the local-part was set to -"postmaster" in initial processing (see Section 4.3).</p> + "postmaster" in initial processing (see Section 4.3).</p> </li> <li> -<p>For IPv4 addresses, both the "i" and "c" macros expand to the standard -dotted-quad format.</p> +<p>For IPv4 addresses, both the "i" and "c" macros expand to the standard + dotted-quad format.</p> </li> <li> -<p>For IPv6 addresses, the "i" macro expands to a dot-format address; it -is intended for use in %{ir}.</p> +<p>For IPv6 addresses, the "i" macro expands to a dot-format address; it + is intended for use in %{ir}.</p> </li> <li> -<p>The "c" macro can expand to any of the hexadecimal colon-format addresses -specified in Section 2.2 of [RFC4291]. -It is intended for humans to read.</p> +<p>The "c" macro can expand to any of the hexadecimal colon-format addresses + specified in Section 2.2 of [RFC4291]. + It is intended for humans to read.</p> </li> <li> -<p>The "p" macro expands to the validated domain name of <ip>. -The procedure for finding the validated domain name is defined in -<a href="#_mechanism_ptr">Section 5.5</a>.</p> +<p>The "p" macro expands to the validated domain name of <ip>. + The procedure for finding the validated domain name is defined in + <a href="#_mechanism_ptr">Section 5.5</a>.</p> <div class="ulist"> <ul> <li> <p>If the <domain> is present in the list of validated domains, it SHOULD be -used.</p> + used.</p> </li> <li> <p>Otherwise, if a subdomain of the <domain> is present, it SHOULD be used.</p> @@ -1559,81 +1567,87 @@ used.</p> </li> <li> <p>If there are no validated domain names or if a DNS error occurs, the -string "unknown" is used.</p> + string "unknown" is used.</p> </li> <li> <p>This macro SHOULD NOT be published (see -<a href="#_mechanism_ptr">Section 5.5</a> -for the discussion).</p> + <a href="#_mechanism_ptr">Section 5.5</a> + for the discussion).</p> </li> </ul> </div> </li> <li> -<p>The "h" macro expands to the parameter that was provided to the SMTP -server via the HELO or EHLO SMTP verb. -For sessions where that verb was provided more than once, the most recent -instance is used.</p> +<p>The "h" macro expands to the parameter that was provided to the SMTP + server via the HELO or EHLO SMTP verb. + For sessions where that verb was provided more than once, the most recent + instance is used.</p> </li> <li> -<p>The "r" macro expands to the name of the receiving MTA. -This SHOULD be a fully qualified domain name, but if one does not exist (as -when the checking is done by a Mail User Agent (MUA)) or if policy -restrictions dictate otherwise, the word "unknown" SHOULD be substituted. -The domain name can be different from the name found in the MX record that -the client MTA used to locate the receiving MTA.</p> +<p>The "r" macro expands to the name of the receiving MTA. + This SHOULD be a fully qualified domain name, but if one does not exist (as + when the checking is done by a Mail User Agent (MUA)) or if policy + restrictions dictate otherwise, the word "unknown" SHOULD be substituted. + The domain name can be different from the name found in the MX record that + the client MTA used to locate the receiving MTA.</p> </li> <li> -<p>The "t" macro expands to the decimal representation of the approximate -number of seconds since the Epoch (Midnight, January 1, 1970, UTC) at the time -of the evaluation. -This is the same value as the value that is returned by the -Portable Operating System Interface (POSIX) time() function in most -standards-compliant libraries.</p> +<p>The "t" macro expands to the decimal representation of the approximate + number of seconds since the Epoch (Midnight, January 1, 1970, UTC) at the time + of the evaluation. + This is the same value as the value that is returned by the + Portable Operating System Interface (POSIX) time() function in most + standards-compliant libraries.</p> </li> <li> <p>When the result of macro expansion is used in a domain name query, -if the expanded domain name exceeds 253 characters (the maximum -length of a domain name in this format), the left side is truncated -to fit, by removing successive domain labels (and their following -dots) until the total length does not exceed 253 characters.</p> + if the expanded domain name exceeds 253 characters (the maximum + length of a domain name in this format), the left side is truncated + to fit, by removing successive domain labels (and their following</p> +<div class="olist lowerroman"> +<ol class="lowerroman" type="i"> +<li> +<p>until the total length does not exceed 253 characters.</p> +</li> +</ol> +</div> </li> <li> <p>Uppercase macros expand exactly as their lowercase equivalents, and -are then URL escaped. -URL escaping MUST be performed for characters not in the -"unreserved" set, which is defined in [RFC3986].</p> + are then URL escaped. + URL escaping MUST be performed for characters not in the + "unreserved" set, which is defined in [RFC3986].</p> </li> <li> <p>Care has to be taken by the sending ADMD so that macro expansion -for legitimate email does not exceed the 63-character limit on DNS -labels. -The local-part of email addresses, in particular, can have -more than 63 characters between dots.</p> + for legitimate email does not exceed the 63-character limit on DNS + labels. + The local-part of email addresses, in particular, can have + more than 63 characters between dots.</p> </li> <li> <p>To minimize DNS lookup resource requirements, it is better if -sending ADMDs avoid using the "s", "l", "o", or "h" macros in -conjunction with any mechanism directive. -Although these macros are powerful and allow per-user records to be -published, they severely limit the ability of implementations to -cache results of check_host() and they reduce the effectiveness of -DNS caches.</p> + sending ADMDs avoid using the "s", "l", "o", or "h" macros in + conjunction with any mechanism directive. + Although these macros are powerful and allow per-user records to be + published, they severely limit the ability of implementations to + cache results of check_host() and they reduce the effectiveness of + DNS caches.</p> </li> <li> <p>If no directive processed during the evaluation of check_host() -contains an "s", "l", "o", or "h" macro, then the results of the -evaluation can be cached on the basis of <domain> and <ip> alone -for as long as the DNS record involved with the shortest Time to -Live (TTL) has not expired.</p> + contains an "s", "l", "o", or "h" macro, then the results of the + evaluation can be cached on the basis of <domain> and <ip> alone + for as long as the DNS record involved with the shortest Time to + Live (TTL) has not expired.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_expansion_examples"><a class="anchor" href="#_expansion_examples"></a>7.4. Expansion Examples</h3> +<h3 id="_expansion_examples">Expansion Examples</h3> <div class="paragraph"> -<p>The <sender> is <a href="mailto:strong-bad@email.example.com">strong-bad@email.example.com</a>. +<p>The <sender> is strong-bad@email.example.com. The IPv4 SMTP client IP is 192.0.2.3. The IPv6 SMTP client IP is 2001:db8::cb01. The PTR domain name of the client IP is mx.example.org.</p> @@ -1652,7 +1666,7 @@ The PTR domain name of the client IP is mx.example.org.</p> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">%{s}</p></td> -<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="mailto:strong-bad@email.example.com">strong-bad@email.example.com</a></p></td> +<td class="tableblock halign-left valign-top"><p class="tableblock">strong-bad@email.example.com</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">%{o}</p></td> @@ -1736,7 +1750,7 @@ The PTR domain name of the client IP is mx.example.org.</p> </div> </div> <div class="sect1"> -<h2 id="_result_handling"><a class="anchor" href="#_result_handling"></a>8. Result Handling</h2> +<h2 id="_result_handling">Result Handling</h2> <div class="sectionbody"> <div class="paragraph"> <p>There are essentially two classes of handling choices:</p> @@ -1745,19 +1759,19 @@ The PTR domain name of the client IP is mx.example.org.</p> <ul> <li> <p>Handling within the SMTP session that attempted to deliver the -message, such as by returning a permanent SMTP error (rejection) or -temporary SMTP error ("try again later");</p> + message, such as by returning a permanent SMTP error (rejection) or + temporary SMTP error ("try again later");</p> </li> <li> <p>Permitting the message to pass (a successful SMTP reply code) and -adding an additional header field that indicates the result -returned by check_host() and other salient details; this is -discussed in more detail in Section 9.</p> + adding an additional header field that indicates the result + returned by check_host() and other salient details; this is + discussed in more detail in Section 9.</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_none"><a class="anchor" href="#_none"></a>8.1. None</h3> +<h3 id="_none">None</h3> <div class="paragraph"> <p>The SPF verifier has no information at all about the authorization or lack thereof of the client to use the checked identity or identities. @@ -1766,20 +1780,20 @@ reach any conclusion.</p> </div> </div> <div class="sect2"> -<h3 id="_neutral"><a class="anchor" href="#_neutral"></a>8.2. Neutral</h3> +<h3 id="_neutral">Neutral</h3> <div class="paragraph"> <p>A policy for the identity was discovered, there is no definite assertion (positive or negative) about the client.</p> </div> <div class="paragraph"> -<p>A "neutral" result MUST be treated exactly like the "none" result; the +<p>A "neutral" result MUST be treated exactly like the "none" result; the distinction exists only for informational purposes. -Treating "neutral" more harshly than "none" would discourage ADMDs +Treating "neutral" more harshly than "none" would discourage ADMDs from testing the use of SPF records (see Section 10.1).</p> </div> </div> <div class="sect2"> -<h3 id="_pass"><a class="anchor" href="#_pass"></a>8.3. Pass</h3> +<h3 id="_pass">Pass</h3> <div class="paragraph"> <p>The client is authorized to inject mail with the given identity. The domain can now, in the sense of reputation, be considered @@ -1790,7 +1804,7 @@ This is further discussed in Appendix G.1.</p> </div> </div> <div class="sect2"> -<h3 id="_fail"><a class="anchor" href="#_fail"></a>8.4. Fail</h3> +<h3 id="_fail">Fail</h3> <div class="paragraph"> <p>The client is not authorized to use the domain in the given identity. Disposition of SPF fail messages is a matter of local policy. @@ -1800,19 +1814,22 @@ See Appendix G.2 for considerations on developing local policy.</p> <ul> <li> <p>If the checking software chooses to reject the mail during the SMTP -transaction, then it SHOULD use an SMTP reply code of 550 (see -[RFC5321]) and, if supported, the 5.7.1 enhanced status code (see -[RFC3463], Section 3.8), in addition to an appropriate reply text.</p> + transaction, then it SHOULD use an SMTP reply code of 550 (see + [RFC5321]) and, if supported, the 5.7.1 enhanced status code (see + [RFC3463], Section 3.8), in addition to an appropriate reply text.</p> </li> <li> <p>The check_host() function will return either a default explanation -string or one from the domain that published the SPF records (see -Section 6.2).</p> + string or one from the domain that published the SPF records (see + Section 6.2).</p> </li> <li> <p>If the information does not originate with the checking software, -it is good to make it clear that the text is provided by the -sender’s domain. For example:</p> + it is good to make it clear that the text is provided by the + sender's domain. For example:</p> +</li> +</ul> +</div> <div class="literalblock"> <div class="content"> <pre>550 5.7.1 SPF MAIL FROM check failed: @@ -1820,24 +1837,25 @@ sender’s domain. For example:</p> 550 5.7.1 Please see http://www.example.com/mailpolicy.html</pre> </div> </div> -</li> +<div class="ulist"> +<ul> <li> <p>If the checking software chooses not to reject the mail during the -SMTP transaction, then it SHOULD add a Received-SPF or -Authentication-Results header field (see Section 9) to communicate -this result to downstream message processors. -While this is true for all SPF results, it is of particular -importance for "fail" results since the message is explicitly not -authorized by the ADMD.</p> + SMTP transaction, then it SHOULD add a Received-SPF or + Authentication-Results header field (see Section 9) to communicate + this result to downstream message processors. + While this is true for all SPF results, it is of particular + importance for "fail" results since the message is explicitly not + authorized by the ADMD.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_softfail"><a class="anchor" href="#_softfail"></a>8.5. Softfail</h3> +<h3 id="_softfail">Softfail</h3> <div class="paragraph"> -<p>A "softfail" result ought to be treated as somewhere between "fail" -and "neutral"/"none". +<p>A "softfail" result ought to be treated as somewhere between "fail" +and "neutral"/"none". The ADMD believes the host is not authorized but is not willing to make a strong policy statement.</p> </div> @@ -1845,23 +1863,23 @@ make a strong policy statement.</p> <ul> <li> <p>Receiving software SHOULD NOT reject the message based solely on -this result, but MAY subject the message to closer scrutiny than -normal.</p> + this result, but MAY subject the message to closer scrutiny than + normal.</p> </li> <li> <p>The ADMD wants to discourage the use of this host and thus desires -limited feedback when a "softfail" result occurs. -For example, the recipient’s MUA could highlight the "softfail" -status, or the receiving MTA could give the sender a message using -greylisting [RFC6647], with a note the first time the message is -received, but accept it on a later attempt based on receiver -policy.</p> + limited feedback when a "softfail" result occurs. + For example, the recipient's MUA could highlight the "softfail" + status, or the receiving MTA could give the sender a message using + greylisting [RFC6647], with a note the first time the message is + received, but accept it on a later attempt based on receiver + policy.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_temperror"><a class="anchor" href="#_temperror"></a>8.6. Temperror</h3> +<h3 id="_temperror">Temperror</h3> <div class="paragraph"> <p>The SPF verifier encountered a transient (generally DNS) error while performing the check.</p> @@ -1870,47 +1888,47 @@ performing the check.</p> <ul> <li> <p>Checking software can choose to accept or temporarily reject the -message.</p> + message.</p> </li> <li> <p>If the message is rejected during the SMTP transaction for this reason, the -software SHOULD use an SMTP reply code of 451 and, if supported, -the 4.4.3 enhanced status code (see Section 3.5 of [RFC3463]).</p> + software SHOULD use an SMTP reply code of 451 and, if supported, + the 4.4.3 enhanced status code (see Section 3.5 of [RFC3463]).</p> </li> <li> -<p>These errors can be caused by problems in either the sender’s or -receiver’s DNS software. -See Appendix G.4 for considerations on developing local policy.</p> +<p>These errors can be caused by problems in either the sender's or + receiver's DNS software. + See Appendix G.4 for considerations on developing local policy.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_permerror"><a class="anchor" href="#_permerror"></a>8.7. Permerror</h3> +<h3 id="_permerror">Permerror</h3> <div class="paragraph"> -<p>The domain’s published records could not be correctly interpreted.</p> +<p>The domain's published records could not be correctly interpreted.</p> </div> <div class="ulist"> <ul> <li> <p>This signals an error condition that definitely requires DNS -operator intervention to be resolved.</p> + operator intervention to be resolved.</p> </li> <li> <p>If the message is rejected during the SMTP transaction for this -reason, the software SHOULD use an SMTP reply code of 550 and, if -supported, the 5.5.2 enhanced status code (see [RFC3463], Section -3.6).</p> + reason, the software SHOULD use an SMTP reply code of 550 and, if + supported, the 5.5.2 enhanced status code (see [RFC3463], Section + 3.6).</p> </li> <li> <p>Be aware that if the ADMD uses macros (Section 7), it is possible that this -result is due to the checked identities having an unexpected -format.</p> + result is due to the checked identities having an unexpected + format.</p> </li> <li> <p>It is also possible that this result is generated by certain SPF -verifiers due to the input arguments having an unexpected format; -see Section 4.8.</p> + verifiers due to the input arguments having an unexpected format; + see Section 4.8.</p> </li> <li> <p>See Appendix G.3 for considerations on developing local policy.</p> @@ -1921,7 +1939,7 @@ see Section 4.8.</p> </div> </div> <div class="sect1"> -<h2 id="_recording_the_result"><a class="anchor" href="#_recording_the_result"></a>9. Recording the Result</h2> +<h2 id="_recording_the_result">Recording the Result</h2> <div class="sectionbody"> <div class="paragraph"> <p>It is RECOMMENDED that SMTP receivers record the result of SPF @@ -1934,57 +1952,57 @@ processing in the message header.</p> <ul> <li> <p>Section 9.1 defines the Received-SPF field, which is the results -field originally defined for SPF use.</p> + field originally defined for SPF use.</p> <div class="ulist"> <ul> <li> <p>Received-SPF is intended to include enough information to enable -reconstruction of the SPF evaluation of the message.</p> + reconstruction of the SPF evaluation of the message.</p> </li> <li> <p>Received-SPF relies on compliance of agents within the receiving -ADMD to adhere to the header field ordering rules of [RFC5321] and -[RFC5322]</p> + ADMD to adhere to the header field ordering rules of [RFC5321] and + [RFC5322]</p> </li> </ul> </div> </li> <li> <p>Section 9.2 discusses the Authentication-Results header field -[RFC7001], which was specified more recently and is designed for -use by SPF and other authentication methods.</p> + [RFC7001], which was specified more recently and is designed for + use by SPF and other authentication methods.</p> <div class="ulist"> <ul> <li> <p>Authentication-Results is designed only to relay the result itself -and related output details of likely use to end users (e.g., what -property of the message was actually authenticated and what it -contained), leaving reconstructive work to the purview of system -logs and the Received field contents.</p> + and related output details of likely use to end users (e.g., what + property of the message was actually authenticated and what it + contained), leaving reconstructive work to the purview of system + logs and the Received field contents.</p> </li> <li> <p>Authentication-Results includes some provisions to protect against -non-compliant implementations.</p> + non-compliant implementations.</p> </li> </ul> </div> </li> <li> <p>An SPF verifier operator could choose to use both to serve -different downstream agents. -In such cases, care needs to be taken to ensure that both fields -are conveying the same details, or unexpected results can occur.</p> + different downstream agents. + In such cases, care needs to be taken to ensure that both fields + are conveying the same details, or unexpected results can occur.</p> </li> </ul> </div> <div class="sect2"> -<h3 id="_the_received_spf_header_field"><a class="anchor" href="#_the_received_spf_header_field"></a>9.1. The Received-SPF Header Field</h3> +<h3 id="_the_received_spf_header_field">The Received-SPF Header Field</h3> <div class="ulist"> <ul> <li> <p>The Received-SPF header field is a trace field (see [RFC5322], -Section 3.6.7) and SHOULD be prepended to the existing header, -above the Received: field that is generated by the SMTP receiver.</p> + Section 3.6.7) and SHOULD be prepended to the existing header, + above the Received: field that is generated by the SMTP receiver.</p> </li> <li> <p>It MUST appear above all other Received-SPF fields in the message.</p> @@ -2033,25 +2051,25 @@ above the Received: field that is generated by the SMTP receiver.</p> </div> <div class="literalblock"> <div class="content"> -<pre>dot-atom = <unquoted word as per [RFC5322]> -quoted-string = <quoted string as per [RFC5322]> -comment = <comment string as per [RFC5322]> -CFWS = <comment or folding white space as per [RFC5322]> -FWS = <folding white space as per [RFC5322]> -CRLF = <standard end-of-line token as per [RFC5322]></pre> +<pre>dot-atom = <unquoted word as per [RFC5322]> +quoted-string = <quoted string as per [RFC5322]> +comment = <comment string as per [RFC5322]> +CFWS = <comment or folding white space as per [RFC5322]> +FWS = <folding white space as per [RFC5322]> +CRLF = <standard end-of-line token as per [RFC5322]></pre> </div> </div> <div class="ulist"> <ul> <li> -<p>The header field SHOULD include a "(…​)" style comment after the -result, conveying supporting information for the result, such as -<ip>, <sender>, and <domain>.</p> +<p>The header field SHOULD include a "(…​)" style comment after the + result, conveying supporting information for the result, such as + <ip>, <sender>, and <domain>.</p> </li> <li> <p>SPF verifiers SHOULD give enough information so that the SPF -results can be verified — that is, at least "client-ip", "helo", -and, if the "MAIL FROM" identity was checked, "envelope-from".</p> + results can be verified -- that is, at least "client-ip", "helo", + and, if the "MAIL FROM" identity was checked, "envelope-from".</p> </li> </ul> </div> @@ -2071,7 +2089,7 @@ and, if the "MAIL FROM" identity was checked, "envelope-from".</p> </li> <li> <p>mechanism: the mechanism that matched (if no mechanisms matched, -substitute the word "default")</p> + substitute the word "default")</p> </li> <li> <p>problem: if an error was returned, details about the error</p> @@ -2081,7 +2099,7 @@ substitute the word "default")</p> </li> <li> <p>identity: the identity that was checked; see the <identity> ABNF -rule</p> + rule</p> </li> </ul> </div> @@ -2120,7 +2138,7 @@ Received-SPF: pass (mybox.example.org: domain of </div> </div> <div class="sect2"> -<h3 id="_spf_results_in_the_authentication_results_header_field"><a class="anchor" href="#_spf_results_in_the_authentication_results_header_field"></a>9.2. SPF Results in the Authentication-Results Header Field</h3> +<h3 id="_spf_results_in_the_authentication_results_header_field">SPF Results in the Authentication-Results Header Field</h3> <div class="paragraph"> <p>The Authentication-Results header field is designed to communicate lists of tests a border MTA did and their results. @@ -2139,13 +2157,13 @@ Received-SPF field:</p> </div> </div> <div class="paragraph"> -<p>It is, however, possible to add CFWS in the "reason" part of an +<p>It is, however, possible to add CFWS in the "reason" part of an Authentication-Results header field and provide the equivalent information, if desired.</p> </div> <div class="paragraph"> <p>As an example, an expanded Authentication-Results header field might -look like (for a "MAIL FROM" check in this example):</p> +look like (for a "MAIL FROM" check in this example):</p> </div> <div class="literalblock"> <div class="content"> @@ -2158,25 +2176,25 @@ look like (for a "MAIL FROM" check in this example):</p> </div> </div> <div class="sect1"> -<h2 id="_effects_on_infrastructure"><a class="anchor" href="#_effects_on_infrastructure"></a>10. Effects on Infrastructure</h2> +<h2 id="_effects_on_infrastructure">Effects on Infrastructure</h2> <div class="sectionbody"> <div class="paragraph"> <p>This section provides operational advice and instruction only. It is non-normative.</p> </div> <div class="sect2"> -<h3 id="_sending_domains"><a class="anchor" href="#_sending_domains"></a>10.1. Sending Domains</h3> +<h3 id="_sending_domains">Sending Domains</h3> <div class="paragraph"> <p>Originating ADMDs that wish to be compliant with this specification will need to determine the list of relays ([RFC5598], Section 2.2.2) -that they allow to use their domain name in the "HELO" and "MAIL FROM" +that they allow to use their domain name in the "HELO" and "MAIL FROM" identities when relaying to other ADMDs. It is recognized that forming such a list is not just a simple technical exercise, but involves policy decisions with both technical and administrative considerations.</p> </div> <div class="sect3"> -<h4 id="_dns_resource_considerations"><a class="anchor" href="#_dns_resource_considerations"></a>10.1.1. DNS Resource Considerations</h4> +<h4 id="_dns_resource_considerations">DNS Resource Considerations</h4> <div class="paragraph"> <p>For example, consider a domain set up as follows:</p> </div> @@ -2230,15 +2248,15 @@ authorized-spf IN A 192.0.2.1 </div> </div> <div class="sect3"> -<h4 id="_administrators_considerations"><a class="anchor" href="#_administrators_considerations"></a>10.1.2. Administrator’s Considerations</h4> +<h4 id="_administrator_s_considerations">Administrator's Considerations</h4> <div class="paragraph"> -<p>There might be administrative considerations: using "a" over "ip4" or -"ip6" allows hosts to be renumbered easily at the cost of a DNS query +<p>There might be administrative considerations: using "a" over "ip4" or +"ip6" allows hosts to be renumbered easily at the cost of a DNS query per receiver. -Using "mx" over "a" allows the set of mail hosts to be changed easily. +Using "mx" over "a" allows the set of mail hosts to be changed easily. Unless such changes are common, it is better to use the less -resource-intensive mechanisms like "ip4" and "ip6" over "a" or "a" -over "mx".</p> +resource-intensive mechanisms like "ip4" and "ip6" over "a" or "a" +over "mx".</p> </div> <div class="paragraph"> <p>Publishing SPF records for domains that send no mail is a well-established @@ -2271,27 +2289,27 @@ mechanism for soliciting feedback on SPF failures. Another suggestion can be found in Appendix C.</p> </div> <div class="paragraph"> -<p>Regardless of the method used, understanding the ADMD’s outbound mail +<p>Regardless of the method used, understanding the ADMD's outbound mail architecture is essential to effective deployment.</p> </div> </div> <div class="sect3"> -<h4 id="_bounces"><a class="anchor" href="#_bounces"></a>10.1.3. Bounces</h4> +<h4 id="_bounces">Bounces</h4> <div class="paragraph"> <p>In this case, the only entity available for performing an SPF check is -the "HELO" identity defined in Section 1.1.4. +the "HELO" identity defined in Section 1.1.4. SPF functionality is enhanced by administrators ensuring this identity is set correctly and has an appropriate SPF record. -It is normal to have the "HELO" identity set to the host name instead +It is normal to have the "HELO" identity set to the host name instead of the domain. Zone file generation for significant numbers of hosts can be -consolidated using the "redirect" modifier and scripted for initial +consolidated using the "redirect" modifier and scripted for initial deployment.</p> </div> </div> </div> <div class="sect2"> -<h3 id="_receivers"><a class="anchor" href="#_receivers"></a>10.2. Receivers</h3> +<h3 id="_receivers">Receivers</h3> <div class="paragraph"> <p>There is no comprehensive normative requirement for specific handling of a message based on SPF results. @@ -2299,10 +2317,10 @@ The information presented in Section 8 and in Appendix G is offered for receiver consideration when forming local handling policies.</p> </div> <div class="paragraph"> -<p>The primary considerations are that SPF might return "pass" for mail +<p>The primary considerations are that SPF might return "pass" for mail that is ultimately harmful (e.g., spammers that arrange for SPF to pass using disposable domain names, or virus or spam outbreaks from -within trusted sources), and might also return "fail" for mail that +within trusted sources), and might also return "fail" for mail that is ultimately legitimate (e.g., legitimate mail that has traversed a mail alias). It is important to take both of these cases under consideration when @@ -2310,9 +2328,9 @@ establishing local handling policy.</p> </div> </div> <div class="sect2"> -<h3 id="_mediator"><a class="anchor" href="#_mediator"></a>10.3. Mediator</h3> +<h3 id="_mediator">Mediator</h3> <div class="paragraph"> -<p>A mediator takes 'delivery' of a message and posts a 'submission' of a +<p>A mediator takes 'delivery' of a message and posts a 'submission' of a new message. The mediator can make the newly posted message be as similar to or as different from the original message as they wish. @@ -2323,7 +2341,7 @@ For the operation of SPF, the essential concern is the email address in the 5321.MailFrom command for the new message.</p> </div> <div class="paragraph"> -<p>Because SPF evaluation is based on the IP address of the "last" +<p>Because SPF evaluation is based on the IP address of the "last" sending SMTP server, the address of the mediator will be used, rather than the address of the SMTP server that sent the message to the mediator. @@ -2340,10 +2358,10 @@ used.</p> </div> </div> <div class="sect1"> -<h2 id="_security_considerations"><a class="anchor" href="#_security_considerations"></a>11. Security Considerations</h2> +<h2 id="_security_considerations">Security Considerations</h2> <div class="sectionbody"> <div class="sect2"> -<h3 id="_processing_limits"><a class="anchor" href="#_processing_limits"></a>11.1. Processing Limits</h3> +<h3 id="_processing_limits">Processing Limits</h3> <div class="paragraph"> <p>The processing limits outlined in Section 4.6.4 are designed to prevent attacks such as the following:</p> @@ -2352,56 +2370,56 @@ prevent attacks such as the following:</p> <ul> <li> <p>A malicious party could create an SPF record with many references -to a victim’s domain and send many emails to different SPF -verifiers; those SPF verifiers would then create a DoS attack. -In effect, the SPF verifiers are being used to amplify the -attacker’s bandwidth by using fewer octets in the SMTP session than -are used by the DNS queries. -Using SPF verifiers also allows the attacker to hide the true -source of the attack. -This potential attack is based on large volumes of mail being -transmitted.</p> + to a victim's domain and send many emails to different SPF + verifiers; those SPF verifiers would then create a DoS attack. + In effect, the SPF verifiers are being used to amplify the + attacker's bandwidth by using fewer octets in the SMTP session than + are used by the DNS queries. + Using SPF verifiers also allows the attacker to hide the true + source of the attack. + This potential attack is based on large volumes of mail being + transmitted.</p> </li> <li> <p>Whereas implementations of check_host() are supposed to limit the -number of DNS lookups, malicious domains could publish records -that exceed these limits in an attempt to waste computation effort -at their targets when they send them mail. -Malicious domains could also design SPF records that cause -particular implementations to use excessive memory or CPU or to -trigger bugs. -If a receiver is configured to accept mail with an SPF result of -"temperror", such an attack might result in mail that would -otherwise have been rejected due to an SPF "fail" result being -accepted. -This potential attack is based on specially crafted SPF records -being used to exhaust DNS resources of the victim.</p> + number of DNS lookups, malicious domains could publish records + that exceed these limits in an attempt to waste computation effort + at their targets when they send them mail. + Malicious domains could also design SPF records that cause + particular implementations to use excessive memory or CPU or to + trigger bugs. + If a receiver is configured to accept mail with an SPF result of + "temperror", such an attack might result in mail that would + otherwise have been rejected due to an SPF "fail" result being + accepted. + This potential attack is based on specially crafted SPF records + being used to exhaust DNS resources of the victim.</p> </li> <li> <p>Malicious parties could send a large volume of mail purporting to -come from the intended target to a wide variety of legitimate mail -hosts. -These legitimate machines would then present a DNS load on the -target as they fetched the relevant records.</p> + come from the intended target to a wide variety of legitimate mail + hosts. + These legitimate machines would then present a DNS load on the + target as they fetched the relevant records.</p> </li> <li> <p>Malicious parties could, in theory, use SPF records as a vehicle -for DNS lookup amplification for a DoS attack. -In this scenario, the attacker publishes an SPF record in its own -DNS that uses "a" and "mx" mechanisms directed toward the intended -victim, e.g., "a:example.com a:foo.example.com a:bar.example.com -…​" and then distributes mail with a MAIL FROM value including its -own domain in large volume to a wide variety of destinations. -Any such destination operating an SPF verifier will begin querying -all of the names associated with the "a" mechanisms in that record. -The names used in the record needn’t exist for the attack to be -effective. -Operational experience since the publication of [RFC4408] suggests -that mitigation of this class of attack can be accomplished with -minimal impact on the deployed base by having the verifier abort -processing and return "permerror" (Section 2.6.7) as soon as more -than two "void lookups" have been encountered (defined in Section -4.6.4).</p> + for DNS lookup amplification for a DoS attack. + In this scenario, the attacker publishes an SPF record in its own + DNS that uses "a" and "mx" mechanisms directed toward the intended + victim, e.g., "a:example.com a:foo.example.com a:bar.example.com + …​" and then distributes mail with a MAIL FROM value including its + own domain in large volume to a wide variety of destinations. + Any such destination operating an SPF verifier will begin querying + all of the names associated with the "a" mechanisms in that record. + The names used in the record needn't exist for the attack to be + effective. + Operational experience since the publication of [RFC4408] suggests + that mitigation of this class of attack can be accomplished with + minimal impact on the deployed base by having the verifier abort + processing and return "permerror" (Section 2.6.7) as soon as more + than two "void lookups" have been encountered (defined in Section + 4.6.4).</p> </li> </ul> </div> @@ -2415,14 +2433,14 @@ Therefore, the processing limits need to be quite low.</p> </div> </div> <div class="sect2"> -<h3 id="_spf_authorized_email_may_contain_other_false_identities"><a class="anchor" href="#_spf_authorized_email_may_contain_other_false_identities"></a>11.2. SPF-Authorized Email May Contain Other False Identities</h3> +<h3 id="_spf_authorized_email_may_contain_other_false_identities">SPF-Authorized Email May Contain Other False Identities</h3> <div class="paragraph"> -<p>The "MAIL FROM" and "HELO" identity authorizations do not provide +<p>The "MAIL FROM" and "HELO" identity authorizations do not provide assurance about the authorization/authenticity of other identities used in the message. It is entirely possible for a malicious sender to inject a message using his own domain in the identities used by SPF and have that -domain’s SPF record authorize the sending host, and yet the message +domain's SPF record authorize the sending host, and yet the message can easily list other identities in its header. Unless the user or the MUA takes care to note that the authorized identity does not match the other more commonly presented identities @@ -2431,7 +2449,7 @@ false sense of security.</p> </div> </div> <div class="sect2"> -<h3 id="_spoofed_dns_and_ip_data"><a class="anchor" href="#_spoofed_dns_and_ip_data"></a>11.3. Spoofed DNS and IP Data</h3> +<h3 id="_spoofed_dns_and_ip_data">Spoofed DNS and IP Data</h3> <div class="paragraph"> <p>There are two aspects of this protocol that malicious parties could exploit to undermine the validity of the check_host() function:</p> @@ -2440,29 +2458,29 @@ exploit to undermine the validity of the check_host() function:</p> <ul> <li> <p>The evaluation of check_host() relies heavily on DNS. -A malicious attacker could attack the DNS infrastructure and cause -check_host() to see spoofed DNS data, and then return incorrect -results. -This could include returning "pass" for an <ip> value where the -actual domain’s record would evaluate to "fail". -See [RFC3833] for a description of DNS weaknesses, and see -[RFC4033] for a countermeasure.</p> + A malicious attacker could attack the DNS infrastructure and cause + check_host() to see spoofed DNS data, and then return incorrect + results. + This could include returning "pass" for an <ip> value where the + actual domain's record would evaluate to "fail". + See [RFC3833] for a description of DNS weaknesses, and see + [RFC4033] for a countermeasure.</p> </li> <li> <p>The client IP address, <ip>, is assumed to be correct. -In a modern, correctly configured system, the risk of this not -being true is nil.</p> + In a modern, correctly configured system, the risk of this not + being true is nil.</p> </li> </ul> </div> </div> <div class="sect2"> -<h3 id="_cross_user_forgery"><a class="anchor" href="#_cross_user_forgery"></a>11.4. Cross-User Forgery</h3> +<h3 id="_cross_user_forgery">Cross-User Forgery</h3> <div class="paragraph"> <p>By definition, SPF policies just map domain names to sets of authorized MTAs, not whole email addresses to sets of authorized users. -Although the "l" macro (Section 7) provides a limited way to define +Although the "l" macro (Section 7) provides a limited way to define individual sets of authorized MTAs for specific email addresses, it is generally impossible to verify, through SPF, the use of specific email addresses by individual users of the same MTA.</p> @@ -2478,11 +2496,11 @@ cryptography, such as Pretty Good Privacy (PGP) ([RFC4880]) or S/MIME </div> </div> <div class="sect2"> -<h3 id="_untrusted_information_sources"><a class="anchor" href="#_untrusted_information_sources"></a>11.5. Untrusted Information Sources</h3> +<h3 id="_untrusted_information_sources">Untrusted Information Sources</h3> <div class="paragraph"> <p>An SPF-compliant receiver gathers information from the SMTP commands it receives and from the published DNS records of the sending domain -holder (e.g., "HELO" domain name, the "MAIL FROM" address from the +holder (e.g., "HELO" domain name, the "MAIL FROM" address from the envelope, and SPF DNS records published by the domain holder). These parameters are not validated in the SMTP process.</p> </div> @@ -2492,7 +2510,7 @@ the authority of the receiver, and thus are not guaranteed to be accurate or legitimate.</p> </div> <div class="sect3"> -<h4 id="_recorded_results"><a class="anchor" href="#_recorded_results"></a>11.5.1. Recorded Results</h4> +<h4 id="_recorded_results">Recorded Results</h4> <div class="paragraph"> <p>This information, passed to the receiver in the Received-SPF: or Authentication-Results: trace fields, can be returned to the client @@ -2503,7 +2521,7 @@ characters and excessively long lines.</p> </div> </div> <div class="sect3"> -<h4 id="_external_explanations"><a class="anchor" href="#_external_explanations"></a>11.5.2. External Explanations</h4> +<h4 id="_external_explanations">External Explanations</h4> <div class="paragraph"> <p>When the authorization check fails, an explanation string could be included in the reject response. @@ -2514,13 +2532,13 @@ The explanation can contain malicious URLs, or it might be offensive or misleading.</p> </div> <div class="paragraph"> -<p>Explanations returned to sender domains due to "exp" modifiers +<p>Explanations returned to sender domains due to "exp" modifiers (Section 6.2) were generated by the sender policy published by the domain holders themselves. As long as messages are only returned with non-delivery notifications ([RFC3464]) to domains publishing the explanation strings from their own DNS SPF records, the only affected parties are the original -publishers of the domain’s SPF records.</p> +publishers of the domain's SPF records.</p> </div> <div class="paragraph"> <p>In practice, such non-delivery notifications can be misdirected, such @@ -2530,7 +2548,7 @@ direct the bounce back to the original sender.</p> </div> </div> <div class="sect3"> -<h4 id="_macro_expansion"><a class="anchor" href="#_macro_expansion"></a>11.5.3. Macro Expansion</h4> +<h4 id="_macro_expansion">Macro Expansion</h4> <div class="paragraph"> <p>Macros (Section 7) allow senders to inject arbitrary text (any non-null [US-ASCII] character) into receiver DNS queries. @@ -2539,11 +2557,11 @@ It is necessary to be prepared for hostile or unexpected content.</p> </div> </div> <div class="sect2"> -<h3 id="_privacy_exposure"><a class="anchor" href="#_privacy_exposure"></a>11.6. Privacy Exposure</h3> +<h3 id="_privacy_exposure">Privacy Exposure</h3> <div class="paragraph"> <p>Checking SPF records causes DNS queries to be sent to the domain owner. -These DNS queries, especially if they are caused by the "exists" +These DNS queries, especially if they are caused by the "exists" mechanism, can contain information about who is sending email and likely to which MTA the email is being sent. This can introduce some privacy concerns, which are more or less of an @@ -2552,13 +2570,13 @@ and the person sending the email.</p> </div> </div> <div class="sect2"> -<h3 id="_delivering_mail_producing_a_fail_result"><a class="anchor" href="#_delivering_mail_producing_a_fail_result"></a>11.7. Delivering Mail Producing a "Fail" Result</h3> +<h3 id="_delivering_mail_producing_a_fail_result">Delivering Mail Producing a "Fail" Result</h3> <div class="paragraph"> -<p>Operators that choose to deliver mail for which SPF produces a "fail" +<p>Operators that choose to deliver mail for which SPF produces a "fail" result need to understand that they are admitting content that is explicitly not authorized by the purported sender. -While there are known failure modes that can be considered "false -negatives", the distinct choice to admit those messages increases +While there are known failure modes that can be considered "false +negatives", the distinct choice to admit those messages increases end-user exposure to likely harm. This is especially true for domains belonging to known good actors that are typically well-behaved; unauthorized mail from those sources @@ -2574,11 +2592,16 @@ Those notions are out of scope for this specification.</p> </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-05-18 01:23:21 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/doc/style.css b/doc/style.css index 9d0b73ce..d1f04a00 100644 --- a/doc/style.css +++ b/doc/style.css @@ -1,13 +1,10 @@ body { margin: 0; - font-family: sans-serif; + font-family: Arial, sans-serif; background-color: #fff; line-height: 1.3; - color: black; -} -a { - text-decoration: none; - color: #375eab; + text-align: center; + color: #222; } pre, code { @@ -21,15 +18,20 @@ pre { padding: 0.625rem; border-radius: 0.3125rem; } +a { + color: #375eab; + text-decoration: none; +} +a:hover { + text-decoration: underline; +} + p, li { max-width: 50rem; word-wrap: break-word; } -p, -pre, -ul, -ol { +pre { margin: 1.25rem; } @@ -117,6 +119,7 @@ dd { } .topbar .top-heading a { color: #222; + text-decoration: none; } .topbar .menu { @@ -130,17 +133,31 @@ dd { border: 0.0625rem solid #375eab; border-radius: 5px; } +.page { + width: 100%; +} -/** Custom classes for asciidoc */ -.article { - padding: 0px 1.25em; +.page > .container, +.topbar > .container { + text-align: left; + margin-left: auto; + margin-right: auto; + padding: 0 1.25rem; +} + +.footer { + text-align: center; + color: #666; + font-size: 0.875rem; + margin: 2.5rem 0; } + +/** Custom classes for asciidoc */ #toctitle { display: none; } #toc { - margin: 0px; - padding: 0px; + font-size: 14px; } #toc li { list-style: none; @@ -153,34 +170,6 @@ dd { margin: 4px; } -h1 a.anchor, -h2 a.anchor, -h3 a.anchor, -h4 a.anchor, -h5 a.anchor, -h6 a.anchor { - visibility: hidden; - color: #375eab; -} - -h1 a.anchor:before, -h2 a.anchor:before, -h3 a.anchor:before, -h4 a.anchor:before, -h5 a.anchor:before, -h6 a.anchor:before { - content: "¶ "; -} - -h1:hover > a.anchor, -h2:hover > a.anchor, -h3:hover > a.anchor, -h4:hover > a.anchor, -h5:hover > a.anchor, -h6:hover > a.anchor { - visibility: visible; -} - @media screen and (max-width: 992px) { #toc { all: unset; diff --git a/html.tmpl b/html.tmpl new file mode 100644 index 00000000..6f0a4aa6 --- /dev/null +++ b/html.tmpl @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>{{.Title}}</title> + {{- range .Styles}} + <link rel="stylesheet" href="{{.}}" /> + {{- end}} + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>{{.Title}}</h1> + {{.Body}} + </div> + <!-- .container --> + </div> + <!-- .page --> + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/lib/contact/README.html b/lib/contact/README.html new file mode 100644 index 00000000..458931a0 --- /dev/null +++ b/lib/contact/README.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title></title> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1></h1> + <p><a href="https://godoc.org/github.com/shuLhan/share/lib/contact"><img src="https://godoc.org/github.com/shuLhan/share/lib/contact?status.svg" alt="GoDoc"></a> +<a href="https://goreportcard.com/report/github.com/shuLhan/share/lib/contact"><img src="https://goreportcard.com/badge/github.com/shuLhan/share/lib/contact" alt="Go Report Card"></a></p> +<h1>contact</h1> +<p>The Go library to manage contacts.</p> +<h2>Features</h2> +<ul> +<li>Import Google's contacts v3 with OAuth2</li> +<li>Import Yahoo's contacts with OAuth2</li> +<li>Import Microsoft's Live/Outlook contacts with OAuth2</li> +</ul> +<h2>TODO</h2> +<ul> +<li>VCard 4.0 Encode and Decode</li> +</ul> + + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/lib/dsv/README.html b/lib/dsv/README.html new file mode 100644 index 00000000..cf1c2e8b --- /dev/null +++ b/lib/dsv/README.html @@ -0,0 +1,365 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title></title> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1></h1> + <p><a href="https://godoc.org/github.com/shuLhan/share/lib/dsv"><img src="https://godoc.org/github.com/shuLhan/share/lib/dsv?status.svg" alt="GoDoc"></a> +<a href="https://goreportcard.com/report/github.com/shuLhan/share/lib/dsv"><img src="https://goreportcard.com/badge/github.com/shuLhan/share/lib/dsv" alt="Go Report Card"></a></p> +<p>Package <code>dsv</code> is a Go library for working with delimited separated value (DSV).</p> +<p>DSV is a free-style form of CSV format of text data, where each record is +separated by newline, and each column can be separated by any string, not just +comma.</p> +<ul> +<li><a href="#example">Example</a></li> +<li><a href="#terminology">Terminology</a></li> +<li><a href="#configuration">Configuration</a> +<ul> +<li><a href="#metadata">Metadata</a></li> +<li><a href="#input">Input</a> +<ul> +<li><a href="#datasetmode-explained">DatasetMode Explained</a></li> +</ul> +</li> +<li><a href="#output">Output</a></li> +</ul> +</li> +<li><a href="#working-with-dsv">Working with DSV</a> +<ul> +<li><a href="#processing-each-rowscolumns">Processing each Rows/Columns</a></li> +<li><a href="#using-different-dataset">Using different Dataset</a></li> +<li><a href="#builtin-functions-for-dataset">Builtin Functions for Dataset</a></li> +</ul> +</li> +<li><a href="#limitations">Limitations</a></li> +</ul> +<hr> +<h2>Example</h2> +<p>Lets process this input file <code>input.dat</code>,</p> +<pre><code>Mon Dt HH MM SS Process +Nov 29 23:14:36 process-1 +Nov 29 23:14:37 process-2 +Nov 29 23:14:38 process-3 +</code></pre> +<p>and generate output file <code>output.dat</code> which format like this,</p> +<pre><code>"process_1","29-Nov" +"process_2","29-Nov" +"process_3","29-Nov" +</code></pre> +<p>How do we do it?</p> +<p>First, create file metadata for input and output, name it <code>config.dsv</code>,</p> +<pre><code>{ + "Input" :"input.dat" +, "Skip" :1 +, "InputMetadata" : + [{ + "Name" :"month" + , "Separator" :" " + },{ + "Name" :"date" + , "Separator" :" " + , "Type" :"integer" + },{ + "Name" :"hour" + , "Separator" :":" + , "Type" :"integer" + },{ + "Name" :"minute" + , "Separator" :":" + , "Type" :"integer" + },{ + "Name" :"second" + , "Separator" :" " + , "Type" :"integer" + },{ + "Name" :"process_name" + , "Separator" :"-" + },{ + "Name" :"process_id" + }] +, "Output" :"output.dat" +, "OutputMetadata": + [{ + "Name" :"process_name" + , "LeftQuote" :"\"" + , "Separator" :"_" + },{ + "Name" :"process_id" + , "RightQuote":"\"" + , "Separator" :"," + },{ + "Name" :"date" + , "LeftQuote" :"\"" + , "Separator" :"-" + },{ + "Name" :"month" + , "RightQuote":"\"" + }] +} +</code></pre> +<p>The metadata is using JSON format. For more information see <code>metadata.go</code> +and <code>reader.go</code>.</p> +<p>Second, we create a reader to read the input file.</p> +<pre><code>dsvReader, e := dsv.NewReader("config.dsv", nil) + +if nil != e { + t.Fatal(e) +} +</code></pre> +<p>Third, we create a writer to write our output data,</p> +<pre><code>dsvWriter, e := dsv.NewWriter("config.dsv") + +if nil != e { + t.Error(e) +} +</code></pre> +<p>Last action, we process them: read input records and pass them to writer.</p> +<pre><code>for { + n, e := dsv.Read(dsvReader) + + if n > 0 { + dsvWriter.Write(dsvReader) + + // EOF, no more record. + } else if e == io.EOF { + break + } +} + +// we will make sure all open descriptor is closed. +_ = dsvReader.Close() +</code></pre> +<p>Easy enough? We can combine the reader and writer using <code>dsv.New()</code>, which will +create reader and writer,</p> +<pre><code>rw, e := dsv.New("config.dsv", nil) + +if nil != e { + t.Error(e) +} + +// do usual process like in the last step. +</code></pre> +<p>Thats it!</p> +<h2>Terminology</h2> +<p>Here are some terminology that we used in developing this library, which may +help reader understanding the configuration and API.</p> +<ul> +<li>Dataset: is a content of file</li> +<li>Record: a single cell in row or column, or the smallest building block of +dataset</li> +<li>Row: is a horizontal representation of records in dataset</li> +<li>Column: is a vertical representation of records in dataset</li> +</ul> +<pre><code> COL-0 COL-1 ... COL-x +ROW-0: record record ... record +ROW-1: record record ... record +... +ROW-y: record record ... record +</code></pre> +<h2>Configuration</h2> +<p>We choose and use JSON for configuration because,</p> +<ol> +<li>No additional source to test.</li> +<li>Easy to extended. User can embed the current metadata, add additional +configuration, and create another reader to work with it.</li> +</ol> +<h3>Metadata</h3> +<p>Metadata contain information about each column when reading input file and +writing to output file,</p> +<ul> +<li><code>Name</code>: mandatory, the name of column</li> +<li><code>Type</code>: optional, type of record when reading input file. Valid value are +"integer", "real", or "string" (default)</li> +<li><code>Separator</code>: optional, default to <code>"\n"</code>. Separator is a string that +separate the current record with the next record.</li> +<li><code>LeftQuote</code>: optional, default is empty <code>""</code>. LeftQuote is a string that +start at the beginning of record.</li> +<li><code>RightQuote</code>: optional, default is empty <code>""</code>. RightQuote is a string at the +end of record.</li> +<li><code>Skip</code>: optional, boolean, default is <code>false</code>. If true the column will be +saved in dataset when reading input file, otherwise it will be ignored.</li> +<li><code>ValueSpace</code>: optional, slice of string, default is empty. This contain the +string representation of all possible value in column.</li> +</ul> +<h3>Input</h3> +<p>Input configuration contain information about input file.</p> +<ul> +<li><code>Input</code>: mandatory, the name of input file, could use relative or absolute +path. If no path is given then it assumed that the input file is in the same +directory with configuration file.</li> +<li><code>InputMetadata</code>: mandatory, list of metadata.</li> +<li><code>Skip</code>: optional, number, default 0. Skip define the number of line that will +be skipped when first input file is opened.</li> +<li><code>TrimSpace</code>: optional, boolean, default is true. If its true, before parsed, the +white space in the beginning and end of each input line will be removed, +otherwise it will leave unmodified.</li> +<li><code>Rejected</code>: optional, default to <code>rejected.dat</code>. Rejected is file where +data that does not match with metadata will be saved. One can inspect the +rejected file fix it for re-process or ignore it.</li> +<li><code>MaxRows</code>: optional, default to <code>256</code>. Maximum number of rows for one read +operation that will be saved in memory. If its negative, i.e. <code>-1</code>, all data +in input file will be processed.</li> +<li><code>DatasetMode</code>: optional, default to "rows". Mode of dataset in memory. +Valid values are "rows", "columns", or "matrix". Matrix mode is combination of +rows and columns, it give more flexibility when processing the dataset but +will require additional memory.</li> +</ul> +<h4><code>DatasetMode</code> Explained</h4> +<p>For example, given input data file,</p> +<pre><code>col1,col2,col3 +a,b,c +1,2,3 +</code></pre> +<p>"rows" mode is where each line saved in its own slice, resulting in Rows:</p> +<pre><code>Rows[0]: [a b c] +Rows[1]: [1 2 3] +</code></pre> +<p>"columns" mode is where each line saved by columns, resulting in Columns:</p> +<pre><code>Columns[0]: {col1 0 0 [] [a 1]} +Columns[1]: {col2 0 0 [] [b 2]} +Columns[1]: {col3 0 0 [] [c 3]} +</code></pre> +<p>Unlike rows mode, each column contain metadata including column name, type, +flag, and value space (all possible value that <em>may</em> contain in column value).</p> +<p>"matrix" mode is where each record saved both in row and column.</p> +<h3>Output</h3> +<p>Output configuration contain information about output file when writing the +dataset.</p> +<ul> +<li><code>Output</code>: mandatory, the name of output file, could use relative or absolute +path. If no path is given then it assumed that the output file is in the same +directory with configuration file.</li> +<li><code>OutputMetadata</code>: mandatory, list of metadata.</li> +</ul> +<h2>Working with DSV</h2> +<h3>Processing each Rows/Columns</h3> +<p>After opening the input file, we can process the dataset based on rows/columns +mode using simple <code>for</code> loop. Example,</p> +<pre><code>// Save dataset object for used later. +dataset := dsvReader.GetDataset().(tabula.DatasetInterface) + +for { + n, e := dsv.Read(dsvReader) + + if n > 0 { + // Process each row ... + for x, row := dataset.GetDataAsRows() { + + for y, record := range row.Records { + // process each record in row + } + } + + // Or, process each columns + for x, column := dataset.GetDataAsColumns() { + + for y, record := range column.Records { + // process each record in column + } + } + + // Write the dataset to file after processed + dsvWriter.Write(dsvReader) + } + if e == io.EOF { + break + } + if e != nil { + // handle error + } +} +</code></pre> +<h3>Using different Dataset</h3> +<p>Default dataset used by Reader is +<a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#Dataset">tabula.Dataset</a>.</p> +<p>You can extend and implement +<a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#DatasetInterface">DatasetInterface</a> +and use it in reader object, either by</p> +<ul> +<li> +<p>passing it in the second parameter in <code>NewReader</code>, for example,</p> +<pre><code>myset := MySet{ + ... +} +reader, e := dsv.NewReader("config.dsv", &myset) +</code></pre> +</li> +<li> +<p>or by calling <code>reader.Init</code> after creating new Reader,</p> +<pre><code>myset := MySet{ + ... +} +reader := dsv.Reader{ + ... +} +reader.Init("config.dsv", &myset) +</code></pre> +</li> +</ul> +<h3>Builtin Functions for Dataset</h3> +<p>Since we use tabula package to manage data, any features in those package +can be used in our dataset. +For more information see <a href="https://godoc.org/github.com/shuLhan/share/lib/tabula">tabula +package</a>.</p> +<h2>Limitations</h2> +<ul> +<li> +<p>New line is <code>\n</code> for each row.</p> +</li> +<li> +<p>Reader and Writer operate in ASCII (8 bit or char type), UTF-8 is not +supported yet, since we can not test it. Patch for supporting UTF-8 (or +runes type) are welcome.</p> +</li> +<li> +<p>About escaped character in content of data.</p> +<p>Since we said that we handle free-style form of CSV, what we mean was the +left-quote, right-quote and separator can be string. Its not only one single +character like single quote or double quote or any single character, but +literally one or more characters without space. Any escaped character will be +read as is (along with <code>'\'</code>) unless its followed by right-quote or separator. +For example,</p> +<pre><code>"test\'" +</code></pre> +<p>will be readed as <code>test\'</code>. But</p> +<pre><code>"test\"" +</code></pre> +<p>will be readed as <code>test"</code>, since the right-quote is matched with escaped +token.</p> +</li> +</ul> + + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/lib/mining/README.html b/lib/mining/README.html new file mode 100644 index 00000000..76909fc1 --- /dev/null +++ b/lib/mining/README.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title></title> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1></h1> + <p><a href="https://godoc.org/github.com/shuLhan/share/lib/mining"><img src="https://godoc.org/github.com/shuLhan/share/lib/mining?status.svg" alt="GoDoc"></a> +<a href="https://goreportcard.com/report/github.com/shuLhan/share/lib/mining"><img src="https://goreportcard.com/badge/github.com/shuLhan/share/lib/mining" alt="Go Report Card"></a></p> +<h1>go-mining</h1> +<p>Go-mining is a small library for data mining.</p> +<p>The library is written in <a href="golang/go">Go language</a>.</p> +<h2>Features</h2> +<h3>Classifiers</h3> +<ul> +<li>CART</li> +<li>Random Forest</li> +<li>Cascaded Random Forest</li> +<li>K-Nearest Neighbourhood</li> +</ul> +<h3>Resampling</h3> +<ul> +<li>SMOTE</li> +<li>LN-SMOTE (Local Neigbourhood SMOTE)</li> +</ul> +<h3>Miscellaneous</h3> +<ul> +<li>Gini index</li> +</ul> + + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/lib/numbers/README.html b/lib/numbers/README.html new file mode 100644 index 00000000..22ec9243 --- /dev/null +++ b/lib/numbers/README.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title></title> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1></h1> + <p><a href="https://godoc.org/github.com/shuLhan/share/lib/numbers"><img src="https://godoc.org/github.com/shuLhan/share/lib/numbers?status.svg" alt="GoDoc"></a> +<a href="https://goreportcard.com/report/github.com/shuLhan/share/lib/numbers"><img src="https://goreportcard.com/badge/github.com/shuLhan/share/lib/numbers" alt="Go Report Card"></a></p> +<p>Package <code>numbers</code> provide functions for working with integer, float, slice of +integers, and slice of floats.</p> +<p>Currently it have function to,</p> +<ul> +<li>sort slice of floats using in-place mergesort algorithm</li> +<li>sort slice of integer/floats by predefined index</li> +<li>count number of value occurence in slice of integer/float</li> +<li>find minimum or maximum value in slice of integer/float</li> +<li>sum slice of integer/float</li> +</ul> +<p>See <a href="https://godoc.org/github.com/shuLhan/share/lib/numbers">documentation</a> +for more information.</p> + + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/lib/tabula/README.html b/lib/tabula/README.html new file mode 100644 index 00000000..ca10e819 --- /dev/null +++ b/lib/tabula/README.html @@ -0,0 +1,177 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title></title> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1></h1> + <p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula"><img src="https://godoc.org/github.com/shuLhan/share/lib/tabula?status.svg" alt="GoDoc"></a> +<a href="https://goreportcard.com/report/github.com/shuLhan/share/lib/tabula"><img src="https://goreportcard.com/badge/github.com/shuLhan/share/lib/tabula" alt="Go Report Card"></a> +<img src="https://cover.run/go/github.com/shuLhan/share/lib/tabula.svg" alt="cover.run go"></p> +<p>Package tabula is a Go library for working with rows, columns, or matrix +(table), or in another terms working with data set.</p> +<h1>Overview</h1> +<p>Go's slice gave a flexible way to manage sequence of data in one type, but what +if you want to manage a sequence of value but with different type of data? +Or manage a bunch of values like a table?</p> +<p>You can use this library to manage sequence of value with different type +and manage data in two dimensional tuple.</p> +<h2>Terminology</h2> +<p>Here are some terminologies that we used in developing this library, which may +help reader understand the internal and API.</p> +<p>Record is a single cell in row or column, or the smallest building block of +dataset.</p> +<p>Row is a horizontal representation of records in dataset.</p> +<p>Column is a vertical representation of records in dataset. +Each column has a unique name and has the same type data.</p> +<p>Dataset is a collection of rows and columns.</p> +<p>Given those definitions we can draw the representation of rows, columns, or +matrix:</p> +<pre><code> COL-0 COL-1 ... COL-x +ROW-0: record record ... record +ROW-1: record record ... record +... +ROW-y: record record ... record +</code></pre> +<h2>What make this package different from other dataset packages?</h2> +<h3>Record Type</h3> +<p>There are only three valid type in record: int64, float64, and string.</p> +<p>Each record is a pointer to interface value. Which means,</p> +<ul> +<li>Switching between rows to columns mode, or vice versa, is only a matter of +pointer switching, no memory relocations.</li> +<li>When using matrix mode, additional memory is used only to allocate slice, the +record in each rows and columns is shared.</li> +</ul> +<h3>Dataset Mode</h3> +<p>Tabula has three mode for dataset: rows, columns, or matrix.</p> +<p>For example, given a table of data,</p> +<pre><code>col1,col2,col3 +a,b,c +1,2,3 +</code></pre> +<ul> +<li> +<p>When in "rows" mode, each line is saved in its own slice, resulting in Rows:</p> +<pre><code>Rows[0]: [a b c] +Rows[1]: [1 2 3] +</code></pre> +<p>Columns is used only to save record metadata: column name, type, flag and +value space.</p> +</li> +<li> +<p>When in "columns" mode, each line saved in columns, resulting in Columns:</p> +<pre><code>Columns[0]: {col1 0 0 [] [a 1]} +Columns[1]: {col2 0 0 [] [b 2]} +Columns[1]: {col3 0 0 [] [c 3]} +</code></pre> +<p>Each column will contain metadata including column name, type, flag, and +value space (all possible value that <em>may</em> contain in column value).</p> +<p>Rows in "columns" mode is empty.</p> +</li> +<li> +<p>When in "matrix" mode, each record is saved both in row and column using +shared pointer to record.</p> +<p>Matrix mode consume more memory by allocating two slice in rows and columns, +but give flexible way to manage records.</p> +</li> +</ul> +<h2>Features</h2> +<ul> +<li> +<p><strong>Switching between rows and columns mode</strong>.</p> +</li> +<li> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#RandomPickRows"><strong>Random pick rows with or without replacement</strong></a>.</p> +</li> +<li> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#RandomPickColumns"><strong>Random pick columns with or without replacement</strong></a>.</p> +</li> +<li> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#SelectColumnsByIdx"><strong>Select column from dataset by index</strong></a>.</p> +</li> +<li> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#SortColumnsByIndex"><strong>Sort columns by index</strong></a>, +or indirect sort.</p> +</li> +<li> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#SplitRowsByNumeric"><strong>Split rows value by numeric</strong></a>. +For example, given two numeric rows,</p> +<pre><code>A: {1,2,3,4} +B: {5,6,7,8} +</code></pre> +<p>if we split row by value 7, the data will splitted into left set</p> +<pre><code>A': {1,2} +B': {5,6} +</code></pre> +<p>and the right set would be</p> +<pre><code>A'': {3,4} +B'': {7,8} +</code></pre> +</li> +<li> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#SplitRowsByCategorical"><strong>Split rows by string</strong></a>. +For example, given two rows,</p> +<pre><code>X: [A,B,A,B,C,D,C,D] +Y: [1,2,3,4,5,6,7,8] +</code></pre> +<p>if we split the rows with value set <code>[A,C]</code>, the data will splitted into left +set which contain all rows that have A or C,</p> +<pre><code> X': [A,A,C,C] + Y': [1,3,5,7] +</code></pre> +<p>and the right set, excluded set, will contain all rows which is not A or C,</p> +<pre><code> X'': [B,B,D,D] + Y'': [2,4,6,8] +</code></pre> +</li> +<li> +<p><a href="https://godoc.org/github.com/shuLhan/share/lib/tabula#SelectRowsWhere"><strong>Select row where</strong></a>. +Select row at column index x where their value is equal to y (an analogy to +<em>select where</em> in SQL). +For example, given a rows of dataset,</p> +<pre><code>ROW-1: {1,A} +ROW-2: {2,B} +ROW-3: {3,A} +ROW-4: {4,C} +</code></pre> +<p>we can select row where the second column contain 'A', which result in,</p> +<pre><code>ROW-1: {1,A} +ROW-3: {3,A} +</code></pre> +</li> +</ul> + + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/lib/websocket/AUTOBAHN.html b/lib/websocket/AUTOBAHN.html index 8f339c86..f8e58fa3 100644 --- a/lib/websocket/AUTOBAHN.html +++ b/lib/websocket/AUTOBAHN.html @@ -1,20 +1,31 @@ <!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="UTF-8"> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<meta name="generator" content="Asciidoctor 2.0.9"> -<title>Autobahn WebSocket Testsuite Status Report</title> -<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> -<link rel="stylesheet" href="./asciidoctor.css"> -</head> -<body class="article"> -<div id="header"> -<h1>Autobahn WebSocket Testsuite Status Report</h1> -</div> -<div id="content"> -<div id="preamble"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title>Autobahn WebSocket Testsuite Status Report</title> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1>Autobahn WebSocket Testsuite Status Report</h1> + <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> <p>This document track the status report from autobahn testsuite [1].</p> @@ -30,10 +41,10 @@ package,</p> </div> <div class="literalblock"> <div class="content"> -<pre>$ cd testdata -$ virtualenv . -$ source ./bin/activate -$ pip install autobahntestsuite</pre> +<pre> $ cd testdata + $ virtualenv . + $ source ./bin/activate + $ pip install autobahntestsuite</pre> </div> </div> </div> @@ -46,9 +57,9 @@ $ pip install autobahntestsuite</pre> </div> <div class="literalblock"> <div class="content"> -<pre>$ cd testdata/server -$ go build . -$ ./server</pre> +<pre> $ cd testdata/server + $ go build . + $ ./server</pre> </div> </div> <div class="paragraph"> @@ -56,14 +67,14 @@ $ ./server</pre> </div> <div class="literalblock"> <div class="content"> -<pre>$ cd testdata/server -$ source ../bin/activate -$ wstest -m fuzzingclient</pre> +<pre> $ cd testdata/server + $ source ../bin/activate + $ wstest -m fuzzingclient</pre> </div> </div> <div class="paragraph"> <p>Wait for the test to complete. After that, we can view the reports on -"reports/index.html".</p> +"reports/index.html".</p> </div> <div class="sect2"> <h3 id="_server_reports_status">Server Reports Status</h3> @@ -166,8 +177,8 @@ points (11/11) </ol> </div> <div class="paragraph"> -<p>Total test cases : 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301 -Total success cases: 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301</p> +<p>Total test cases : 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301 +Total success cases: 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301</p> </div> <div class="paragraph"> <p>Success Rate = 100%</p> @@ -183,9 +194,9 @@ Total success cases: 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = </div> <div class="literalblock"> <div class="content"> -<pre>$ cd testdata/client -$ source ../bin/activate -$ wstest -m fuzzingserver</pre> +<pre> $ cd testdata/client + $ source ../bin/activate + $ wstest -m fuzzingserver</pre> </div> </div> <div class="paragraph"> @@ -193,15 +204,15 @@ $ wstest -m fuzzingserver</pre> </div> <div class="literalblock"> <div class="content"> -<pre>$ cd testdata/client -$ go build . -$ ./client</pre> +<pre> $ cd testdata/client + $ go build . + $ ./client</pre> </div> </div> <div class="paragraph"> <p>Wait for the test to complete. After that, open the browser at -<a href="http://127.0.0.1:8080/test_browser.html" class="bare">http://127.0.0.1:8080/test_browser.html</a> , and click on "Update Reports -(Manual)" to update client reports at "testdata/client/reports/index.html".</p> +<a href="http://127.0.0.1:8080/test_browser.html , and click on "Update Reports" class="bare">http://127.0.0.1:8080/test_browser.html , and click on "Update Reports</a> +(Manual)" to update client reports at "testdata/client/reports/index.html".</p> </div> <div class="sect2"> <h3 id="_client_reports_status">Client Reports Status</h3> @@ -304,8 +315,8 @@ points (11/11) </ol> </div> <div class="paragraph"> -<p>Total test cases : 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301 -Total success cases: 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301</p> +<p>Total test cases : 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301 +Total success cases: 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = 301</p> </div> <div class="paragraph"> <p>Success Rate = 100%</p> @@ -321,11 +332,16 @@ Total success cases: 16 + 11 + 7 + 10 + 20 + 145 + 37 + 0 + 54 + 1 + 0 + 0 + 0 = </div> </div> </div> -</div> -<div id="footer"> -<div id="footer-text"> -Last updated 2019-04-04 13:49:10 +0700 -</div> -</div> -</body> -</html>
\ No newline at end of file + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> diff --git a/lib/websocket/BENCHMARK.html b/lib/websocket/BENCHMARK.html new file mode 100644 index 00000000..93ea2c24 --- /dev/null +++ b/lib/websocket/BENCHMARK.html @@ -0,0 +1,175 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#375EAB" /> + + <title></title> + </head> + <body> + <div class="topbar"> + <div class="container"> + <div class="top-heading"> + <a href="/">github.com/shuLhan/share</a> + </div> + <div class="menu"> + <a href="https://godoc.org/github.com/shuLhan/share">GoDoc</a> + </div> + <div class="menu"> + <a href="/CHANGELOG.html">Changelog</a> + </div> + </div> + </div> + + <div class="page"> + <div class="container"> + <h1></h1> + <p>This note document a benchmark between gobwas vs our websocket library.</p> +<h1>github.com/gobwas/ws@v0.1.0</h1> +<h2>Go v1.10.3</h2> +<pre><code>goos: linux +goarch: amd64 +pkg: github.com/gobwas/ws +BenchmarkUpgrader/base-8 5000000 377 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/lowercase-8 5000000 380 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/uppercase-8 5000000 394 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/subproto-8 3000000 529 ns/op 1 B/op 1 allocs/op +BenchmarkUpgrader/subproto_comma-8 3000000 453 ns/op 1 B/op 1 allocs/op +BenchmarkUpgrader/#00-8 1000000 1824 ns/op 1354 B/op 4 allocs/op +BenchmarkUpgrader/bad_http_method-8 10000000 143 ns/op 3 B/op 1 allocs/op +BenchmarkUpgrader/bad_http_proto-8 10000000 135 ns/op 3 B/op 1 allocs/op +BenchmarkUpgrader/bad_host-8 10000000 224 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade-8 10000000 215 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade#01-8 10000000 235 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade#02-8 10000000 229 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection-8 10000000 216 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection#01-8 10000000 175 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version_x-8 10000000 216 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version-8 5000000 237 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_key-8 5000000 379 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_key#01-8 5000000 382 ns/op 0 B/op 0 allocs/op +PASS +ok github.com/gobwas/ws 58.827s +</code></pre> +<h2>Go version devel +d6a27e8edc</h2> +<pre><code>goos: linux +goarch: amd64 +pkg: github.com/gobwas/ws +BenchmarkUpgrader/base-8 5000000 378 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/lowercase-8 5000000 374 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/uppercase-8 5000000 398 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/subproto-8 3000000 533 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/subproto_comma-8 3000000 449 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/#00-8 1000000 1653 ns/op 1354 B/op 4 allocs/op +BenchmarkUpgrader/bad_http_method-8 10000000 142 ns/op 3 B/op 1 allocs/op +BenchmarkUpgrader/bad_http_proto-8 10000000 138 ns/op 3 B/op 1 allocs/op +BenchmarkUpgrader/bad_host-8 10000000 219 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade-8 10000000 217 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade#01-8 5000000 233 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade#02-8 5000000 227 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection-8 10000000 215 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection#01-8 10000000 176 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version_x-8 10000000 217 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version-8 5000000 266 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_key-8 5000000 398 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_key#01-8 5000000 391 ns/op 0 B/op 0 allocs/op +PASS +ok github.com/gobwas/ws 57.334s +</code></pre> +<h1>github.com/shuLhan/share/lib/websocket</h1> +<h2>Go v1.10.3</h2> +<pre><code>goos: linux +goarch: amd64 +pkg: github.com/shuLhan/share/lib/websocket +BenchmarkUpgrader/base-8 5000000 339 ns/op 176 B/op 1 allocs/op +BenchmarkUpgrader/lowercase-8 5000000 358 ns/op 176 B/op 1 allocs/op +BenchmarkUpgrader/uppercase-8 5000000 352 ns/op 176 B/op 1 allocs/op +BenchmarkUpgrader/subproto-8 10000000 172 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/subproto_comma-8 3000000 389 ns/op 176 B/op 1 allocs/op +BenchmarkUpgrader/#00-8 10000000 174 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_http_method-8 100000000 23.8 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_http_proto-8 50000000 29.3 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_host-8 100000000 23.1 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade-8 100000000 23.2 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade#01-8 3000000 440 ns/op 453 B/op 6 allocs/op +BenchmarkUpgrader/bad_upgrade#02-8 10000000 167 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection-8 50000000 24.4 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection#01-8 20000000 108 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version_x-8 50000000 24.2 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version-8 10000000 138 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_key-8 5000000 343 ns/op 176 B/op 1 allocs/op +BenchmarkUpgrader/bad_sec_key#01-8 5000000 369 ns/op 176 B/op 1 allocs/op +PASS +ok github.com/shuLhan/share/lib/websocket 50.192s +</code></pre> +<h2>Go v1.12</h2> +<pre><code>websocket version: 8dec8c9 +Benchmark date : Thu 7 Mar 22:09:17 WIB 2019 + +goos: linux +goarch: amd64 +pkg: github.com/shuLhan/share/lib/websocket +BenchmarkUpgrader/base-8 10000000 165 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/lowercase-8 10000000 165 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/uppercase-8 10000000 163 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/subproto-8 10000000 133 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/subproto_comma-8 10000000 192 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/#00-8 10000000 144 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_http_method-8 50000000 25.4 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_http_proto-8 50000000 30.9 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_host-8 50000000 24.2 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade-8 50000000 24.3 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade#01-8 5000000 381 ns/op 453 B/op 6 allocs/op +BenchmarkUpgrader/bad_upgrade#02-8 10000000 133 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection-8 50000000 24.4 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection#01-8 20000000 91.8 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version_x-8 50000000 24.4 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version-8 20000000 112 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_key-8 10000000 165 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/bad_sec_key#01-8 10000000 166 ns/op 32 B/op 1 allocs/op +PASS +ok github.com/shuLhan/share/lib/websocket 49.379s +</code></pre> +<h2>Go version devel +05b3db24 (>1.12)</h2> +<pre><code>websocket version: 8dec8c9 +Benchmark date : Thu 7 Mar 22:09:17 WIB 2019 + +goos: linux +goarch: amd64 +pkg: github.com/shuLhan/share/lib/websocket +BenchmarkUpgrader/base-8 10000000 156 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/lowercase-8 10000000 160 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/uppercase-8 10000000 153 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/subproto-8 10000000 137 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/subproto_comma-8 10000000 181 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/#00-8 10000000 143 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_http_method-8 50000000 25.0 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_http_proto-8 50000000 31.6 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_host-8 50000000 24.6 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade-8 50000000 24.5 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_upgrade#01-8 5000000 372 ns/op 453 B/op 6 allocs/op +BenchmarkUpgrader/bad_upgrade#02-8 10000000 133 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection-8 100000000 23.4 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_connection#01-8 20000000 92.7 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version_x-8 100000000 23.3 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_version-8 20000000 113 ns/op 0 B/op 0 allocs/op +BenchmarkUpgrader/bad_sec_key-8 10000000 154 ns/op 32 B/op 1 allocs/op +BenchmarkUpgrader/bad_sec_key#01-8 10000000 157 ns/op 32 B/op 1 allocs/op +PASS +ok github.com/shuLhan/share/lib/websocket 52.285s +</code></pre> + + </div> + + </div> + + + <div class="footer"> + Copyright 2019, Shulhan <ms@kilabit.info>. All rights reserved. + <br /> + Use of this source code is governed by a BSD-style license that can be + found in the <a href="/LICENSE">LICENSE</a> file. + </div> + </body> +</html> |
