]> git.sur5r.net Git - openldap/blob - libraries/liblutil/sasl.c
743758f815e86efe6d7f4244771ebd6bc90fa7a1
[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 && dflt ) {
105                 goto use_default;
106         }
107
108         if( flags == LDAP_SASL_QUIET ) {
109                 /* don't prompt */
110                 return LDAP_OTHER;
111         }
112
113         if( challenge ) {
114                 if( interact->challenge ) {
115                         fprintf( stderr, "Challenge: %s\n", interact->challenge );
116                 }
117         }
118
119         if( dflt ) {
120                 fprintf( stderr, "Default: %s\n", dflt );
121         }
122
123         sprintf( input, "%s: ",
124                 interact->prompt ? interact->prompt : "Interact" );
125
126         if( noecho ) {
127                 interact->result = (char *) getpassphrase( input );
128                 interact->len = interact->result
129                         ? strlen( interact->result ) : 0;
130
131         } else {
132                 /* prompt user */
133                 fputs( input, stderr );
134
135                 /* get input */
136                 interact->result = fgets( input, sizeof(input), stdin );
137
138                 if( interact->result == NULL ) {
139                         interact->len = 0;
140                         return LDAP_UNAVAILABLE;
141                 }
142
143                 /* len of input */
144                 interact->len = strlen(input); 
145
146                 if( interact->len > 0 && input[interact->len - 1] == '\n' ) {
147                         /* input includes '\n', trim it */
148                         interact->len--;
149                         input[interact->len] = '\0';
150                 }
151         }
152
153
154         if( interact->len > 0 ) {
155                 /* duplicate */
156                 char *p = interact->result;
157                 interact->result = strdup( p );
158
159                 /* zap */
160                 memset( p, '\0', interact->len );
161
162         } else {
163 use_default:
164                 /* must be empty */
165                 interact->result = strdup( (dflt && *dflt) ? dflt : "" );
166                 interact->len = interact->result
167                         ? strlen( interact->result ) : 0;
168         }
169
170         if( defaults && defaults->passwd && interact->id == SASL_CB_PASS ) {
171                 /* zap password after first use */
172                 memset( defaults->passwd, '\0', strlen(defaults->passwd) );
173                 defaults->passwd = NULL;
174         }
175
176         return LDAP_SUCCESS;
177 }
178
179 int lutil_sasl_interact(
180         LDAP *ld,
181         unsigned flags,
182         void *defaults,
183         void *in )
184 {
185         sasl_interact_t *interact = in;
186
187         if( flags != LDAP_SASL_QUIET ) {
188                 fputs( "SASL Interaction\n", stderr );
189         }
190
191         while( interact->id != SASL_CB_LIST_END ) {
192                 int rc = interaction( flags, interact, defaults );
193
194                 if( rc )  return rc;
195                 interact++;
196         }
197         
198         return LDAP_SUCCESS;
199 }
200 #endif