]> git.sur5r.net Git - openldap/blob - libraries/liblutil/sasl.c
Fix includes for EBCDIC
[openldap] / libraries / liblutil / sasl.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #ifdef HAVE_CYRUS_SASL
10
11 #include <stdio.h>
12 #include <ac/stdlib.h>
13 #include <ac/string.h>
14 #include <ac/unistd.h>
15
16 #ifdef HAVE_SASL_SASL_H
17 #include <sasl/sasl.h>
18 #else
19 #include <sasl.h>
20 #endif
21
22 #include <ldap.h>
23 #include "ldap_pvt.h"
24 #include "lutil_ldap.h"
25
26
27 typedef struct lutil_sasl_defaults_s {
28         char *mech;
29         char *realm;
30         char *authcid;
31         char *passwd;
32         char *authzid;
33         char **resps;
34         int nresps;
35 } lutilSASLdefaults;
36
37
38 void
39 lutil_sasl_freedefs(
40         void *defaults )
41 {
42         lutilSASLdefaults *defs = defaults;
43         
44         if (defs->mech) ber_memfree(defs->mech);
45         if (defs->realm) ber_memfree(defs->realm);
46         if (defs->authcid) ber_memfree(defs->authcid);
47         if (defs->passwd) ber_memfree(defs->passwd);
48         if (defs->authzid) ber_memfree(defs->authzid);
49         if (defs->resps) ldap_charray_free(defs->resps);
50
51         ber_memfree(defs);
52 }
53
54 void *
55 lutil_sasl_defaults(
56         LDAP *ld,
57         char *mech,
58         char *realm,
59         char *authcid,
60         char *passwd,
61         char *authzid )
62 {
63         lutilSASLdefaults *defaults;
64         
65         defaults = ber_memalloc( sizeof( lutilSASLdefaults ) );
66
67         if( defaults == NULL ) return NULL;
68
69         defaults->mech = mech ? ber_strdup(mech) : NULL;
70         defaults->realm = realm ? ber_strdup(realm) : NULL;
71         defaults->authcid = authcid ? ber_strdup(authcid) : NULL;
72         defaults->passwd = passwd ? ber_strdup(passwd) : NULL;
73         defaults->authzid = authzid ? ber_strdup(authzid) : NULL;
74
75         if( defaults->mech == NULL ) {
76                 ldap_get_option( ld, LDAP_OPT_X_SASL_MECH, &defaults->mech );
77         }
78         if( defaults->realm == NULL ) {
79                 ldap_get_option( ld, LDAP_OPT_X_SASL_REALM, &defaults->realm );
80         }
81         if( defaults->authcid == NULL ) {
82                 ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid );
83         }
84         if( defaults->authzid == NULL ) {
85                 ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid );
86         }
87         defaults->resps = NULL;
88         defaults->nresps = 0;
89
90         return defaults;
91 }
92
93 static int interaction(
94         unsigned flags,
95         sasl_interact_t *interact,
96         lutilSASLdefaults *defaults )
97 {
98         const char *dflt = interact->defresult;
99         char input[1024];
100
101         int noecho=0;
102         int challenge=0;
103
104         switch( interact->id ) {
105         case SASL_CB_GETREALM:
106                 if( defaults ) dflt = defaults->realm;
107                 break;
108         case SASL_CB_AUTHNAME:
109                 if( defaults ) dflt = defaults->authcid;
110                 break;
111         case SASL_CB_PASS:
112                 if( defaults ) dflt = defaults->passwd;
113                 noecho = 1;
114                 break;
115         case SASL_CB_USER:
116                 if( defaults ) dflt = defaults->authzid;
117                 break;
118         case SASL_CB_NOECHOPROMPT:
119                 noecho = 1;
120                 challenge = 1;
121                 break;
122         case SASL_CB_ECHOPROMPT:
123                 challenge = 1;
124                 break;
125         }
126
127         if( dflt && !*dflt ) dflt = NULL;
128
129         if( flags != LDAP_SASL_INTERACTIVE &&
130                 ( dflt || interact->id == SASL_CB_USER ) )
131         {
132                 goto use_default;
133         }
134
135         if( flags == LDAP_SASL_QUIET ) {
136                 /* don't prompt */
137                 return LDAP_OTHER;
138         }
139
140         if( challenge ) {
141                 if( interact->challenge ) {
142                         fprintf( stderr, _("Challenge: %s\n"), interact->challenge );
143                 }
144         }
145
146         if( dflt ) {
147                 fprintf( stderr, _("Default: %s\n"), dflt );
148         }
149
150         snprintf( input, sizeof input, "%s: ",
151                 interact->prompt ? interact->prompt : _("Interact") );
152
153         if( noecho ) {
154                 interact->result = (char *) getpassphrase( input );
155                 interact->len = interact->result
156                         ? strlen( interact->result ) : 0;
157
158         } else {
159                 /* prompt user */
160                 fputs( input, stderr );
161
162                 /* get input */
163                 interact->result = fgets( input, sizeof(input), stdin );
164
165                 if( interact->result == NULL ) {
166                         interact->len = 0;
167                         return LDAP_UNAVAILABLE;
168                 }
169
170                 /* len of input */
171                 interact->len = strlen(input); 
172
173                 if( interact->len > 0 && input[interact->len - 1] == '\n' ) {
174                         /* input includes '\n', trim it */
175                         interact->len--;
176                         input[interact->len] = '\0';
177                 }
178         }
179
180
181         if( interact->len > 0 ) {
182                 /* duplicate */
183                 char *p = (char *)interact->result;
184                 ldap_charray_add(&defaults->resps, interact->result);
185                 interact->result = defaults->resps[defaults->nresps++];
186
187                 /* zap */
188                 memset( p, '\0', interact->len );
189
190         } else {
191 use_default:
192                 /* input must be empty */
193                 interact->result = (dflt && *dflt) ? dflt : "";
194                 interact->len = strlen( interact->result );
195         }
196
197         return LDAP_SUCCESS;
198 }
199
200 int lutil_sasl_interact(
201         LDAP *ld,
202         unsigned flags,
203         void *defaults,
204         void *in )
205 {
206         sasl_interact_t *interact = in;
207
208         if( ld == NULL ) return LDAP_PARAM_ERROR;
209
210         if( flags == LDAP_SASL_INTERACTIVE ) {
211                 fputs( _("SASL Interaction\n"), stderr );
212         }
213
214         while( interact->id != SASL_CB_LIST_END ) {
215                 int rc = interaction( flags, interact, defaults );
216
217                 if( rc )  return rc;
218                 interact++;
219         }
220         
221         return LDAP_SUCCESS;
222 }
223 #endif