17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /* Plain SASL plugin
77c478bd9Sstevel@tonic-gate * Rob Siemborski
8*1da57d55SToomas Soome * Tim Martin
97c478bd9Sstevel@tonic-gate * $Id: plain.c,v 1.61 2003/03/26 17:18:04 rjs3 Exp $
107c478bd9Sstevel@tonic-gate */
117c478bd9Sstevel@tonic-gate
12*1da57d55SToomas Soome /*
137c478bd9Sstevel@tonic-gate * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
147c478bd9Sstevel@tonic-gate *
157c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
167c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions
177c478bd9Sstevel@tonic-gate * are met:
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
20*1da57d55SToomas Soome * notice, this list of conditions and the following disclaimer.
217c478bd9Sstevel@tonic-gate *
227c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
237c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
247c478bd9Sstevel@tonic-gate * the documentation and/or other materials provided with the
257c478bd9Sstevel@tonic-gate * distribution.
267c478bd9Sstevel@tonic-gate *
277c478bd9Sstevel@tonic-gate * 3. The name "Carnegie Mellon University" must not be used to
287c478bd9Sstevel@tonic-gate * endorse or promote products derived from this software without
297c478bd9Sstevel@tonic-gate * prior written permission. For permission or any other legal
30*1da57d55SToomas Soome * details, please contact
317c478bd9Sstevel@tonic-gate * Office of Technology Transfer
327c478bd9Sstevel@tonic-gate * Carnegie Mellon University
337c478bd9Sstevel@tonic-gate * 5000 Forbes Avenue
347c478bd9Sstevel@tonic-gate * Pittsburgh, PA 15213-3890
357c478bd9Sstevel@tonic-gate * (412) 268-4387, fax: (412) 268-7395
367c478bd9Sstevel@tonic-gate * tech-transfer@andrew.cmu.edu
377c478bd9Sstevel@tonic-gate *
387c478bd9Sstevel@tonic-gate * 4. Redistributions of any form whatsoever must retain the following
397c478bd9Sstevel@tonic-gate * acknowledgment:
407c478bd9Sstevel@tonic-gate * "This product includes software developed by Computing Services
417c478bd9Sstevel@tonic-gate * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
427c478bd9Sstevel@tonic-gate *
437c478bd9Sstevel@tonic-gate * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
447c478bd9Sstevel@tonic-gate * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
457c478bd9Sstevel@tonic-gate * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
467c478bd9Sstevel@tonic-gate * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
477c478bd9Sstevel@tonic-gate * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
487c478bd9Sstevel@tonic-gate * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
497c478bd9Sstevel@tonic-gate * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
507c478bd9Sstevel@tonic-gate */
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate #include <config.h>
537c478bd9Sstevel@tonic-gate #include <stdio.h>
54*1da57d55SToomas Soome #include <string.h>
557c478bd9Sstevel@tonic-gate #include <sasl.h>
567c478bd9Sstevel@tonic-gate #include <saslplug.h>
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate #include "plugin_common.h"
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
617c478bd9Sstevel@tonic-gate #ifdef WIN32
627c478bd9Sstevel@tonic-gate /* This must be after sasl.h */
637c478bd9Sstevel@tonic-gate # include "saslPLAIN.h"
647c478bd9Sstevel@tonic-gate #endif /* WIN32 */
657c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
667c478bd9Sstevel@tonic-gate
67*1da57d55SToomas Soome #ifdef macintosh
68*1da57d55SToomas Soome #include <sasl_plain_plugin_decl.h>
69*1da57d55SToomas Soome #endif
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate /***************************** Common Section *****************************/
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
747c478bd9Sstevel@tonic-gate static const char plugin_id[] = "$Id: plain.c,v 1.61 2003/03/26 17:18:04 rjs3 Exp $";
757c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate /***************************** Server Section *****************************/
787c478bd9Sstevel@tonic-gate
plain_server_mech_new(void * glob_context,sasl_server_params_t * sparams,const char * challenge,unsigned challen,void ** conn_context)79*1da57d55SToomas Soome static int plain_server_mech_new(void *glob_context __attribute__((unused)),
807c478bd9Sstevel@tonic-gate sasl_server_params_t *sparams,
817c478bd9Sstevel@tonic-gate const char *challenge __attribute__((unused)),
827c478bd9Sstevel@tonic-gate unsigned challen __attribute__((unused)),
837c478bd9Sstevel@tonic-gate void **conn_context)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate /* holds state are in */
867c478bd9Sstevel@tonic-gate if (!conn_context) {
877c478bd9Sstevel@tonic-gate PARAMERROR( sparams->utils );
887c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
897c478bd9Sstevel@tonic-gate }
90*1da57d55SToomas Soome
917c478bd9Sstevel@tonic-gate *conn_context = NULL;
92*1da57d55SToomas Soome
937c478bd9Sstevel@tonic-gate return SASL_OK;
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate
plain_server_mech_step(void * conn_context,sasl_server_params_t * params,const char * clientin,unsigned clientinlen,const char ** serverout,unsigned * serveroutlen,sasl_out_params_t * oparams)967c478bd9Sstevel@tonic-gate static int plain_server_mech_step(void *conn_context __attribute__((unused)),
977c478bd9Sstevel@tonic-gate sasl_server_params_t *params,
987c478bd9Sstevel@tonic-gate const char *clientin,
997c478bd9Sstevel@tonic-gate unsigned clientinlen,
1007c478bd9Sstevel@tonic-gate const char **serverout,
1017c478bd9Sstevel@tonic-gate unsigned *serveroutlen,
1027c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams)
1037c478bd9Sstevel@tonic-gate {
1047c478bd9Sstevel@tonic-gate const char *author;
1057c478bd9Sstevel@tonic-gate const char *authen;
1067c478bd9Sstevel@tonic-gate const char *password;
1077c478bd9Sstevel@tonic-gate size_t password_len;
1087c478bd9Sstevel@tonic-gate unsigned lup=0;
1097c478bd9Sstevel@tonic-gate int result;
110*1da57d55SToomas Soome char *passcopy;
111*1da57d55SToomas Soome
1127c478bd9Sstevel@tonic-gate *serverout = NULL;
1137c478bd9Sstevel@tonic-gate *serveroutlen = 0;
114*1da57d55SToomas Soome
1157c478bd9Sstevel@tonic-gate /* should have received author-id NUL authen-id NUL password */
116*1da57d55SToomas Soome
1177c478bd9Sstevel@tonic-gate /* get author */
1187c478bd9Sstevel@tonic-gate author = clientin;
1197c478bd9Sstevel@tonic-gate while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
120*1da57d55SToomas Soome
1217c478bd9Sstevel@tonic-gate if (lup >= clientinlen) {
1227c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
1237c478bd9Sstevel@tonic-gate params->utils->log(params->utils->conn, SASL_LOG_ERR,
1247c478bd9Sstevel@tonic-gate "Can only find author (no password)");
1257c478bd9Sstevel@tonic-gate #else
1267c478bd9Sstevel@tonic-gate SETERROR(params->utils, "Can only find author (no password)");
1277c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1287c478bd9Sstevel@tonic-gate return SASL_BADPROT;
1297c478bd9Sstevel@tonic-gate }
130*1da57d55SToomas Soome
1317c478bd9Sstevel@tonic-gate /* get authen */
1327c478bd9Sstevel@tonic-gate ++lup;
1337c478bd9Sstevel@tonic-gate authen = clientin + lup;
1347c478bd9Sstevel@tonic-gate while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
135*1da57d55SToomas Soome
1367c478bd9Sstevel@tonic-gate if (lup >= clientinlen) {
1377c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
1387c478bd9Sstevel@tonic-gate params->utils->log(params->utils->conn, SASL_LOG_ERR,
1397c478bd9Sstevel@tonic-gate "Can only find author/en (no password)");
1407c478bd9Sstevel@tonic-gate #else
1417c478bd9Sstevel@tonic-gate params->utils->seterror(params->utils->conn, 0,
1427c478bd9Sstevel@tonic-gate "Can only find author/en (no password)");
1437c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1447c478bd9Sstevel@tonic-gate return SASL_BADPROT;
1457c478bd9Sstevel@tonic-gate }
146*1da57d55SToomas Soome
1477c478bd9Sstevel@tonic-gate /* get password */
1487c478bd9Sstevel@tonic-gate lup++;
1497c478bd9Sstevel@tonic-gate password = clientin + lup;
1507c478bd9Sstevel@tonic-gate while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
151*1da57d55SToomas Soome
1527c478bd9Sstevel@tonic-gate password_len = clientin + lup - password;
153*1da57d55SToomas Soome
1547c478bd9Sstevel@tonic-gate if (lup != clientinlen) {
1557c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
1567c478bd9Sstevel@tonic-gate params->utils->log(params->utils->conn, SASL_LOG_ERR,
1577c478bd9Sstevel@tonic-gate "Got more data than we were expecting in the PLAIN plugin");
1587c478bd9Sstevel@tonic-gate #else
1597c478bd9Sstevel@tonic-gate SETERROR(params->utils,
1607c478bd9Sstevel@tonic-gate "Got more data than we were expecting in the PLAIN plugin\n");
1617c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
1627c478bd9Sstevel@tonic-gate return SASL_BADPROT;
1637c478bd9Sstevel@tonic-gate }
164*1da57d55SToomas Soome
1657c478bd9Sstevel@tonic-gate /* this kinda sucks. we need password to be null terminated
1667c478bd9Sstevel@tonic-gate but we can't assume there is an allocated byte at the end
1677c478bd9Sstevel@tonic-gate of password so we have to copy it */
168*1da57d55SToomas Soome passcopy = params->utils->malloc(password_len + 1);
1697c478bd9Sstevel@tonic-gate if (passcopy == NULL) {
1707c478bd9Sstevel@tonic-gate MEMERROR(params->utils);
1717c478bd9Sstevel@tonic-gate return SASL_NOMEM;
1727c478bd9Sstevel@tonic-gate }
173*1da57d55SToomas Soome
1747c478bd9Sstevel@tonic-gate strncpy(passcopy, password, password_len);
1757c478bd9Sstevel@tonic-gate passcopy[password_len] = '\0';
176*1da57d55SToomas Soome
1777c478bd9Sstevel@tonic-gate /* Canonicalize userid first, so that password verification is only
1787c478bd9Sstevel@tonic-gate * against the canonical id */
1797c478bd9Sstevel@tonic-gate if (!author || !*author)
1807c478bd9Sstevel@tonic-gate author = authen;
181*1da57d55SToomas Soome
1827c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn,
1837c478bd9Sstevel@tonic-gate authen, 0, SASL_CU_AUTHID, oparams);
1847c478bd9Sstevel@tonic-gate if (result != SASL_OK) {
1857c478bd9Sstevel@tonic-gate _plug_free_string(params->utils, &passcopy);
1867c478bd9Sstevel@tonic-gate return result;
1877c478bd9Sstevel@tonic-gate }
188*1da57d55SToomas Soome
1897c478bd9Sstevel@tonic-gate /* verify password - return sasl_ok on success*/
1907c478bd9Sstevel@tonic-gate result = params->utils->checkpass(params->utils->conn,
1917c478bd9Sstevel@tonic-gate oparams->authid, oparams->alen,
1927c478bd9Sstevel@tonic-gate passcopy, password_len);
193*1da57d55SToomas Soome
1947c478bd9Sstevel@tonic-gate _plug_free_string(params->utils, &passcopy);
195*1da57d55SToomas Soome
1967c478bd9Sstevel@tonic-gate if (result != SASL_OK) {
1977c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
1987c478bd9Sstevel@tonic-gate params->utils->seterror(params->utils->conn, 0,
1997c478bd9Sstevel@tonic-gate gettext("Password verification failed"));
2007c478bd9Sstevel@tonic-gate #else
2017c478bd9Sstevel@tonic-gate params->utils->seterror(params->utils->conn, 0,
2027c478bd9Sstevel@tonic-gate "Password verification failed");
2037c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
2047c478bd9Sstevel@tonic-gate return result;
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate /* Canonicalize and store the authorization ID */
2087c478bd9Sstevel@tonic-gate /* We need to do this after calling verify_user just in case verify_user
2097c478bd9Sstevel@tonic-gate * needed to get auxprops itself */
2107c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn,
2117c478bd9Sstevel@tonic-gate author, 0, SASL_CU_AUTHZID, oparams);
2127c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result;
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate /* Transition? */
2157c478bd9Sstevel@tonic-gate if (params->transition) {
2167c478bd9Sstevel@tonic-gate params->transition(params->utils->conn, password, password_len);
2177c478bd9Sstevel@tonic-gate }
218*1da57d55SToomas Soome
2197c478bd9Sstevel@tonic-gate /* set oparams */
2207c478bd9Sstevel@tonic-gate oparams->doneflag = 1;
2217c478bd9Sstevel@tonic-gate oparams->mech_ssf = 0;
2227c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 0;
2237c478bd9Sstevel@tonic-gate oparams->encode_context = NULL;
2247c478bd9Sstevel@tonic-gate oparams->encode = NULL;
2257c478bd9Sstevel@tonic-gate oparams->decode_context = NULL;
2267c478bd9Sstevel@tonic-gate oparams->decode = NULL;
2277c478bd9Sstevel@tonic-gate oparams->param_version = 0;
228*1da57d55SToomas Soome
2297c478bd9Sstevel@tonic-gate return SASL_OK;
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate
232*1da57d55SToomas Soome static sasl_server_plug_t plain_server_plugins[] =
2337c478bd9Sstevel@tonic-gate {
2347c478bd9Sstevel@tonic-gate {
2357c478bd9Sstevel@tonic-gate "PLAIN", /* mech_name */
2367c478bd9Sstevel@tonic-gate 0, /* max_ssf */
2377c478bd9Sstevel@tonic-gate SASL_SEC_NOANONYMOUS, /* security_flags */
2387c478bd9Sstevel@tonic-gate SASL_FEAT_WANT_CLIENT_FIRST
2397c478bd9Sstevel@tonic-gate | SASL_FEAT_ALLOWS_PROXY, /* features */
2407c478bd9Sstevel@tonic-gate NULL, /* glob_context */
2417c478bd9Sstevel@tonic-gate &plain_server_mech_new, /* mech_new */
2427c478bd9Sstevel@tonic-gate &plain_server_mech_step, /* mech_step */
2437c478bd9Sstevel@tonic-gate NULL, /* mech_dispose */
2447c478bd9Sstevel@tonic-gate NULL, /* mech_free */
2457c478bd9Sstevel@tonic-gate NULL, /* setpass */
2467c478bd9Sstevel@tonic-gate NULL, /* user_query */
2477c478bd9Sstevel@tonic-gate NULL, /* idle */
2487c478bd9Sstevel@tonic-gate NULL, /* mech_avail */
2497c478bd9Sstevel@tonic-gate NULL /* spare */
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate };
2527c478bd9Sstevel@tonic-gate
plain_server_plug_init(const sasl_utils_t * utils,int maxversion,int * out_version,sasl_server_plug_t ** pluglist,int * plugcount)2537c478bd9Sstevel@tonic-gate int plain_server_plug_init(const sasl_utils_t *utils,
2547c478bd9Sstevel@tonic-gate int maxversion,
2557c478bd9Sstevel@tonic-gate int *out_version,
2567c478bd9Sstevel@tonic-gate sasl_server_plug_t **pluglist,
2577c478bd9Sstevel@tonic-gate int *plugcount)
2587c478bd9Sstevel@tonic-gate {
2597c478bd9Sstevel@tonic-gate if (maxversion < SASL_SERVER_PLUG_VERSION) {
2607c478bd9Sstevel@tonic-gate SETERROR(utils, "PLAIN version mismatch");
2617c478bd9Sstevel@tonic-gate return SASL_BADVERS;
2627c478bd9Sstevel@tonic-gate }
263*1da57d55SToomas Soome
2647c478bd9Sstevel@tonic-gate *out_version = SASL_SERVER_PLUG_VERSION;
2657c478bd9Sstevel@tonic-gate *pluglist = plain_server_plugins;
266*1da57d55SToomas Soome *plugcount = 1;
267*1da57d55SToomas Soome
2687c478bd9Sstevel@tonic-gate return SASL_OK;
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate /***************************** Client Section *****************************/
2727c478bd9Sstevel@tonic-gate
2737c478bd9Sstevel@tonic-gate typedef struct client_context {
2747c478bd9Sstevel@tonic-gate char *out_buf;
2757c478bd9Sstevel@tonic-gate unsigned out_buf_len;
2767c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
2777c478bd9Sstevel@tonic-gate void *h;
2787c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
2797c478bd9Sstevel@tonic-gate } client_context_t;
2807c478bd9Sstevel@tonic-gate
plain_client_mech_new(void * glob_context,sasl_client_params_t * params,void ** conn_context)2817c478bd9Sstevel@tonic-gate static int plain_client_mech_new(void *glob_context __attribute__((unused)),
2827c478bd9Sstevel@tonic-gate sasl_client_params_t *params,
2837c478bd9Sstevel@tonic-gate void **conn_context)
2847c478bd9Sstevel@tonic-gate {
2857c478bd9Sstevel@tonic-gate client_context_t *text;
286*1da57d55SToomas Soome
2877c478bd9Sstevel@tonic-gate /* holds state are in */
2887c478bd9Sstevel@tonic-gate text = params->utils->malloc(sizeof(client_context_t));
2897c478bd9Sstevel@tonic-gate if (text == NULL) {
2907c478bd9Sstevel@tonic-gate MEMERROR( params->utils );
2917c478bd9Sstevel@tonic-gate return SASL_NOMEM;
2927c478bd9Sstevel@tonic-gate }
293*1da57d55SToomas Soome
2947c478bd9Sstevel@tonic-gate memset(text, 0, sizeof(client_context_t));
295*1da57d55SToomas Soome
2967c478bd9Sstevel@tonic-gate *conn_context = text;
297*1da57d55SToomas Soome
2987c478bd9Sstevel@tonic-gate return SASL_OK;
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate
plain_client_mech_step(void * conn_context,sasl_client_params_t * params,const char * serverin,unsigned serverinlen,sasl_interact_t ** prompt_need,const char ** clientout,unsigned * clientoutlen,sasl_out_params_t * oparams)3017c478bd9Sstevel@tonic-gate static int plain_client_mech_step(void *conn_context,
3027c478bd9Sstevel@tonic-gate sasl_client_params_t *params,
3037c478bd9Sstevel@tonic-gate const char *serverin __attribute__((unused)),
3047c478bd9Sstevel@tonic-gate unsigned serverinlen __attribute__((unused)),
3057c478bd9Sstevel@tonic-gate sasl_interact_t **prompt_need,
3067c478bd9Sstevel@tonic-gate const char **clientout,
3077c478bd9Sstevel@tonic-gate unsigned *clientoutlen,
3087c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams)
3097c478bd9Sstevel@tonic-gate {
3107c478bd9Sstevel@tonic-gate client_context_t *text = (client_context_t *) conn_context;
3117c478bd9Sstevel@tonic-gate const char *user = NULL, *authid = NULL;
3127c478bd9Sstevel@tonic-gate sasl_secret_t *password = NULL;
3137c478bd9Sstevel@tonic-gate unsigned int free_password = 0; /* set if we need to free password */
3147c478bd9Sstevel@tonic-gate int user_result = SASL_OK;
3157c478bd9Sstevel@tonic-gate int auth_result = SASL_OK;
3167c478bd9Sstevel@tonic-gate int pass_result = SASL_OK;
3177c478bd9Sstevel@tonic-gate int result;
318*1da57d55SToomas Soome
3197c478bd9Sstevel@tonic-gate *clientout = NULL;
3207c478bd9Sstevel@tonic-gate *clientoutlen = 0;
321*1da57d55SToomas Soome
3227c478bd9Sstevel@tonic-gate /* doesn't really matter how the server responds */
323*1da57d55SToomas Soome
3247c478bd9Sstevel@tonic-gate /* check if sec layer strong enough */
3257c478bd9Sstevel@tonic-gate if (params->props.min_ssf > params->external_ssf) {
3267c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
3277c478bd9Sstevel@tonic-gate SETERROR( params->utils, gettext("SSF requested of PLAIN plugin"));
3287c478bd9Sstevel@tonic-gate #else
3297c478bd9Sstevel@tonic-gate SETERROR( params->utils, "SSF requested of PLAIN plugin");
3307c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
3317c478bd9Sstevel@tonic-gate return SASL_TOOWEAK;
3327c478bd9Sstevel@tonic-gate }
333*1da57d55SToomas Soome
334*1da57d55SToomas Soome /* try to get the authid */
3357c478bd9Sstevel@tonic-gate if (oparams->authid == NULL) {
3367c478bd9Sstevel@tonic-gate auth_result = _plug_get_authid(params->utils, &authid, prompt_need);
337*1da57d55SToomas Soome
3387c478bd9Sstevel@tonic-gate if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
3397c478bd9Sstevel@tonic-gate return auth_result;
340*1da57d55SToomas Soome }
341*1da57d55SToomas Soome
3427c478bd9Sstevel@tonic-gate /* try to get the userid */
3437c478bd9Sstevel@tonic-gate if (oparams->user == NULL) {
3447c478bd9Sstevel@tonic-gate user_result = _plug_get_userid(params->utils, &user, prompt_need);
345*1da57d55SToomas Soome
3467c478bd9Sstevel@tonic-gate if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
3477c478bd9Sstevel@tonic-gate return user_result;
3487c478bd9Sstevel@tonic-gate }
349*1da57d55SToomas Soome
3507c478bd9Sstevel@tonic-gate /* try to get the password */
3517c478bd9Sstevel@tonic-gate if (password == NULL) {
3527c478bd9Sstevel@tonic-gate pass_result = _plug_get_password(params->utils, &password,
3537c478bd9Sstevel@tonic-gate &free_password, prompt_need);
354*1da57d55SToomas Soome
3557c478bd9Sstevel@tonic-gate if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
3567c478bd9Sstevel@tonic-gate return pass_result;
3577c478bd9Sstevel@tonic-gate }
358*1da57d55SToomas Soome
3597c478bd9Sstevel@tonic-gate /* free prompts we got */
3607c478bd9Sstevel@tonic-gate if (prompt_need && *prompt_need) {
3617c478bd9Sstevel@tonic-gate params->utils->free(*prompt_need);
3627c478bd9Sstevel@tonic-gate *prompt_need = NULL;
3637c478bd9Sstevel@tonic-gate }
364*1da57d55SToomas Soome
3657c478bd9Sstevel@tonic-gate /* if there are prompts not filled in */
3667c478bd9Sstevel@tonic-gate if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) ||
3677c478bd9Sstevel@tonic-gate (pass_result == SASL_INTERACT)) {
3687c478bd9Sstevel@tonic-gate /* make the prompt list */
3697c478bd9Sstevel@tonic-gate result =
3707c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
3717c478bd9Sstevel@tonic-gate _plug_make_prompts(params->utils, &text->h, prompt_need,
3727c478bd9Sstevel@tonic-gate user_result == SASL_INTERACT ?
3737c478bd9Sstevel@tonic-gate convert_prompt(params->utils, &text->h,
3747c478bd9Sstevel@tonic-gate gettext("Please enter your authorization name"))
3757c478bd9Sstevel@tonic-gate : NULL,
3767c478bd9Sstevel@tonic-gate NULL,
3777c478bd9Sstevel@tonic-gate auth_result == SASL_INTERACT ?
3787c478bd9Sstevel@tonic-gate convert_prompt(params->utils, &text->h,
3797c478bd9Sstevel@tonic-gate gettext("Please enter your authentication name"))
3807c478bd9Sstevel@tonic-gate : NULL,
3817c478bd9Sstevel@tonic-gate NULL,
3827c478bd9Sstevel@tonic-gate pass_result == SASL_INTERACT ?
3837c478bd9Sstevel@tonic-gate convert_prompt(params->utils, &text->h,
3847c478bd9Sstevel@tonic-gate gettext("Please enter your password")) : NULL,
3857c478bd9Sstevel@tonic-gate NULL,
3867c478bd9Sstevel@tonic-gate NULL, NULL, NULL,
3877c478bd9Sstevel@tonic-gate NULL, NULL, NULL);
3887c478bd9Sstevel@tonic-gate #else
3897c478bd9Sstevel@tonic-gate _plug_make_prompts(params->utils, prompt_need,
3907c478bd9Sstevel@tonic-gate user_result == SASL_INTERACT ?
3917c478bd9Sstevel@tonic-gate "Please enter your authorization name" : NULL,
3927c478bd9Sstevel@tonic-gate NULL,
3937c478bd9Sstevel@tonic-gate auth_result == SASL_INTERACT ?
3947c478bd9Sstevel@tonic-gate "Please enter your authentication name" : NULL,
3957c478bd9Sstevel@tonic-gate NULL,
3967c478bd9Sstevel@tonic-gate pass_result == SASL_INTERACT ?
3977c478bd9Sstevel@tonic-gate "Please enter your password" : NULL, NULL,
3987c478bd9Sstevel@tonic-gate NULL, NULL, NULL,
3997c478bd9Sstevel@tonic-gate NULL, NULL, NULL);
4007c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
4017c478bd9Sstevel@tonic-gate if (result != SASL_OK) goto cleanup;
402*1da57d55SToomas Soome
4037c478bd9Sstevel@tonic-gate return SASL_INTERACT;
4047c478bd9Sstevel@tonic-gate }
405*1da57d55SToomas Soome
4067c478bd9Sstevel@tonic-gate if (!password) {
4077c478bd9Sstevel@tonic-gate PARAMERROR(params->utils);
4087c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
4097c478bd9Sstevel@tonic-gate }
4107c478bd9Sstevel@tonic-gate
4117c478bd9Sstevel@tonic-gate if (!user || !*user) {
4127c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn, authid, 0,
4137c478bd9Sstevel@tonic-gate SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate else {
4167c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn, user, 0,
4177c478bd9Sstevel@tonic-gate SASL_CU_AUTHZID, oparams);
4187c478bd9Sstevel@tonic-gate if (result != SASL_OK) goto cleanup;
419*1da57d55SToomas Soome
4207c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn, authid, 0,
4217c478bd9Sstevel@tonic-gate SASL_CU_AUTHID, oparams);
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate if (result != SASL_OK) goto cleanup;
424*1da57d55SToomas Soome
4257c478bd9Sstevel@tonic-gate /* send authorized id NUL authentication id NUL password */
4267c478bd9Sstevel@tonic-gate *clientoutlen = (oparams->ulen + 1
4277c478bd9Sstevel@tonic-gate + oparams->alen + 1
4287c478bd9Sstevel@tonic-gate + password->len);
429*1da57d55SToomas Soome
4307c478bd9Sstevel@tonic-gate /* remember the extra NUL on the end for stupid clients */
4317c478bd9Sstevel@tonic-gate result = _plug_buf_alloc(params->utils, &(text->out_buf),
4327c478bd9Sstevel@tonic-gate &(text->out_buf_len), *clientoutlen + 1);
4337c478bd9Sstevel@tonic-gate if (result != SASL_OK) goto cleanup;
434*1da57d55SToomas Soome
4357c478bd9Sstevel@tonic-gate memset(text->out_buf, 0, *clientoutlen + 1);
4367c478bd9Sstevel@tonic-gate memcpy(text->out_buf, oparams->user, oparams->ulen);
4377c478bd9Sstevel@tonic-gate memcpy(text->out_buf + oparams->ulen + 1, oparams->authid, oparams->alen);
4387c478bd9Sstevel@tonic-gate memcpy(text->out_buf + oparams->ulen + oparams->alen + 2,
4397c478bd9Sstevel@tonic-gate password->data, password->len);
440*1da57d55SToomas Soome
4417c478bd9Sstevel@tonic-gate *clientout = text->out_buf;
442*1da57d55SToomas Soome
4437c478bd9Sstevel@tonic-gate /* set oparams */
4447c478bd9Sstevel@tonic-gate oparams->doneflag = 1;
4457c478bd9Sstevel@tonic-gate oparams->mech_ssf = 0;
4467c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 0;
4477c478bd9Sstevel@tonic-gate oparams->encode_context = NULL;
4487c478bd9Sstevel@tonic-gate oparams->encode = NULL;
4497c478bd9Sstevel@tonic-gate oparams->decode_context = NULL;
4507c478bd9Sstevel@tonic-gate oparams->decode = NULL;
4517c478bd9Sstevel@tonic-gate oparams->param_version = 0;
452*1da57d55SToomas Soome
4537c478bd9Sstevel@tonic-gate result = SASL_OK;
4547c478bd9Sstevel@tonic-gate
4557c478bd9Sstevel@tonic-gate cleanup:
4567c478bd9Sstevel@tonic-gate /* free sensitive info */
4577c478bd9Sstevel@tonic-gate if (free_password) _plug_free_secret(params->utils, &password);
458*1da57d55SToomas Soome
4597c478bd9Sstevel@tonic-gate return result;
4607c478bd9Sstevel@tonic-gate }
4617c478bd9Sstevel@tonic-gate
plain_client_mech_dispose(void * conn_context,const sasl_utils_t * utils)4627c478bd9Sstevel@tonic-gate static void plain_client_mech_dispose(void *conn_context,
4637c478bd9Sstevel@tonic-gate const sasl_utils_t *utils)
4647c478bd9Sstevel@tonic-gate {
4657c478bd9Sstevel@tonic-gate client_context_t *text = (client_context_t *) conn_context;
466*1da57d55SToomas Soome
4677c478bd9Sstevel@tonic-gate if (!text) return;
468*1da57d55SToomas Soome
4697c478bd9Sstevel@tonic-gate if (text->out_buf) utils->free(text->out_buf);
4707c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
4717c478bd9Sstevel@tonic-gate convert_prompt(utils, &text->h, NULL);
4727c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
473*1da57d55SToomas Soome
4747c478bd9Sstevel@tonic-gate utils->free(text);
4757c478bd9Sstevel@tonic-gate }
4767c478bd9Sstevel@tonic-gate
477*1da57d55SToomas Soome static sasl_client_plug_t plain_client_plugins[] =
4787c478bd9Sstevel@tonic-gate {
4797c478bd9Sstevel@tonic-gate {
4807c478bd9Sstevel@tonic-gate "PLAIN", /* mech_name */
4817c478bd9Sstevel@tonic-gate 0, /* max_ssf */
4827c478bd9Sstevel@tonic-gate SASL_SEC_NOANONYMOUS, /* security_flags */
4837c478bd9Sstevel@tonic-gate SASL_FEAT_WANT_CLIENT_FIRST
4847c478bd9Sstevel@tonic-gate | SASL_FEAT_ALLOWS_PROXY, /* features */
4857c478bd9Sstevel@tonic-gate NULL, /* required_prompts */
4867c478bd9Sstevel@tonic-gate NULL, /* glob_context */
4877c478bd9Sstevel@tonic-gate &plain_client_mech_new, /* mech_new */
4887c478bd9Sstevel@tonic-gate &plain_client_mech_step, /* mech_step */
4897c478bd9Sstevel@tonic-gate &plain_client_mech_dispose, /* mech_dispose */
4907c478bd9Sstevel@tonic-gate NULL, /* mech_free */
4917c478bd9Sstevel@tonic-gate NULL, /* idle */
4927c478bd9Sstevel@tonic-gate NULL, /* spare */
4937c478bd9Sstevel@tonic-gate NULL /* spare */
4947c478bd9Sstevel@tonic-gate }
4957c478bd9Sstevel@tonic-gate };
4967c478bd9Sstevel@tonic-gate
plain_client_plug_init(sasl_utils_t * utils,int maxversion,int * out_version,sasl_client_plug_t ** pluglist,int * plugcount)4977c478bd9Sstevel@tonic-gate int plain_client_plug_init(sasl_utils_t *utils,
4987c478bd9Sstevel@tonic-gate int maxversion,
4997c478bd9Sstevel@tonic-gate int *out_version,
5007c478bd9Sstevel@tonic-gate sasl_client_plug_t **pluglist,
5017c478bd9Sstevel@tonic-gate int *plugcount)
5027c478bd9Sstevel@tonic-gate {
5037c478bd9Sstevel@tonic-gate if (maxversion < SASL_CLIENT_PLUG_VERSION) {
5047c478bd9Sstevel@tonic-gate SETERROR(utils, "PLAIN version mismatch");
5057c478bd9Sstevel@tonic-gate return SASL_BADVERS;
5067c478bd9Sstevel@tonic-gate }
507*1da57d55SToomas Soome
5087c478bd9Sstevel@tonic-gate *out_version = SASL_CLIENT_PLUG_VERSION;
5097c478bd9Sstevel@tonic-gate *pluglist = plain_client_plugins;
5107c478bd9Sstevel@tonic-gate *plugcount = 1;
511*1da57d55SToomas Soome
5127c478bd9Sstevel@tonic-gate return SASL_OK;
5137c478bd9Sstevel@tonic-gate }
514