1.\" $NetBSD: libsaslc.3,v 1.9 2011/02/16 02:14:22 christos Exp $ 2.\" 3.\" Copyright (c) 2010 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Mateusz Kocielski. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 3. All advertising materials mentioning features or use of this software 18.\" must display the following acknowledgement: 19.\" This product includes software developed by the NetBSD 20.\" Foundation, Inc. and its contributors. 21.\" 4. Neither the name of The NetBSD Foundation nor the names of its 22.\" contributors may be used to endorse or promote products derived 23.\" from this software without specific prior written permission. 24.\" 25.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35.\" POSSIBILITY OF SUCH DAMAGE. 36.\" 37.Dd February 14, 2011 38.Dt LIBSASLC 3 39.Os 40.Sh NAME 41.Nm saslc_alloc , 42.Nm saslc_end , 43.Nm saslc_init , 44.Nm saslc_sess_cont , 45.Nm saslc_sess_decode , 46.Nm saslc_sess_encode , 47.Nm saslc_sess_end , 48.Nm saslc_sess_getmech , 49.Nm saslc_sess_getprop , 50.Nm saslc_sess_init , 51.Nm saslc_sess_setprop , 52.Nm saslc_sess_strerror , 53.Nm saslc_strerror 54.Nd Simple Authentication and Security Layer client library 55.Sh LIBRARY 56.Lb libsaslc 57.Sh SYNOPSIS 58.In saslc.h 59.Ft saslc_t * 60.Fn saslc_alloc "void" 61.Ft int 62.Fn saslc_end "saslc_t *ctx" 63.Ft int 64.Fn saslc_init "saslc_t *ctx" "const char *appname" "const char *cfgpath" 65.Ft int 66.Fn saslc_sess_cont "saslc_sess_t *sess" "const void *in" "size_t inlen" \ 67"void* *out" "size_t *outlen" 68.Ft ssize_t 69.Fn saslc_sess_decode "saslc_sess_t *sess" "const void *in" "size_t inlen" \ 70"void* *out" "size_t *outlen" 71.Ft ssize_t 72.Fn saslc_sess_encode "saslc_sess_t *sess" "const void *in" "size_t inlen" \ 73"void* *out" "size_t *outlen" 74.Ft void 75.Fn saslc_sess_end "saslc_sess_t *sess" 76.Ft const char * 77.Fn saslc_sess_getmech "saslc_sess_t *sess" 78.Ft const char * 79.Fn saslc_sess_getprop "saslc_sess_t *sess" "const char *key" 80.Ft saslc_sess_t * 81.Fn saslc_sess_init "saslc_t *ctx" "const char *mechs" "const char *secopts" 82.Ft int 83.Fn saslc_sess_setprop "saslc_sess_t *sess" "const char *key" \ 84"const char *value" 85.Ft const char * 86.Fn saslc_sess_strerror "saslc_sess_t *sess" 87.Ft const char * 88.Fn saslc_strerror "saslc_t *ctx" 89.Sh DESCRIPTION 90The 91.Fn saslc_alloc 92function allocates and returns a new saslc context. 93The context is uninitialized: see 94.Fn saslc_init . 95Returns 96.Dv NULL 97on error. 98.Pp 99The 100.Fn saslc_end 101function destroys and deallocate resources used by the context 102.Ar ctx . 103The context shouldn't have any sessions assigned to it. 104Returns 0 on success and \-1 if the context has active sessions and 105cannot be deallocated. 106.Pp 107The 108.Fn saslc_init 109function initializes the saslc context 110.Ar ctx . 111Based on the application name 112.Ar appname , 113it also parses the configuration files as indicated by 114.Ar cfgpath , 115sets up the context and mechanism dictionaries, and creates mechanism 116list for the context. 117If 118.Ar cfgpath 119is 120.Dv NULL , 121it checks the environment variable 122.Ev SASLC_CONFIG 123for a location and if that is not found it uses the default path 124.Pa /etc/saslc.d . 125Returns 0 on success and \-1 on failure. 126.Pp 127The 128.Fn saslc_sess_init 129function creates new session assigned to the 130.Ar ctx 131context. 132The function chooses the mechanism to use for authentication from the 133.Ar mechs 134list taking into account the requirements from the 135.Ar secopts 136list. 137Both lists may be space or comma delimited. 138The first matching mechanism from the 139.Ar mechs 140list is used. 141See 142.Sx CONFIGURATION 143below for the supported mechanisms. 144The valid security options are 145.Pp 146.Bl -tag -width "nodictionaryxxx" -offset indent -compact 147.It Qo noanonymous Qc 148reject anonymous mechanisms 149.It Qo noplaintext Qc 150reject plaintext mechanisms 151.It Qo nodictionary Qc 152reject mechanisms prone to dictionary attack 153.It Qo noactive Qc 154reject mechanisms prone to active non-dictionary attacks 155.It Qo mutual Qc 156require mutual authentication mechanisms 157.El 158.Pp 159Unknown security options are ignored. 160Returns a session handle or 161.Dv NULL 162on error or no match. 163.Pp 164The 165.Fn saslc_sess_end 166function ends the sasl session 167.Ar sess . 168It destroys and deallocates all internal resources. 169This does not fail. 170.Pp 171The 172.Fn saslc_sess_getprop 173function gets the property indicated by the 174.Ar key 175from the saslc dictionaries. 176Dictionaries are searched in following order: session 177.Ar sess 178dictionary, 179context dictionary (global configuration), and mechanism dictionary. 180Returns the property value or 181.Dv NULL 182if the property is not found. 183.Pp 184The 185.Fn saslc_sess_setprop 186function sets the property indexed by 187.Ar key 188to the value 189.Ar value 190in the session 191.Ar sess 192dictionary. 193If the property already exists in the session dictionary, then the 194previous value is replaced by the new value. 195If 196.Ar value 197is 198.Dv NULL , 199then any previous value in the session dictionary is removed. 200Returns 0 on success or \-1 on failure. 201.Pp 202.Fn saslc_strerror 203and 204.Fn saslc_sess_strerror 205functions return the error message string for the last error in the 206context 207.Ar ctx 208or session 209.Ar sess , 210respectively. 211It never returns 212.Dv NULL . 213.Pp 214The 215.Fn saslc_strmech 216function gets the name of the mechanism used in the saslc session 217.Ar sess . 218This does not fail. 219.Pp 220The 221.Fn saslc_sess_cont 222performs one step of the sasl authentication. 223It reads 224.Ar inlen 225bytes of input data 226.Pq from the server 227from the 228.Ar in 229buffer and stores 230.Ar outlen 231bytes of output data in 232.Ar out 233.Pq for the server . 234The user is responsible for freeing memory allocated for 235.Ar out . 236It returns 0 if the authentication process is completed, 1 if another 237step is required, and \-1 on error. 238Note that the completion of authentication process does not mean the 239client is authenticated; that is determined by the server. 240.Pp 241.Fn saslc_sess_encode 242and 243.Fn saslc_sess_decode 244are used to provide the integrity 245.Pq Qq auth-int 246and confidentiality 247.Pq Qq auth-int 248layers for mechanisms that provide them. 249They encode and, respectively, decode 250.Ar inlen 251bytes of data from the 252.Ar in 253buffer using the method negotiated during authentication. 254On error they return \-1. 255Otherwise, they return the number of bytes consumed from 256.Ar in 257and output 258.Ar outlen 259bytes of data in the 260.Ar out 261buffer. 262The user is responsible for freeing memory allocated for 263.Ar out . 264If 265.Ar outlen 266is 0, more data is needed before anything can be output. 267Unused input data is stored internally for use in subsequent calls. 268.Pp 269When encoding, the internal buffer may be flushed through the encoder 270by calling 271.Fn saslc_sess_encode 272with 273.Ar inlen 274= 0. 275In this case, 276.Fn saslc_sess_encode 277returns the number of bytes that were flushed from the internal buffer. 278.Pp 279When decoding, the internal buffers can only be flushed by providing 280the missing packet data and it is an error to call 281.Fn ssalc_sess_decode 282with 283.Ar inlen 284= 0. 285The first call of 286.Fn saslc_sess_decode 287in a session must begin at the start of a packet. 288Subsequent calls need not be aligned on packet boundaries. 289.Pp 290The following code fragments illustrate the possible use of these 291functions. 292.Bd -literal 293int 294decode_stream(saslc_sess_t *sess, int fdin, int fdout) 295{ 296 uint8_t buf[BUFSIZE]; 297 uint8_t *in; 298 void *out; 299 size_t inlen, outlen; 300 ssize_t n, rval; 301.Pp 302 for (;;) { 303 if ((rval = read(fdin, buf, sizeof(buf))) == \-1) 304 return \-1; 305 if (rval == 0) 306 break; 307 in = buf; 308 inlen = rval; 309 while (inlen > 0) { 310 rval = saslc_sess_decode(sess, in, inlen, &out, 311 &outlen); 312 if (rval == \-1) 313 return \-1; 314 if (outlen > 0) { 315 n = write(fdout, out, outlen); 316 free(out); 317 if (n == \-1) 318 return \-1; 319 } 320 in += rval; 321 inlen -= rval; 322 } 323 } 324 return 0; 325} 326.Pp 327int 328encode_stream(saslc_sess_t *sess, int fdin, int fdout) 329{ 330 uint8_t buf[BUFSIZE]; 331 uint8_t *in; 332 void *out; 333 size_t inlen, outlen; 334 ssize_t n, rval; 335.Pp 336 for (;;) { 337 if ((rval = read(fdin, buf, sizeof(buf))) == \-1) 338 return \-1; 339 if (rval == 0) 340 break; 341 in = buf; 342 inlen = rval; 343 while (inlen > 0) { 344 rval = saslc_sess_encode(sess, in, inlen, &out, 345 &outlen); 346 if (rval == \-1) 347 return \-1; 348 if (outlen > 0) { 349 n = write(fdout, out, outlen); 350 free(out); 351 if (n == \-1) 352 return \-1; 353 } 354 in += rval; 355 inlen -= rval; 356 } 357 } 358 /* flush internal encoder buffer */ 359 if (saslc_sess_encode(sess, NULL, 0, &out, &outlen) == \-1) 360 return \-1; 361 if (outlen > 0) 362 if (write(fdout, out, outlen) == \-1) 363 return \-1; 364 return 0; 365} 366.Ed 367.Sh CONFIGURATION 368.Nm 369uses three types of dictionaries: context (or global), session, and 370mechanism, and they are searched in that order by 371.Fn saslc_getprop 372and the first matching entry is taken. 373The context and mechanism dictionaries are loaded from configuration 374files, while the session dictionary is loaded by the caller via 375.Fn saslc_setprop . 376The configuration context configuration file is 377.Pa <cfgpath>/<appname>/saslc.conf , 378while the mechanism configuration file is 379.Pa <cfgpath>/<appname>/mech/<mechanism>.conf . 380The 381.Pa <cfgpath> 382is 383.Pa /etc/saslc.d 384by default, but this may be overridden by the environment variable 385.Ev SASLC_CONFIG , 386which in turn may be overridden by 387.Fn saslc_init . 388The 389.Pa <appname> 390is 391.Pa saslc 392by default, but may also be overridden by 393.Fn saslc_init . 394Finally, the 395.Pa <mechanism> 396is the mechanism in use by the session as returned by 397.Fn saslc_sess_getmech . 398Note that this name is case sensitive. 399The currently supported mechanisms are 400.Bl -tag -width DIGEST-MD5 401.It ANONYMOUS 402See RFC 2245 and RFC 4505. 403.It CRAM-MD5 404See RFC 2195. 405.It DIGEST-MD5 406See RFC 2831. 407.It EXTERNAL 408See RFC 2222 section 7.4 and RFC 4422 appendix A. 409.It GSSAPI 410See RFC 2222 section 7.2 and RFC 4752. 411This requires GSS, Heimdal, or MIT Kerberos. 412.It LOGIN 413Non-standard, but common. 414.It PLAIN 415See RFC 2595 and RFC 4616. 416.El 417.Pp 418If any of the mechanism files are missing they are silently ignored, 419unless debugging is enabled. 420.Pp 421The configuration files consists of lines of the form: 422.Bd -literal -offset indent 423\fB#\fP comment line 424.Ao key Ac \~\~ Ao value Ac \~\~ Bo \fB#\fP comment Bc 425.Ed 426.Pp 427The 428.Aq key 429is a string beginning with an alpha character 430.Pq Xr isalpha 3 431followed by any number of alpha numeric 432.Pq Xr isalnum 3 433or underscore 434.Sq _ 435characters; this is case sensitive. 436The 437.Aq value 438is a number or a quoted string. 439More than one 440.Aq key 441and 442.Aq value 443pair may occur on a single line, but they may not be broken across 444lines. 445A 446.Sq \fB#\fP 447character 448.Pq outside a quoted string 449indicates that the rest of the line is a comment. 450.Pp 451NOTE: Currently, no escaping is supported in strings, so they may not 452contain quotes. 453Numbers must be between 0 and 454.Dv LLONG_MAX , 455inclusive. 456Any base supported by 457.Xr strtoll 3 458is allowed. 459.Sh PROPERTIES 460Most of the control of the 461.Nm 462behavior is done via setting various properties in the context or 463mechanism dictionaries via the configuration files or in the session 464dictionary with 465.Fn saslc_setprop . 466The following properties are currently used, as defined in 467.Pa saslc.h : 468.Bl -tag -width indent 469.It SASLC_PROP_AUTHCID Po Qo AUTHCID Qc Pc 470The authentication name 471.Pq or username 472to authenticate with. 473Used by all mechanisms except EXTERNAL. 474.It SASLC_PROP_AUTHZID Po Qo AUTHZID Qc Pc 475The authorization string to use. 476By default, this string is empty. 477Used by the DIGEST-MD5, EXTERNAL, and PLAIN mechanisms. 478.It SASLC_PROP_BASE64IO Po Qo BASE64IO Qc Pc 479If true ("true", "yes", or nonzero), then input and output strings are 480base64 encoded. 481Any other value is false and the input and output strings are not 482base64 encoded. 483By default, this is assumed true. 484Used by all mechanisms. 485.It SASLC_PROP_CIPHERMASK Po Qo CIPHERMASK Qc Pc 486The mask of ciphers to use with the DIGEST-MD5 mechanism when using 487the 488.Qq auth-conf 489QOP. 490By default all supported ciphers are used, but they may be limited by 491a comma delimited list of cipher names. 492The recognized cipher names for DIGEST-MD5 are: 493.Pp 494.Bl -tag -offset indent -compact 495.It Li "3des" 496Triple-DES Cipher in CBC "two keys" mode with 112 bit key 497.It Li "aes" 498AES Cipher in CBC mode with 128 bit key 499.It Li "des" 500DES Cipher in CBC mode with 56 bit key 501.It Li "rc4" 502RC4 Cipher with 128 bit key 503.It Li "rc4-40" 504RC4 Cipher with 40 bit key 505.It Li "rc4-56" 506RC4 Cipher with 56 bit key 507.El 508.Pp 509The default value is 510.Qq des,3des,rc4,rc4_40,rc4_56,aes . 511.Po 512Note that 513.Qq aes 514is not part of the official standard. 515.Pc 516Used by the DIGEST-MD5 mechanism. 517.It SASLC_PROP_DEBUG Po Qo DEBUG Qc Pc 518If true, then enable debug messages. 519This is implemented as a global variable so it will affect all 520sessions. 521If set via 522.Fn saslc_sess_setprop , 523it should be set before the first call to 524.Fn saslc_sess_cont . 525.Po 526Also see the environment variable 527.Ev SASLC_ENV_DEBUG 528in the 529.Sx ENVIRONMENT 530section below. 531.Pc 532.It SASLC_PROP_HOSTNAME Po Qo HOSTNAME Qc Pc 533The fully qualified domain name of the server host. 534Used by the DIGEST-MD5 and GSSAPI mechanisms. 535.It SASLC_PROP_MAXBUF Po Qo MAXBUF Qc Pc 536The size of the decode buffer. 537This info is sent to the server so that it doesn't send packets that 538won't fit in the decode buffer when decoded. 539Used by the DIGEST-MD5 and GSSAPI mechanisms. 540.It SASLC_PROP_PASSWD Po Qo PASSWD Qc Pc 541The password to authenticate with. 542Used by the CRAM-MD5, DIGEST-MD5, LOGIN, and PLAIN mechanisms. 543.It SASLC_PROP_QOPMASK Po Qo QOPMASK Qc Pc 544The mask of QOP (quality of protection) to use with the DIGEST-MD5 545and GSSAPI mechanisms. 546By default all supported QOP values are allowed, but they may be 547limited by a comma delimited list of QOP values. 548The recognized QOP values are: 549.Pp 550.Bl -tag -offset indent -compact 551.It Li "auth" 552authentication only 553.It Li "auth-int" 554authentication with integrity 555.It Li "auth-conf" 556authentication with confidentiality 557.El 558.Pp 559so the default value of the mask is 560.Qq auth,auth-int,auth-conf . 561Used by the DIGEST-MD5 and GSSAPI mechanisms. 562.It SASLC_PROP_REALM Po Qo REALM Qc Pc 563A comma delimited list of possible realms to use for authentication. 564The format of each element in the list is 565.Qq Oo Ao hostname Ac : Oc Ns Ao realm Ac . 566The user specified realm is the first realm in the list with a 567matching hostname or, if none is found, the first realm in the list 568with no hostname. 569If the server provides a list of realms, the one matching the user 570specified realm is selected. 571If no match is found or if the user didn't provide a realm, the first 572realm provided by the server is selected. 573If the server doesn't provide any realms, use the user specified realm 574if there is one, or the hostname if not. 575This is useful when the server provides multiple realms or no realm. 576Used by the DIGEST-MD5 mechanism. 577.It SASLC_PROP_SECURITY Po Qo SECURITY Qc Pc 578A comma delimited list of extra security option flags that will be 579.Qo or Qc Ns -ed 580together with those passed to 581.Fn saslc_sess_init . 582Since these flags are used to choose the session mechanism, they are 583only effective if they are in the context configuration file. 584.Po 585See the 586.Sx CONFIGURATION 587section and the 588.Fn saslc_sess_init 589function. 590.Pc 591.It SASLC_PROP_SERVICE Po Qo SERVICE Qc Pc 592The service being used, e.g., smtp, imap, etc. 593Used by the DIGEST-MD5 and GSSAPI mechanisms. 594.It SASLC_PROP_SERVNAME Po Qo SERVNAME Qc Pc 595A comma delimited list of possible service names with elements of the 596form 597.Qq Oo Ao hostname Ac : Oc Ns Ao serv-name Ac 598and with the same rules as for the SASLC_PROP_REALM list. 599This should only be used if the client uses a DNS name for the service 600that is different from the FQDN of the server. 601For example, the service name 602.Em example.com 603might resolve 604.Pq via SRV or MX records 605into a set of other DNS names, one of which, 606.Em mail3.example.com , 607is the FQDN of the server. 608.Po 609See RFC 2831 section 2.1.2 610.Qq serv-name . 611.Pc 612Used by the DIGEST-MD5 mechanism. 613.El 614.Pp 615The defines in 616.Pa saslc.h 617should be used in code, but their values need to be used in the config 618files. 619.Sh ENVIRONMENT 620The following environment variables 621.Pq defined in Pa saslc.h 622affect the behavior of 623.Nm : 624.Bl -tag -width indent 625.It Ev SASLC_ENV_CONFIG Po Qo SASLC_CONFIG Qc Pc 626If the environment variable 627.Ev SASLC_CONFIG 628is set it overrides the default configuration file location of 629.Pa /etc/saslc.d . 630This may be overridden by 631.Fn saslc_init . 632.It Ev SASLC_ENV_DEBUG Po Qo SASLC_DEBUG Qc Pc 633If set, turn on debugging messages. 634This turns on debugging as early as possible and is a global setting. 635.El 636.Sh GSSAPI AND KERBEROS 637The following is a minimal 638.Pq Heimdal 639Kerberos 5 setup for use with an smtp server that has been configured 640to support 641.Em SASL 642with the 643.Em GSSAPI 644mechanism. 645It assumes that Kerberos and the smtp server will both run on 646.Em server.my.domain 647and that the client is on 648.Em client.my.domain . 649It also assumes that the smtp server runs as user 650.Em postfix 651and group 652.Em mail , 653and that it is not chrooted. 654.Pp 655On 656.Em server.my.domain 657run the following script as 658.Em root 659and then start the Kerberos server 660.Xr kdc 8 . 661You will be prompted for a master password for Kerberos and a password 662for the 663.Em postfix 664principal. 665.Bd -literal -offset indent 666#/bin/sh 667.Pp 668cat <<- EOF >> /etc/krb5.conf 669[libdefaults] 670 default_realm = MY.DOMAIN 671[realms] 672 MY.DOMAIN = { 673 kdc = server.my.domain 674 admin_servers = server.my.domain 675 } 676[domain_realm] 677 .my.domain = MY.DOMAIN 678EOF 679.Pp 680mkdir /var/heimdal 681chown root:wheel /var/heimdal 682chmod 755 /var/heimdal 683.Pp 684kstash 685kadmin -l init --realm-max-ticket-life=unlimited \\ 686 --realm-max-renewable-life=unlimited \\ 687 MY.DOMAIN 688kadmin -l add --max-ticket-life="1 day" \\ 689 --max-renewable-life="1 week" \\ 690 --expiration-time=never \\ 691 --pw-expiration-time=never \\ 692 --attributes="" \\ 693 postfix 694kadmin -l add --random-key \\ 695 --max-ticket-life="1 day" \\ 696 --max-renewable-life="1 week" \\ 697 --expiration-time=never \\ 698 --pw-expiration-time=never \\ 699 --attributes="" \\ 700 smtp/server.my.domain 701kadmin -l ext -k /etc/krb5.keytab smtp/server.my.domain 702chown root:mail /etc/krb5.keytab 703chmod 640 /etc/krb5.keytab 704.Ed 705.Pp 706Note that the keytab 707.Pa /etc/krb5.keytab 708must be readable by the smtp server or authentication will fail. 709The location of this keytab file may be changed with the environment 710variable 711.Ev KRB5_KTNAME . 712If postfix is the smtp server, note the 713.Em import_environment 714parameter 715.Pq see Xr postconf 5 . 716.Pp 717On 718.Em client.my.domain 719copy the keytab file from 720.Pa server.my.domain:/etc/krb5.keytab 721to 722.Pa /etc/krb5.keytab . 723Setup the 724.Pa /etc/saslc.d 725configuration directory 726.Po see Sx CONFIGURATION 727above 728.Pc . 729Add the line 730.Bd -literal -offset indent 731AUTHCID "postfix" 732.Ed 733.Pp 734to the file 735.Pa /etc/saslc.d/postfix/mech/GSSAPI.conf 736so that the 737.Em postfix 738principle will be used for authentication. 739Enable 740.Em SASL 741in the smtp client. 742Assuming the smtp client is postfix, you will need to add the 743following to the 744.Pa /etc/postfix/main.cf 745file to do this: 746.Bd -literal -offset indent 747smtp_sasl_auth_enable = yes 748smtp_sasl_type = saslc 749smtp_sasl_mechanism_filter = GSSAPI 750relayhost = [server.my.domain]:submission 751.Ed 752.Pp 753Here we have assumed the 754.Em submission 755port is the port the server is listening to. 756Finally, as 757.Em root , 758run the command 759.Bd -literal -offset indent 760su -m postfix -c kinit 761.Ed 762.Pp 763to obtain a ticket for the postfix user with the postfix credential 764and you should be good to go! 765.Sh COMPATIBILITY 766There exist other SASL client library implementations including Cyrus SASL 767(http://asg.web.cmu.edu/sasl/sasl-library.html) and GNU SASL 768(http://www.gnu.org/software/gsasl/). 769.Sh STANDARDS 770RFC 2195, RFC 2222, RFC 2245, RFC 2595, RFC 2831, RFC 4422, RFC 4505, 771RFC 4616, RFC 4752. 772.Sh CAVEATS 773The API was heavily influenced by its use with 774.Xr postfix 1 . 775.Pp 776Currently the ANONYMOUS, LOGIN, PLAIN, CRAM-MD5, DIGEST-MD5, and 777GSSAPI mechanisms have been tested and shown to work for 778authentication with a 779.Xr postfix 1 780SMTP server using the cyrus-sasl library. 781The DIGEST-MD5 and GSSAPI specs also provide for integrity and 782confidentiality layers via the 783.Fn saslc_sess_encode 784and 785.Fn saslc_sess_decode 786routines, but these have not yet been tested against any servers. 787