1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> 2<html> 3<head> 4<meta name="generator" content="HTML Tidy, see www.w3.org"> 5<title>SASL Application Programmer's Guide</title> 6</head> 7<body> 8<h1>SASL Application Programmer's Guide</h1> 9 10<h3>NOTE: This is a work in progress. Any contributions would be 11<i>very</i> appreciated</h3> 12 13<h2>Contents</h2> 14 15<ul> 16<li><a href="#intro">Introduction</a> 17 18<ul> 19<li><a href="#about_this_guide">About this guide</a></li> 20 21<li><a href="#what_is_sasl">What is SASL?</a></li> 22</ul> 23</li> 24 25<li><a href="#background">Background</a> 26 27<ul> 28<li><a href="#world_before">How did the world work before 29SASL?</a></li> 30 31<li><a href="#sasl_rescue">SASL to the rescue!</a></li> 32</ul> 33</li> 34 35<li><a href="#briefly">Briefly</a> 36 37<ul> 38<li><a href="#what_good_for">What is the Cyrus SASL library good 39for?</a></li> 40 41<li><a href="#what_do">What does the Cyrus SASL library 42do?</a></li> 43 44<li><a href="#what_doesnt">What doesn't the Cyrus SASL library 45do?</a></li> 46</ul> 47</li> 48 49<li><a href="#client_only">Client-only Section</a> 50 51<ul> 52<li><a href="#client_typical">A typical interaction from the 53client's perspective</a></li> 54 55<li><a href="#client_code">How does this look in code?</a></li> 56 57<li><a href="#sasl_client_init">sasl_client_init</a></li> 58 59<li><a href="#sasl_client_new">sasl_client_new</a></li> 60 61<li><a href="#sasl_client_start">sasl_client_start</a></li> 62 63<li><a href="#sasl_client_step">sasl_client_step</a></li> 64</ul> 65</li> 66 67<li><a href="#server_section">Server-only Section</a> 68 69<ul> 70<li><a href="#server_typical">A typical interaction from the 71server's perspective</a></li> 72 73<li><a href="#server_code">How does this look in code?</a></li> 74 75<li><a href="#sasl_server_init">sasl_server_init</a></li> 76 77<li><a href="#sasl_server_new">sasl_server_new</a></li> 78 79<li><a href="#sasl_server_start">sasl_server_start</a></li> 80 81<li><a href="#sasl_server_step">sasl_server_step</a></li> 82 83<li><a href="#sasl_listmech">sasl_listmech</a></li> 84 85<li><a href="#sasl_checkpass">sasl_checkpass</a></li> 86</ul> 87</li> 88 89<li><a href="#common_section">Common Section</a> 90 91<ul> 92<li><a href="#callbacks_interactions">Callbacks and 93Interaction</a></li> 94 95<li><a href="#layers">Security layers</a></li> 96</ul> 97</li> 98 99<li><a href="#example_section">Example applications that come with 100the Cyrus SASL library</a> 101 102<ul> 103<li><a href="#sample_client"><tt>sample-client</tt> and 104<tt>sample-server</tt></a></li> 105 106<li><a href="#cyrus_imapd">Cyrus imapd v2.1.0 or later</a></li> 107 108<li><a href="#imtest"><tt>imtest</tt>, from cyrus imapd 2.1.0 or 109later</a></li> 110</ul> 111</li> 112 113<li><a href="#random_things">Miscellaneous Information</a> 114 115<ul> 116<li><a href="#empty_exchanges">Empty exchanges</a></li> 117</ul> 118</li> 119</ul> 120 121<h2><a name="intro">Introduction</a></h2> 122 123<h3><a name="about_this_guide">About this Guide</a></h3> 124 125<p>This guide gives a tutorial on the use of the Cyrus SASL library 126for a client or server application. It complies with versions 127including and after 2.0.0. The following pages should only be 128considered a guide, not the final word on programming with the 129Cyrus SASL library. Consult the header files in the distribution in 130the case of ambiguities.</p> 131 132<h3><a name="what_is_sasl">What is SASL?</a></h3> 133 134<p>SASL stands for Simple Authentication Security Layer and is 135explained in <a href="http://ftp.ietf.org/rfc/rfc2222.txt">RFC 1362222</a>. That document is very difficult to understand however and 137it should be unnecessary to consult it.</p> 138 139<h2><a name="background">Background</a></h2> 140 141<h3><a name="world_before">How did the world work before 142SASL?</a></h3> 143 144<p>Before SASL, when a new protocol was written which required 145authentication (users proving who they are to an entity), the 146protocol had to allow explicitly for each individual authentication 147mechanism. There had to be a distinct way to say "I want to log in 148with Kerberos V4". There had to be another distinct way to say "I 149want to log in with CRAM-MD5". There had to be yet a different way 150to say "I want to log in anonymously," and so on. This was 151non-ideal for both the protocol and application writers.</p> 152 153<p>Additionally, many programmers were not very familiar with 154security, so the protocol did support many mechanisms, or worse, 155they were supported incorrectly. Moreover, when a new 156authentication method was invented the protocol needed to be 157modified to support that mechanism.</p> 158 159<p>This system also was not ideal for application writer. She had 160to have a special case for each mechanism she wished her 161application to support. Also, the mechanisms were difficult to 162implement. Even with a good library, an understanding of how the 163mechanism worked was still necessary. Finally if an application 164used more than one protocol (for example a mail client might use 165IMAP, POP, and SMTP) then "Kerberos V4 for IMAP", "Kerberos V4 for 166POP", "Kerberos V4 for SMTP", "CRAM MD5 for IMAP", "CRAM-MD5 for 167POP", etc... would need to be written. This could quickly create a 168huge number of different mechanism-protocol pairs to implement.</p> 169 170<h3><a name="sasl_rescue">SASL to the rescue!</a></h3> 171 172<p>SASL hopefully solves all these problems. In practice it makes 173many of them easier to deal with.</p> 174 175<p>Protocol designers simply have to support SASL (in particular 176RFC 2222). Consequently, any mechanism that supports SASL (just 177about anything you would want to use does now) is supported by the 178protocol. If a new authentication mechanism is invented the 179protocol automatically supports it without any modifications.</p> 180 181<p>Application writers, instead of having to support every 182mechanism for every protocol, only need to support SASL for every 183protocol. Application writers do not need to understand the 184authentication mechanisms at all: the SASL library handles all 185that. Also with the Cyrus SASL library if a new mechanism is 186invented you do not have rewrite your application at all. You may 187not even have to restart your application if it is a long running 188process. This is because the Cyrus SASL library loads each 189mechanism from a shared library. Simply copying a shared library 190into a directory will magically make your application support a new 191mechanism.</p> 192 193<p>Cyrus SASL version 2 supports a much improved API over version 1941, that allows for much smarter and faster memory allocation for 195the mechanisms as well as the applications. It is also provides for 196several new types of plugins to allow for greater overall 197flexibility. Unfortunately, though similar, this new API is 198completely incompatible with the old API, and applications will 199need to be rewritten.</p> 200 201<h2><a name="briefly">Briefly</a></h2> 202 203<h3><a name="what_good_for">What is the Cyrus SASL library good 204for?</a></h3> 205 206<p>The Cyrus SASL library is good for applications that wish to use 207protocols that support SASL authentication. An non-exhaustive list 208of these are: IMAP, SMTP, ACAP, and LDAP. Also if you are making a 209proprietary system and wish to support authentication it is a good 210way of supporting many different authentication types.</p> 211 212<h3><a name="what_do">What does the Cyrus SASL library do?</a></h3> 213 214<p>From a client point of view, the Cyrus SASL library, given a 215list of mechanisms the server supports it will decide the best 216mechanism to use and tell you what to send to the server at each 217step of the authentication. From a server perspective, it handles 218authentication requests from clients.</p> 219 220<h3><a name="what_doesnt">What doesn't the Cyrus SASL library 221do?</a></h3> 222 223<p>The Cyrus SASL library is neither network nor protocol aware. It 224is up to the application to send the data over the wire as well as 225to send the data in the protocol specific manner. With IMAP this 226means putting it in the form: <tt>+ [base64'ed data]\r\n</tt>. LDAP 227just sends data in binary via bind requests. The Cyrus SASL library 228has utility base64 encode and decode routines to help with 229this.</p> 230 231<h2><a name="client_section">Client-only Section</a></h2> 232 233<h3><a name="client_typical">A typical interaction from the 234client's perspective</a></h3> 235 236<ol> 237<li>A client makes a few calls (explained later) to initialize 238SASL.</li> 239 240<li>Every time the client application makes a new connection it 241should make a new context that is kept for the life of the 242connection.</li> 243 244<li>Ask the server for the list of supported mechanisms</li> 245 246<li>Feed this list to the library</li> 247 248<li>Start the authentication with the mechanism the library 249chose</li> 250 251<li>The server will return some bytes</li> 252 253<li>Give these to the library</li> 254 255<li>The library returns some bytes to the application</li> 256 257<li>Application sends these bytes over the network</li> 258 259<li>repeat the last 4 steps until the server tells you that the 260authentication is completed</li> 261</ol> 262 263<h3><a name="client_code">How does this look in code</a></h3> 264 265<b>Initialize the library</b>. (done once). 266 267<pre> 268 269 int result; 270 271 /* attempt to start sasl 272 * See the section on Callbacks and Interactions for an 273 * explanation of the variable callbacks 274 */ 275 276 result=sasl_client_init(callbacks); 277 278 /* check to see if that worked */ 279 if (result!=SASL_OK) [failure] 280 281</pre> 282 283<b>For every network connection, make a new SASL connection</b>: 284 285<pre> 286 287 /* The SASL context kept for the life of the connection */ 288 sasl_conn_t *conn; 289 290 291 /* client new connection */ 292 result=sasl_client_new("imap", /* The service we are using */ 293 serverFQDN, /* The fully qualified domain 294 name of the server we're 295 connecting to */ 296 NULL, NULL, /* Local and remote IP 297 address strings 298 (NULL disables mechanisms 299 which require this info)*/ 300 NULL, /* connection-specific 301 callbacks */ 302 0, /* security flags */ 303 &conn); /* allocated on success */ 304 305 /* check to see if that worked */ 306 if (result!=SASL_OK) [failure] 307 308 309</pre> 310 311Next get the list of SASL mechanisms the server supports. This is 312usually done through a capability command. Format the list as a 313single string separated by spaces. Feed this string into SASL to 314begin the authentication process. 315 316<pre> 317 318 sasl_interact_t *client_interact=NULL; 319 const char *out, *mechusing; 320 unsigned outlen; 321 322 do { 323 324 result=sasl_client_start(conn, /* the same context from 325 above */ 326 mechlist, /* the list of mechanisms 327 from the server */ 328 &client_interact, /* filled in if an 329 interaction is needed */ 330 &out, /* filled in on success */ 331 &outlen, /* filled in on success */ 332 &mechusing); 333 334 if (result==SASL_INTERACT) 335 { 336 [deal with the interactions. See interactions section below] 337 } 338 339 340 } while (result==SASL_INTERACT); /* the mechanism may ask us to fill 341 in things many times. result is 342 SASL_CONTINUE on success */ 343 if (result!=SASL_CONTINUE) [failure] 344 345 346</pre> 347 348Note that you do not need to worry about the allocation and freeing 349of the output buffer out. This is all handled inside of the 350mechanism. It is important to note, however, that the output buffer 351is not valid after the next call to <tt>sasl_client_start</tt> or 352<tt>sasl_client_step</tt>. 353 354<p>If this is successful send the protocol specific command to 355start the authentication process. This may or may not allow for 356initial data to be sent (see the documentation of the protocol to 357see).</p> 358 359<pre> 360 For IMAP this might look like: 361 {tag} "AUTHENTICATE" {mechusing}\r\n 362 A01 AUTHENTICATE KERBEROS_V4\r\n 363 364 SMTP looks like: 365 "AUTH" {mechusing}[ {out base64 encoded}] 366 AUTH DIGEST-MD5 GHGJJGDDFDKHGHJG= 367 368</pre> 369 370<br> 371 <a name="client_authentication_step"><b>Check Results</b></a> <br> 372 Next, read what the server sent back. It can be one of three 373things: 374 375<ol> 376<li>Authentication failure. Authentication process is halted. This 377might look like <tt>A01 NO Authentication failure</tt> in IMAP or 378<tt>501 Failed</tt> in SMTP. Either retry the authentication or 379abort.</li> 380 381<li>Authentication success. We're now successfully authenticated. 382This might look like <tt>A01 OK Authenticated successful</tt> in 383IMAP or <tt>235 Authentication successful</tt> in SMTP. Go <a href= 384"#client_authentication_success">here</a></li> 385 386<li>Another step in the authentication process is necessary. This 387might look like <tt>+ HGHDS1HAFJ=</tt> in IMAP or <tt>334 388PENCeUxFREJoU0NnbmhNWitOMjNGNndAZWx3b29kLmlubm9zb2Z0LmNvbT4=</tt> 389in SMTP. Note it could be an empty string such as <tt>+ \r\n</tt> 390in IMAP.</li> 391</ol> 392 393Convert the continuation data to binary format (for example, this 394may include base64 decoding it). Perform another step in the 395authentication. 396 397<pre> 398 do { 399 result=sasl_client_step(conn, /* our context */ 400 in, /* the data from the server */ 401 inlen, /* it's length */ 402 &client_interact, /* this should be 403 unallocated and NULL */ 404 &out, /* filled in on success */ 405 &outlen); /* filled in on success */ 406 407 if (result==SASL_INTERACT) 408 { 409 [deal with the interactions. See below] 410 } 411 412 413 } while (result==SASL_INTERACT || result == SASL_CONTINUE); 414 415 if (result!=SASL_OK) [failure] 416 417 418</pre> 419 420Format the output (variable out of length outlen) in the protocol 421specific manner and send it across the network to the server. <br> 422 Goto <a href="#client_authentication_step">here</a> (this process 423repeats until authentication either succeeds or fails. <br> 424<br> 425<br> 426 <a name="client_authentication_success"><b>Authentication 427Successful</b></a><br> 428<br> 429 430 431<p>Before we're done we need to call sasl_client_step() one more 432time to make sure the server isn't trying to fool us. Some 433protocols include data along with the last step. If so this data 434should be used here. If not use a length of zero.</p> 435 436<pre> 437 result=sasl_client_step(conn, /* our context */ 438 in, /* the data from the server */ 439 inlen, /* it's length */ 440 &client_interact, /* this should be unallocated and NULL */ 441 &out, /* filled in on success */ 442 &outlen); /* filled in on success */ 443 444 if (result!=SASL_OK) [failure] 445 446</pre> 447 448<p>Congratulations. You have successfully authenticated to the 449server.</p> 450 451<p>Don't throw away the SASL connection object (sasl_conn_t *) yet 452though. If a security layer was negotiated you will need it to 453encode and decode the data sent over the network.</p> 454 455<br> 456 When you are finally done with connection to server, dispose of 457SASL connection. 458 459<pre> 460 461 sasl_dispose(&conn); 462 463 464</pre> 465 466If you are done with SASL forever (application quiting for 467example): 468 469<pre> 470 sasl_done(); 471 472</pre> 473 474<h3>sasl_client_init</h3> 475 476<pre> 477 int sasl_client_init(const sasl_callback_t *callbacks); 478 479</pre> 480 481Parameters: 482 483<ul> 484<li>callbacks - List of callbacks. See Callbacks section</li> 485</ul> 486 487This function initializes the SASL library. This must be called 488before any other SASL calls. See the callbacks section for complete 489description of callbacks. 490 491<h3>sasl_client_new</h3> 492 493<pre> 494 int sasl_client_new(const char *service, 495 const char *serverFQDN, 496 const char *iplocalport, 497 const char *ipremoteport, 498 const sasl_callback_t *prompt_supp, 499 unsigned secflags, 500 sasl_conn_t **pconn); 501 502</pre> 503 504Parameters: 505 506<ul> 507<li>service - the service name being used. This usually is the 508protocol name (e.g. "ldap")</li> 509 510<li>serverFQDN - Fully qualified domain name of server</li> 511 512<li>iplocalport and ipremoteport - a string of the format 513"a.b.c.d;p" detailing the local or remote IP and port, or NULL 514(which will disable mechanisms that require this information)</li> 515 516<li>prompt_supp - List off callbacks specific to this 517connection</li> 518 519<li>secflags - security flags ORed together requested (e.g. 520SASL_SEC_NOPLAINTEXT)</li> 521 522<li>pconn - the SASL connection object allocated upon success</li> 523</ul> 524 525This function creates a new SASL connection object. It should be 526called once for every connection you want to authenticate for. 527 528<h3>sasl_client_start</h3> 529 530<pre> 531 int sasl_client_start(sasl_conn_t *conn, 532 const char *mechlist, 533 sasl_interact_t **prompt_need, 534 const char **clientout, 535 unsigned *clientoutlen, 536 const char **mech); 537 538</pre> 539 540Parameters: 541 542<ul> 543<li>conn - the SASL connection object gotten from 544sasl_client_new()</li> 545 546<li>mechlist - the list of mechanisms to try (separated by 547spaces)</li> 548 549<li>prompt_need - filled in when a SASL_INTERACT is returned</li> 550 551<li>clientout - filled in upon success with data to send to 552server</li> 553 554<li>clientoutlen - length of that data</li> 555 556<li>mech - filled in with mechanism being used</li> 557</ul> 558 559This function starts an authentication session. It takes a list of 560possible mechanisms (usually gotten from the server through a 561capability command) and chooses the "best" mechanism to try. Upon 562success clientout points at data to send to the server. 563 564<h3>sasl_client_step</h3> 565 566<pre> 567 int sasl_client_step(sasl_conn_t *conn, 568 const char *serverin, 569 unsigned serverinlen, 570 sasl_interact_t **prompt_need, 571 const char **clientout, 572 unsigned *clientoutlen); 573 574</pre> 575 576Parameters: 577 578<ul> 579<li>conn - the SASL connection object gotten from 580sasl_client_new()</li> 581 582<li>serverin - data from the server</li> 583 584<li>serverinlen - length of data from the server</li> 585 586<li>prompt_need - filled in with a SASL_INTERACT is returned</li> 587 588<li>clientout - filled in upon success with data to send to 589server</li> 590 591<li>clientoutlen - length of that data</li> 592</ul> 593 594This step preforms a step in the authentication process. It takes 595the data from the server (serverin) and outputs data to send to the 596server (clientout) upon success. SASL_CONTINUE is returned if 597another step in the authentication process is necessary. SASL_OK is 598returned if we're all done. 599 600<h2><a name="server_section">Server-only Section</a></h2> 601 602<h3><a name="server_typical">A typical interaction from the 603server's perspective</a></h3> 604 605The server makes a few Cyrus SASL calls for initialization. When it 606gets a new connection it should make a new context for that 607connection immediately. The client may then request a list of 608mechanisms the server supports. The client also may request to 609authenticate at some point. The client will specify the mechanism 610it wishes to use. The server should negotiate this authentication 611and keep around the context afterwards for encoding and decoding 612the layers. 613 614<h3><a name="server_code">How does this look in code?</a></h3> 615 616Initialization (done once). The application name is used for 617reading configuration information. 618 619<pre> 620 621 int result; 622 623 /* Initialize SASL */ 624 result=sasl_server_init(callbacks, /* Callbacks supported */ 625 "TestServer"); /* Name of the application */ 626 627 628</pre> 629 630This should be called for each new connection. It probably should 631be called right when the socket is accepted. 632 633<pre> 634 sasl_conn_t *conn; 635 int result; 636 637 /* Make a new context for this connection */ 638 result=sasl_server_new("smtp", /* Registered name of service */ 639 NULL, /* my fully qualified domain name; 640 NULL says use gethostname() */ 641 NULL, /* The user realm used for password 642 lookups; NULL means default to serverFQDN 643 Note: This does not affect Kerberos */ 644 NULL, NULL, /* IP Address information strings */ 645 NULL, /* Callbacks supported only for this connection */ 646 0, /* security flags (security layers are enabled 647 * using security properties, separately) 648 &conn); 649 650 651</pre> 652 653When a client requests the list of mechanisms supported by the 654server. This particular call might produce the string: <i>"{PLAIN, 655KERBEROS_V4, CRAM-MD5, DIGEST-MD5}"</i> 656 657<pre> 658 result=sasl_listmech(conn, /* The context for this connection */ 659 NULL, /* not supported */ 660 "{", /* What to prepend the string with */ 661 ", ", /* What to separate mechanisms with */ 662 "}", /* What to append to the string */ 663 &result_string, /* The produced string. */ 664 &string_length, /* length of the string */ 665 &number_of_mechanisms); /* Number of mechanisms in 666 the string */ 667 668 669</pre> 670 671When a client requests to authenticate: 672 673<pre> 674 int result; 675 const char *out; 676 unsigned outlen; 677 678 result=sasl_server_start(conn, /* context */ 679 mechanism_client_chose, 680 clientin, /* the optional string the client gave us */ 681 clientinlen, /* and it's length */ 682 &out, /* The output of the library. 683 Might not be NULL terminated */ 684 &outlen); 685 686 if ((result!=SASL_OK) && (result!=SASL_CONTINUE)) 687 [failure. Send protocol specific message that says authentication failed] 688 else if (result==SASL_OK) 689 [authentication succeeded. Send client the protocol specific message 690 to say that authentication is complete] 691 else 692 [send data 'out' with length 'outlen' over the network in protocol 693 specific format] 694 695</pre> 696 697When a response is returned by the client. <i>clientin</i> is the 698data from the client decoded from protocol specific format to a 699string of bytes of length <i>clientinlen</i>. This step may occur 700zero or more times. An application must be able to deal with it 701occurring an arbitrary number of times. 702 703<pre> 704 int result; 705 706 result=sasl_server_step(conn, 707 clientin, /* what the client gave */ 708 clientinlen, /* it's length */ 709 &out, /* allocated by library on success. 710 Might not be NULL terminated */ 711 &outlen); 712 713 if ((result!=SASL_OK) && (result!=SASL_CONTINUE)) 714 [failure. Send protocol specific message that says authentication failed] 715 else if (result==SASL_OK) 716 [authentication succeeded. Send client the protocol specific message 717 to say that authentication is complete] 718 else 719 [send data 'out' with length 'outlen' over the network in protocol 720 specific format] 721 722</pre> 723 724This continues until authentication succeeds. When the connection 725is concluded, make a call to <tt>sasl_dispose</tt> as with the 726client connection. 727 728<h3><a name="sasl_server_init">sasl_server_init</a></h3> 729 730<pre> 731 int sasl_server_init(const sasl_callback_t *callbacks, 732 const char *appname); 733</pre> 734 735Parameters: 736 737<ul> 738<li>callbacks - A list of callbacks supported by the application 739(see Interaction and Callbacks section)</li> 740 741<li>appname - A string of the name of the application. This string 742is what is used when loading configuration options.</li> 743</ul> 744 745sasl_server_init() initializes the session. This should be the 746first function called. In this function the shared library 747authentication mechanisms are loaded. 748 749<h3><a name="sasl_server_new">sasl_server_new</a></h3> 750 751<pre> 752 int sasl_server_new(const char *service, 753 const char *serverFQDN, 754 const char *user_realm, 755 const char *iplocalport, 756 const char *ipremoteport, 757 const sasl_callback_t *callbacks, 758 unsigned secflags, 759 sasl_conn_t **pconn); 760</pre> 761 762Parameters: 763 764<ul> 765<li>service - The name of the service you are supporting. This 766might be "acap" or "smtp". This is used by Kerberos mechanisms and 767possibly other mechanisms. It is also used for PAM 768authentication.</li> 769 770<li>serverFQDN - This is the fully qualified domain name of the 771server (i.e. your hostname); if NULL, the library calls 772<tt>gethostbyname()</tt>.</li> 773 774<li>user_realm - The realm the connected client is in. The Kerberos 775mechanisms ignore this parameter and default to the local Kerberos 776realm. A value of NULL makes the library default, usually to the 777serverFQDN; a value of "" specifies that the client should specify 778the realm; this also changes the semantics of "@" in a username for 779mechanisms that don't support realms.</li> 780 781<li>iplocalport and ipremoteport - a string of the format 782"a.b.c.d;p" detailing the local or remote IP and port, or NULL 783(which will disable mechanisms that require this information)</li> 784 785<li>callbacks - Additional callbacks that you wish only to apply to 786this connection.</li> 787 788<li>secflags - security flags.</li> 789 790<li>pconn - Context. Filled in on success.</li> 791</ul> 792 793<h3><a name="sasl_server_start">sasl_server_start</a></h3> 794 795<pre> 796 int sasl_server_start(sasl_conn_t *conn, 797 const char *mech, 798 const char *clientin, 799 unsigned clientinlen, 800 const char **serverout, 801 unsigned *serveroutlen); 802 803</pre> 804 805Parameters: 806 807<ul> 808<li>conn - The context for the connection</li> 809 810<li>mech - The authentication mechanism the client wishes to try 811(e.g. <tt>KERBEROS_V4</tt>)</li> 812 813<li>clientin - Initial client challenge bytes. Note: some protocols 814do not allow this. If this is the case passing NULL is valid</li> 815 816<li>clientinlen - The length of the challenge. 0 is there is 817none.</li> 818 819<li>serverout - allocated and filled in by the function. These are 820the bytes that should be encoded as per the protocol and sent over 821the network back to the client.</li> 822 823<li>serveroutlen - length of bytes to send to client</li> 824</ul> 825 826This function begins the authentication process with a client. If 827the program returns SASL_CONTINUE that means <tt>serverout</tt> 828should be sent to the client. If SASL_OK is returned that means 829authentication is complete and the application should tell the 830client the authentication was successful. Any other return code 831means the authentication failed and the client should be notified 832of this. 833 834<h3><a name="sasl_server_step">sasl_server_step</a></h3> 835 836<pre> 837 int sasl_server_step(sasl_conn_t *conn, 838 const char *clientin, 839 unsigned clientinlen, 840 const char **serverout, 841 unsigned *serveroutlen); 842 843</pre> 844 845Parameters: 846 847<ul> 848<li>conn - The context for the connection</li> 849 850<li>clientin - Data sent by the client.</li> 851 852<li>clientinlen - The length of the client data. Note that this may 853be 0</li> 854 855<li>serverout - allocated and filled in by the function. These are 856the bytes that should be encoded as per the protocol and sent over 857the network back to the client.</li> 858 859<li>serveroutlen - length of bytes to send to client. Note that 860this may be 0</li> 861</ul> 862 863This function preforms a step of the authentication. This may need 864to be called an arbitrary number of times. If the program returns 865SASL_CONTINUE that means <tt>serverout</tt> should be sent to the 866client. If SASL_OK is returned that means authentication is 867complete and the application should tell the client the 868authentication was successful. Any other return code means the 869authentication failed and the client should be notified of this. 870 871<h3><a name="sasl_listmech">sasl_listmech</a></h3> 872 873<pre> 874 int sasl_listmech(sasl_conn_t *conn, 875 const char *user, 876 const char *prefix, 877 const char *sep, 878 const char *suffix, 879 const char **result, 880 unsigned *plen, 881 unsigned *pcount); 882 883</pre> 884 885Parameters: 886 887<ul> 888<li>conn - The context for this connection</li> 889 890<li>user - Currently not implemented</li> 891 892<li>prefix - The string to prepend</li> 893 894<li>sep - The string to separate mechanisms with</li> 895 896<li>suffix - The string to end with</li> 897 898<li>result - Resultant string</li> 899 900<li>plen - Number of characters in the result string</li> 901 902<li>pcount - Number of mechanisms listed in the result string</li> 903</ul> 904 905This function is used to create a string with a list of SASL 906mechanisms supported by the server. This string is often needed for 907a capability statement. 908 909<h3><a name="sasl_checkpass">sasl_checkpass</a></h3> 910 911<pre> 912 int sasl_checkpass(sasl_conn_t *conn, 913 const char *user, 914 unsigned userlen, 915 const char *pass, 916 unsigned passlen); 917 918</pre> 919 920Parameters: 921 922<ul> 923<li>conn - The context for this connection</li> 924 925<li>user - The user trying to check the password for</li> 926 927<li>userlen - The user length</li> 928 929<li>pass - The password</li> 930 931<li>passlen - The password length</li> 932</ul> 933 934This checks a plaintext password <i>pass</i> for user <i>user</i> 935Some protocols have legacy systems for plaintext authentication 936where this might be used. 937 938<h2><a name="common_section">Common Section</a></h2> 939 940<h3><a name="callbacks_interactions">Callbacks and 941Interactions</a></h3> 942 943When the application starts and calls sasl_client_init() you must 944specify for what data you support callbacks and/or interactions. 945These are for the library getting information needed for 946authentication from the application. This is needed for things like 947authentication name and password. If you do not declare supporting 948a callback you will not be able to use mechanisms that need that 949data. A callback is for when you have the information before you 950start the authentication. The SASL library calls a function you 951specify and your function fills in the requested information. For 952example if you had the userid of the user already for some reason. 953An interaction is usually for things you support but will need to 954ask the user for (e.g. password). sasl_client_start() or 955sasl_client_step() will return SASL_INTERACT. This will be a list 956of sasl_interact_t's which contain a human readable string you can 957prompt the user with, a possible computer readable string, and a 958default result. The nice thing about interactions is you get them 959all at once so if you had a GUI application you could bring up a 960dialog box asking for authentication name and password together 961instead of one at a time. 962 963<p>Any memory that is given to the SASL library for the purposes of 964callbacks and interactions must persist until the exchange 965completes in either success or failure. That is, the data must 966persist until <tt>sasl_client_start</tt> or 967<tt>sasl_client_step</tt> returns something other than 968<tt>SASL_INTERACT</tt> or <tt>SASL_CONTINUE</tt>.</p> 969 970<p><b>Memory management:</b>As in the rest of the SASLv2 API, 971whoever allocates the memory is responsible for freeing it. In 972almost all cases this should be fairly easy to manage, however a 973slight exception where the interaction sasl_interact_t structure is 974allocated and freed by the library, while the results are allocated 975and freed by the application. As noted above, however, <i>the 976results may not be freed until after the exchange completes, in 977either success or failure</i>.</p> 978 979<p>For a detailed description of what each of the callback types 980are see the sasl.h file. Here are some brief explanations:</p> 981 982<ul> 983<li>SASL_CB_AUTHNAME - the name of the user authenticating</li> 984 985<li>SASL_CB_USER - the name of the user acting for. (for example 986postman delivering mail for tmartin might have an AUTHNAME of 987postman and a USER of tmartin)</li> 988 989<li>SASL_CB_PASS - password for AUTHNAME</li> 990 991<li>SASL_CB_GETREALM - Realm of the server</li> 992</ul> 993 994An example of a way to handle callbacks: 995 996<pre> 997 /* callbacks we support. This is a global variable at the 998 top of the program */ 999 static sasl_callback_t callbacks[] = { 1000 { 1001 SASL_CB_GETREALM, NULL, NULL /* we'll just use an interaction if this comes up */ 1002 }, { 1003 SASL_CB_USER, NULL, NULL /* we'll just use an interaction if this comes up */ 1004 }, { 1005 SASL_CB_AUTHNAME, &getauthname_func, NULL /* A mechanism should call getauthname_func 1006 if it needs the authentication name */ 1007 }, { 1008 SASL_CB_PASS, &getsecret_func, NULL /* Call getsecret_func if need secret */ 1009 }, { 1010 SASL_CB_LIST_END, NULL, NULL 1011 } 1012 }; 1013 1014 1015 static int getsecret_func(sasl_conn_t *conn, 1016 void *context __attribute__((unused)), 1017 int id, 1018 sasl_secret_t **psecret) 1019 { 1020 [ask the user for their secret] 1021 1022 [allocate psecret and insert the secret] 1023 1024 return SASL_OK; 1025 } 1026 1027 static int getauthname_func(void *context, 1028 int id, 1029 const char **result, 1030 unsigned *len) 1031 { 1032 if (id!=SASL_CB_AUTHNAME) return SASL_FAIL; 1033 1034 [fill in result and len] 1035 1036 return SASL_OK; 1037 } 1038 1039 1040 in the main program somewhere 1041 1042 sasl_client_init(callbacks); 1043 1044 1045</pre> 1046 1047<h3><a name="layers">Security layers</a></h3> 1048 1049<p>All is well and good to securely authenticate, but if you don't 1050have some sort of integrity or privacy layer, anyone can hijack 1051your TCP session after authentication. If your application has 1052indicated that it can support a security layer, one <i>might</i> be 1053negotiated.</p> 1054 1055<p>To set that you support a security layer, set a security 1056property structure with <tt>max_ssf</tt> set to a non-zero 1057number:</p> 1058 1059<pre> 1060 sasl_security_properties_t secprops; 1061 1062 secprops.min_ssf = 0; 1063 secprops.max_ssf = 256; 1064 secprops.maxbufsize = /* SEE BELOW */; 1065 1066 secprops.property_names = NULL; 1067 secprops.property_values = NULL; 1068 secprops.security_flags = SASL_SEC_NOANONYMOUS; /* as appropriate */ 1069 1070 sasl_setprop(conn, SASL_SEC_PROPS, &secprops); 1071</pre> 1072 1073The <tt>secprops</tt> variable will be copied during the call to 1074<tt>sasl_setprop</tt>, so you may free its memory immediately. The 1075<i>SSF</i> stands for <i>security strength factor</i> and is a 1076rough indication of how "secure" the connection is. A connection 1077supplying only integrity with no privacy would have an SSF of 1. A 1078connection secured by 56-bit DES would have an SSF of 56. 1079 1080<p>To require a security layer, set <tt>min_ssf</tt> to the minimum 1081acceptable security layer strength.</p> 1082 1083<p>After authentication is successful, you can determine whether or 1084not a security layer has been negotiated by looking at the SASL_SSF 1085property:</p> 1086 1087<pre> 1088 const int *ssfp; 1089 1090 result = sasl_getprop(conn, SASL_SSF, (const **) &ssfp); 1091 if (result != SASL_OK) { 1092 /* ??? */ 1093 } 1094 if (*ssfp > 0) { 1095 /* yay, we have a security layer! */ 1096 } 1097</pre> 1098 1099<p>If a security layer has been negotiated, your application must 1100make use of the <tt>sasl_encode()</tt> and <tt>sasl_decode()</tt> 1101calls. All output must be passed through <tt>sasl_encode()</tt> 1102before being written to the wire; all input must be passed through 1103<tt>sasl_decode()</tt> before being looked at by the application. 1104Your application must also be prepared to deal with 1105<tt>sasl_decode()</tt> not returning any data in the rare case that 1106the peer application did something strange (by splitting a single 1107SASL blob into two seperate TCP packets).</p> 1108 1109<p>The only subtlety dealing with security layers is the maximum size 1110of data that can be passed through <tt>sasl_encode()</tt> or 1111<tt>sasl_decode()</tt>. This must be limited to make sure that only 1112a finite amount of data needs to be buffered. The simple rules to 1113follow:</p> 1114 1115<ul> 1116<li>Before starting authentication, set <tt>maxbufsize</tt> in your 1117security properties to be the buffer size that you pass to the 1118<tt>read()</tt> system call—that is, the amount of data 1119you're prepared to read at any one time.</li> 1120 1121<li>After authentication finishes, use <tt>sasl_getprop()</tt> to 1122retrieve the <tt>SASL_MAXOUTBUF</tt> value, and call 1123<tt>sasl_encode()</tt> with chunks of data of that size or less. 1124<tt>sasl_encode()</tt> will throw an error if you call it with a 1125larger chunk of data, so be careful!</li> 1126</ul> 1127 1128<p><b>Memory management:</b> As usual, whoever allocates the memory 1129must free it. The SASL library will keep the data returned from 1130<tt>sasl_encode()</tt> until the next call to <tt>sasl_encode()</tt> 1131on that connection. (<tt>sasl_decode()</tt> results persist until the 1132next call to <tt>sasl_decode()</tt> on that connection.) The 1133application must not attempt to free the memory returned from either 1134function.</p> 1135 1136<p><b>Internally:</b></p> 1137 1138<ul> 1139<li>your application sets SASL_SEC_PROPS with the buffer size X of 1140the amount of data it will be using to read() from the socket.</li> 1141 1142<li>libsasl passes this number to the mechanism.</li> 1143 1144<li>the mechanism passes this number to the other side. the other 1145side gives the corresponding read() size to our side.</li> 1146 1147<li>the mechanism subtracts the overhead of the layers from the 1148size retrieved from the other side and returns it to the 1149libsasl.</li> 1150 1151<li>libsasl then returns (via SASL_MAXOUTBUF) this number as the 1152maximum amount of plaintext material that can be encoded at any one 1153time, Y.</li> 1154 1155<li>sasl_encode() enforces the restriction of the length Y.</li> 1156</ul> 1157 1158<h2><a name="example_section">Example applications that come with 1159the Cyrus SASL library</a></h2> 1160 1161<h3><a name="sample_client"><tt>sample-client</tt> and 1162<tt>sample-server</tt></a></h3> 1163 1164The sample client and server included with this distribution were 1165initially written to help debug mechanisms. They base64 encode all 1166the data and print it out on standard output. 1167 1168<p>Make sure that you set the IP addresses, the username, the 1169authenticate name, and anything else on the command line (some 1170mechanisms depend on these being present).</p> 1171 1172<p>Also, sometimes you will receive a get "<tt>realm: Information 1173not available</tt>" message, or similar; this is due to the fact 1174that some mechanisms do not support realms and therefore never set 1175it.</p> 1176 1177<h3><a name="cyrus_imapd">Cyrus imapd v2.1.0 or later</a></h3> 1178 1179The Cyrus IMAP server now incorporates SASLv2 for all its 1180authentication needs. It is a good example of a fairly large server 1181application. Also of interest is the prot layer, included in 1182libcyrus. This is a stdio-like interface that automatically takes 1183care of layers using a simple "<tt>prot_setsasl()</tt>" call. 1184 1185<p>Cyrus imapd also sets a <tt>SASL_CB_PROXY_POLICY</tt> callback, 1186which should be of interest to many applications.</p> 1187 1188<h3><a name="imtest"><tt>imtest</tt>, from Cyrus 2.1.0 or 1189later</a></h3> 1190 1191<tt>imtest</tt> is an application included with Cyrus imapd. It is 1192a very simple IMAP client, but should be of interest to those 1193writing applications. It also uses the prot layer, but it is easy 1194to incorporate similar support without using the prot layer. 1195Likewise, there are other sample client applications that you can 1196look at including <tt>smtptest</tt> and <tt>pop3test</tt> in the 1197SASL distribution and the Cyrus IMAPd distribution, respectively. 1198 1199<h2><a name="random_things">Miscellaneous Information</a></h2> 1200 1201<h3><a name="empty_exchanges">Empty exchanges</a></h3> 1202 1203<p>Some SASL mechanisms intentionally send no data; an application 1204should be prepared to either send or receive an empty exchange. The 1205SASL profile for the protocol should define how to send an empty 1206string; make sure to send an empty string when requested, and when 1207receiving an empty string make sure that the "<tt>inlength</tt>" 1208passed in is 0.</p> 1209 1210<p>Note especially that the distinction between the empty string "" 1211and the lack of a string (NULL) is extremely important in many 1212cases (most notably, the client-send first scenario), and the 1213application must ensure that it is passing the correct values to 1214the SASL library at all times.</p> 1215 1216<h3><a name="idle">Idle</a></h3> 1217 1218While the implementation and the plugins correctly implement the 1219idle calls, none of them currently do anything. 1220 1221<hr> 1222Please send any questions or comments to: 1223 1224<address><a href= 1225"mailto:cyrus-bugs@andrew.cmu.edu">cyrus-bugs@andrew.cmu.edu</a></address> 1226 1227<br> 1228 Back to the <a href="index.html">index</a> 1229</body> 1230</html> 1231 1232