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