comparison svr-authpam.c @ 131:9c372a039532 private-rez

strdup() variables correctly for the PAM conversation function
author Matt Johnston <matt@ucc.asn.au>
date Tue, 21 Sep 2004 11:42:03 +0000
parents 33d976eeb859
children 364a75cfebab
comparison
equal deleted inserted replaced
130:154c8d5a6d1e 131:9c372a039532
82 TRACE(("PAM_PROMPT_ECHO_OFF: unrecognized prompt")); 82 TRACE(("PAM_PROMPT_ECHO_OFF: unrecognized prompt"));
83 rc = PAM_CONV_ERR; 83 rc = PAM_CONV_ERR;
84 break; 84 break;
85 } 85 }
86 86
87 /* This looks leaky, but the PAM module-writer docs 87 /* You have to read the PAM module-writers' docs (do we look like
88 * assure us that the caller will free it... */ 88 * module writers? no.) to find out that the module will
89 * free the pam_response and its resp element - ie we _must_ malloc
90 * it here */
89 resp = (struct pam_response*) m_malloc(sizeof(struct pam_response)); 91 resp = (struct pam_response*) m_malloc(sizeof(struct pam_response));
90 memset(resp, 0, sizeof(struct pam_response)); 92 memset(resp, 0, sizeof(struct pam_response));
91 93
92 /* Safe to just use the direct pointer (no strdup) since 94 resp->resp = m_strdup(userDatap->passwd);
93 * it shouldn't be getting munged at all */ 95 m_burn(userDatap->passwd, strlen(userDatap->passwd));
94 resp->resp = userDatap->passwd;
95 (*respp) = resp; 96 (*respp) = resp;
96 break; 97 break;
97 98
98 99
99 case PAM_PROMPT_ECHO_ON: 100 case PAM_PROMPT_ECHO_ON:
104 TRACE(("PAM_PROMPT_ECHO_ON: unrecognized prompt")); 105 TRACE(("PAM_PROMPT_ECHO_ON: unrecognized prompt"));
105 rc = PAM_CONV_ERR; 106 rc = PAM_CONV_ERR;
106 break; 107 break;
107 } 108 }
108 109
109 /* This looks leaky, but the PAM module-writer docs 110 /* You have to read the PAM module-writers' docs (do we look like
110 * assure us that the caller will free it... */ 111 * module writers? no.) to find out that the module will
112 * free the pam_response and its resp element - ie we _must_ malloc
113 * it here */
111 resp = (struct pam_response*) m_malloc(sizeof(struct pam_response)); 114 resp = (struct pam_response*) m_malloc(sizeof(struct pam_response));
112 memset(resp, 0, sizeof(struct pam_response)); 115 memset(resp, 0, sizeof(struct pam_response));
113 116
114 /* Safe to just use the direct pointer (no strdup) since 117 /* Safe to just use the direct pointer (no strdup) since
115 * it shouldn't be getting munged at all */ 118 * it shouldn't be getting munged at all */
116 resp->resp = userDatap->user; 119 resp->resp = m_strdup(userDatap->user);
117 TRACE(("userDatap->user='%s'", userDatap->user)); 120 TRACE(("userDatap->user='%s'", userDatap->user));
118 (*respp) = resp; 121 (*respp) = resp;
119 break; 122 break;
120 123
121 default: 124 default:
137 * Keyboard interactive would be a lot nicer, but since PAM is synchronous, it 140 * Keyboard interactive would be a lot nicer, but since PAM is synchronous, it
138 * gets very messy trying to send the interactive challenges, and read the 141 * gets very messy trying to send the interactive challenges, and read the
139 * interactive responses, over the network. */ 142 * interactive responses, over the network. */
140 void svr_auth_pam() { 143 void svr_auth_pam() {
141 144
142 struct UserDataS userData; 145 struct UserDataS userData = {NULL, NULL};
143 struct pam_conv pamConv = { 146 struct pam_conv pamConv = {
144 pamConvFunc, 147 pamConvFunc,
145 &userData /* submitted to pamvConvFunc as appdata_ptr */ 148 &userData /* submitted to pamvConvFunc as appdata_ptr */
146 }; 149 };
147 150
161 goto cleanup; 164 goto cleanup;
162 } 165 }
163 166
164 password = buf_getstring(ses.payload, &passwordlen); 167 password = buf_getstring(ses.payload, &passwordlen);
165 168
166 /* used to pass data to the PAM conversation function */ 169 /* used to pass data to the PAM conversation function - don't bother with
170 * strdup() etc since these are touched only by our own conversation
171 * function (above) which takes care of it */
167 userData.user = ses.authstate.printableuser; 172 userData.user = ses.authstate.printableuser;
168 userData.passwd = password; 173 userData.passwd = password;
169 174
170 /* Init pam */ 175 /* Init pam */
171 if ((rc = pam_start("sshd", NULL, &pamConv, &pamHandlep)) != PAM_SUCCESS) { 176 if ((rc = pam_start("sshd", NULL, &pamConv, &pamHandlep)) != PAM_SUCCESS) {
187 192
188 if ((rc = pam_authenticate(pamHandlep, 0)) != PAM_SUCCESS) { 193 if ((rc = pam_authenticate(pamHandlep, 0)) != PAM_SUCCESS) {
189 dropbear_log(LOG_WARNING, "pam_authenticate() failed, rc=%d, %s\n", 194 dropbear_log(LOG_WARNING, "pam_authenticate() failed, rc=%d, %s\n",
190 rc, pam_strerror(pamHandlep, rc)); 195 rc, pam_strerror(pamHandlep, rc));
191 dropbear_log(LOG_WARNING, 196 dropbear_log(LOG_WARNING,
192 "bad pam password attempt for '%s'", 197 "bad PAM password attempt for '%s'",
193 ses.authstate.printableuser); 198 ses.authstate.printableuser);
194 send_msg_userauth_failure(0, 1); 199 send_msg_userauth_failure(0, 1);
195 goto cleanup; 200 goto cleanup;
196 } 201 }
197 202
198 if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) { 203 if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) {
199 dropbear_log(LOG_WARNING, "pam_acct_mgmt() failed, rc=%d, %s\n", 204 dropbear_log(LOG_WARNING, "pam_acct_mgmt() failed, rc=%d, %s\n",
200 rc, pam_strerror(pamHandlep, rc)); 205 rc, pam_strerror(pamHandlep, rc));
201 dropbear_log(LOG_WARNING, 206 dropbear_log(LOG_WARNING,
202 "bad pam password attempt for '%s'", 207 "bad PAM password attempt for '%s'",
203 ses.authstate.printableuser); 208 ses.authstate.printableuser);
204 send_msg_userauth_failure(0, 1); 209 send_msg_userauth_failure(0, 1);
205 goto cleanup; 210 goto cleanup;
206 } 211 }
207 212
208 /* successful authentication */ 213 /* successful authentication */
209 dropbear_log(LOG_NOTICE, "pam password auth succeeded for '%s'", 214 dropbear_log(LOG_NOTICE, "PAM password auth succeeded for '%s'",
210 ses.authstate.printableuser); 215 ses.authstate.printableuser);
211 send_msg_userauth_success(); 216 send_msg_userauth_success();
212 217
213 cleanup: 218 cleanup:
214 if (password != NULL) { 219 if (password != NULL) {
215 m_burn(password, passwordlen); 220 m_burn(password, passwordlen);
216 m_free(password); 221 m_free(password);
217 } 222 }
218 if (pamHandlep != NULL) { 223 if (pamHandlep != NULL) {
224 TRACE(("pam_end"));
219 (void) pam_end(pamHandlep, 0 /* pam_status */); 225 (void) pam_end(pamHandlep, 0 /* pam_status */);
220 } 226 }
221 } 227 }
222 228
223 #endif /* ENABLE_SVR_PAM_AUTH */ 229 #endif /* ENABLE_SVR_PAM_AUTH */