1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
GNU SASL examples/saml20/README -- Explanation of SMTP SAML 2.0 example.
Copyright (C) 2012-2025 Simon Josefsson
See the end for copying conditions.
This directory holds a GNU SASL example application that implements a
SMTP server with SAML 2.0 authentication support. The SAML
implementation used is Lasso: http://lasso.entrouvert.org/
It should be noted that this is just an example of how it could work.
You don't need to implement it this way. For example, sometimes
having a Apache/PHP web server running is a problem. Then you could
use something like MicroHTTPD and implement everything in one process
using Lasso in C. Then you don't need any IPC stuff. Also, you could
also want to use another SAML implementation instead of Lasso. The
point of this example is just to proof that it works.
This setup was tested with GNU SASL version 1.7.3.
There is one example SMTP server and some helper tools that implement
the actual SAML part:
smtp-server-saml20.c:
The actual SMTP server, based on ../smtp-server.c. It invokes
gsasl-saml20-request.c to generate the request, and then waits
for gsasl-saml20-sp.php to accept the SAML response.
gsasl-saml20-request.c
Given a Identity Provider identifier it generates a SAML Request
and prints a user redirect URL. This tool is invoked by
smtp-server-saml20.c. It uses Lasso as the SAML library.
gsasl-saml20-sp.php:
This is the SAML SP responsible for accepting SAML Responses.
Intended to be invoked via a webserver.
These three tools communicate with each other using a simple
file-based IPC interface, normally placed below /tmp/gsasl-saml20/.
Install the SAML SP:
The "gsasl-saml20-sp.php" script needs to be install so that it is
reachable under some URL via a web server. This is the
AssertionConsumerService (ACS) for the GNU SASL SP. For example, on
interop.josefsson.org I make the ACS available as
http://interop.josefsson.org/gsasl-saml20-sp.php
by copying the file into
/var/www/gsasl-saml20-sp.php
Configure the tool by specifying the state and configuration
directories in a file called gsasl-saml20-config.php in the same
directory, like this:
echo '<?php $state_path = "/tmp/gsasl-saml20"; $cfg_path = "/etc/gsasl-saml20"; ?>' > /var/www/gsasl-saml20-config.php
Of course you can chose different paths, but then you need to update
the paths accordingly in the rest of this documentation.
Create SAML SP configuration:
/etc/gsasl-saml20/sp-key.pem
/etc/gsasl-saml20/sp-crt.pem
This is a private key and certificate for your SP. It can be
self-signed. You may generate the files with GnuTLS like this:
certtool -p --outfile sp-key.pem
echo 'organization=My SP' > sp-crt.template
certtool --generate-self-signed --load-privkey sp-key.pem
--template sp-crt.template --outfile sp-crt.pem
Currently the private key is not used to sign requests.
/etc/gsasl-saml20/sp-metadata.xml
This is specific for your SP. Use sp-metadata.xml as a starting
point if you are unsure, and use a text editor to modify it. You
need to:
1) Change the entityID to something (the URL does not have to
resolve to anything, but should be unique to this SP).
2) Replace the ACS URL to point at your gsasl-saml20-sp.php.
3) Replace the certificate data (in two places) with the base64
data from sp-crt.pem.
4) Update with your contact information at the bottom.
You may want to make the SP metadata reachable over the web as
well, for example by doing:
ln -s /etc/gsasl-saml20/sp-metadata.xml /var/www/
/etc/gsasl-saml20/IDP/idp-metadata.xml
This is the XML metadata for each IdP. Replace "IDP" in the
filename with the Identity Provider Identifier you expect users to
type.
/etc/gsasl-saml20/openidp.feide.no/idp-metadata.xml
Here we used Feide OpenIdP as an example. The content of
idp-metadata.xml is retrieved from the IdP. For Feide OpenIdP you
can retrieve it from the following URL:
https://openidp.feide.no/simplesaml/saml2/idp/metadata.php
/etc/gsasl-saml20/idp.protectnetwork.org/idp-metadata.xml
As the second test IdP we used Protect Network. You can retrieve
the file from here:
http://www.protectnetwork.org/protectnetwork-metadata.xml
Lasso requires that the KeyDescriptor tags are qualified with
attributes use="signing" or use="encryption" respectively, so you
need to modify the file slightly.
Here is the normal process:
1) Start the example SMTP server "smtp-server-saml20", for example
when running it on the interop.josefsson.org server the following
is used:
su -c "env LD_LIBRARY_PATH=/root/gsasl/lib/src/.libs PATH=$PATH:/root/gsasl/examples/saml20 nohup /root/gsasl/examples/saml20/smtp-server-saml20 2001 /etc/gsasl-saml20 /tmp/gsasl-saml20 /etc/gsasl-saml20/sp-metadata.xml /etc/gsasl-saml20/sp-key.pem /etc/gsasl-saml20/sp-crt.pem 2>&1 | logger -t saml20" www-data &
For permission reasons, you should run the server under the same
user as the webserver runs gsasl-saml20-sp.php.
The "gsasl-saml20" tool takes some parameters, the port, the
configuration directory, the IPC directory, and the metadata, key
and certificate for the SP.
2) The smtp-server-saml20 receives incoming connections from clients.
The client sends the Identity Provider Identifier. You may use the
gsasl command line tool to act as a client. For example:
jas@latte:~$ gsasl --smtp -m SAML20 interop.josefsson.org 2001
Trying ‘interop.josefsson.org’...
220 localhost ESMTP GNU SASL smtp-server
EHLO [127.0.0.1]
250-localhost
250 AUTH ANONYMOUS EXTERNAL LOGIN PLAIN SECURID DIGEST-MD5 CRAM-MD5 SCRAM-SHA-1 SAML20 OPENID20
EHLO [127.0.0.1]
250-localhost
250 AUTH ANONYMOUS EXTERNAL LOGIN PLAIN SECURID DIGEST-MD5 CRAM-MD5 SCRAM-SHA-1 SAML20 OPENID20
AUTH SAML20
334
Enter SAML authentication identifier (e.g. "http://example.org/"):
At the prompt, you could type for example "openidp.feide.no".
3) smtp-server-saml20 invokes "gsasl-saml20-request" to get the
redirect URL, which is also stored in this file:
/tmp/gsasl-saml20/SESSIONID/redirect_url
The SESSIONID will be unique for every SAML Request, it looks for
example like "_B6F098F6D17C63796A9DF3BB63EF58AA".
4) The server continue with the SMTP authentication process, the
output from the gsasl client looks like:
biwsb3BlbmlkcC5mZWlkZS5ubw==
334 aHR0cHM6Ly9vcGVuaWRwLmZlaWRlLm5vL3NpbXBsZXNhbWwvc2FtbDIvaWRwL1NTT1NlcnZpY2UucGhwP1NBTUxSZXF1ZXN0PWZaRlBiNE13RE1XJTJGQ3NvZFFzdEthUVJJdEF5cDB2NVVZOXBobHltaXBzMFVraXdPM2ZidEIxU2R0a3N2UGp6N0p6OCUyRnA4ZzdhVmpSdTZONmdvOGUwSGxmblZUSXBrWkdlcXVZNWlpUUtkNEJNdGV3dXJpJTJGWSUyRk1nWk1acXB4c3R5UiUyRmtPc0VSd1RxaEZmRzJaVWJlMW5FVnJwSXFMbWZMVFJ3dFYzR3hLcXRvdlk2ajIycVJGQVh4WHNEaU1KJTJCUkFSOGd4QjYyQ2gxWGJwREMyZHdQYiUyRnhaOGh3bWJMRmcwZXlWZU9Wd2cxRGNUZFRST1lPTVVtMUFpYjBKV2hCN0NKU21LRG9qWVhSTXh6S25RNWZXOVdNTjlpUWFDTXpSRUslMkZTdG9FcG00eTBYQ0tNRG5iREVlSUVGeVZQUjU1TnpteCUyQjJTZVVBNnROOEs0UldrU3RBbTBQOUlBY3BUJTJGdEMzMDBLZjJMcHVkWFBBeWhiY3VkbHFMNUhnMTAzRjNQZEZURTNtJTJCblVlWXNWeWhBT2VJVlV1clBqUVh1ZnMzUyUyRkx6eiUyRjhmekh3JTNEJTNEJlNpZ0FsZz1odHRwJTNBJTJGJTJGd3d3LnczLm9yZyUyRjIwMDAlMkYwOSUyRnhtbGRzaWclMjNyc2Etc2hhMSZTaWduYXR1cmU9RU1hR3JERWZFZUlXeGJSUFREazZNUXllJTJGalF1cVVsY1p0bE9Ob0VnMkVSOUxwckU4UWhSbXdpMU02QzliMnNJbEU1b01PZXUzeCUyRlM1aWJiTlV3Y1ZwMk1lRTRlWnFWdm5xQThGZzklMkJhc2FHQTY4QVpRWWxxelNGZXJqdWljWkwwN2NWVkElMkZGRWsyWmJPcGdUdGZKbWg1dWtiUXY5VUROeHUwazlkWHY4ejQwVldsVDVSRUJHYjFkUVRFMEFFczNrQyUyQlZxR0ZkUVpHYmtJeGt3MVBZblVHTkQzJTJCUnZ1OFcyTENRTGE5ZDN1RGlTUllMekhvJTJGSGZKTnhuTVFjTVliMHV0dFNQNnp2bktqJTJCSGJRTGxERUNMemxpJTJCRkFuWUYxTDBpOXo0cFFSQUthVmRNYmNHaWFBZSUyRnVoZDAlMkJUQVVRZlJraGpDRWFoS1dYeXN5OEtualIlMkY5TThDZWNUMU4lMkJ1NFV4emhVM1BDcG1zVnNUVW9ZekxYUGxWRnBod2owb0l4S2JGQUd0bnF3TktieENTV2JaUk5RJTNEJTNE
Visit this URL to proceed with authentication:
https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php?SAMLRequest=fZFPb4MwDMW%2FCsodQstKaQRItAyp0v5UY9phlymips0UkiwO3fbtB1SdtksvPjz7Jz8%2Fp8g7aVjRu6N6go8e0HlfnVTIpkZGequY5iiQKd4BMtewuri%2FY%2FMgZMZqpxstyR%2FkOsERwTqhFfG2ZUbe1nEVrpIqLmfLTRwtV3GxKqtovY6j22qRFAXxXsDiMJ%2BRAR8gxB62Ch1XbpDC2dwPb%2FxZ8hwmbLFg0eyVeOVwg1DcTdTROYOMUm1Aib0JWhB7CJSmKDojYXRMxzKnQ5fW9WMN9iQaCMzREK%2FStoEpm4y0XCKMDnbDEeIEFyVPR55Nzmx%2B2SeUA6tN8K4RWkStAm0P9IAcpT%2FtC300Kf2LpudXPAyhbcudlqL5Hg103F3PdFTE3m%2BnUeYsVyhAOeIVUurPjQXufs3S%2FLzz%2F8fzHw%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=EMaGrDEfEeIWxbRPTDk6MQye%2FjQuqUlcZtlONoEg2ER9LprE8QhRmwi1M6C9b2sIlE5oMOeu3x%2FS5ibbNUwcVp2MeE4eZqVvnqA8Fg9%2BasaGA68AZQYlqzSFerjuicZL07cVVA%2FFEk2ZbOpgTtfJmh5ukbQv9UDNxu0k9dXv8z40VWlT5REBGb1dQTE0AEs3kC%2BVqGFdQZGbkIxkw1PYnUGND3%2BRvu8W2LCQLa9d3uDiSRYLzHo%2FHfJNxnMQcMYb0uttSP6zvnKj%2BHbQLlDECLzli%2BFAnYF1L0i9z4pQRAKaVdMbcGiaAe%2Fuhd0%2BTAUQfRkhjCEahKWXysy8KnjR%2F9M8CecT1N%2Bu4UxzhU3PCpmsVsTUoYzLXPlVFphwj0oIxKbFAGtnqwNKbxCSWbZRNQ%3D%3D
PQ==
5) smtp-server-saml20 waits for one of the following files to appear:
/tmp/gsasl-saml20/_B6F098F6D17C63796A9DF3BB63EF58AA/success
/tmp/gsasl-saml20/_B6F098F6D17C63796A9DF3BB63EF58AA/fail
6) Meanwhile the user will receive the redirect URL over the SMTP
connection and will access the URL in his browser. Eventually,
after IdP approval, the browser will be redirected to the SP with
the SAML response.
7) The gsasl-saml20-sp.php verify the SAML Response (using Lasso as
the SAML library) and writes files to the IPC store.
8) smtp-server-saml20 notice that one of the IPC files is present and
proceeds by reading the files and returning success/fail to the
client as appropriate. The client will print something like this:
235 OK [authid: _d69b0f484333df7eea73fccfd0b4dae2629f2eeb89 authzid: N/A]
Client authentication finished (server trusted)...
Enter application data (EOF to finish):
----------------------------------------------------------------------
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
|