Mercurial > dropbear
comparison svr-authpam.c @ 57:3b2a5a1c4347 authpam
svr-authpam code merged and works. needs tidying a log
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 08 Aug 2004 16:57:37 +0000 |
parents | |
children | 3394a7cb30cd |
comparison
equal
deleted
inserted
replaced
56:6f091656c100 | 57:3b2a5a1c4347 |
---|---|
1 /* | |
2 * Dropbear - a SSH2 server | |
3 * | |
4 * Copyright (c) 2002,2003 Matt Johnston | |
5 * All rights reserved. | |
6 * | |
7 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 * of this software and associated documentation files (the "Software"), to deal | |
9 * in the Software without restriction, including without limitation the rights | |
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 * copies of the Software, and to permit persons to whom the Software is | |
12 * furnished to do so, subject to the following conditions: | |
13 * | |
14 * The above copyright notice and this permission notice shall be included in | |
15 * all copies or substantial portions of the Software. | |
16 * | |
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
23 * SOFTWARE. */ | |
24 | |
25 /* Validates a user password */ | |
26 | |
27 #include "includes.h" | |
28 #include "session.h" | |
29 #include "buffer.h" | |
30 #include "dbutil.h" | |
31 #include "auth.h" | |
32 | |
33 #if defined(HAVE_SECURITY_PAM_APPL_H) | |
34 #include <security/pam_appl.h> | |
35 #elif defined (HAVE_PAM_PAM_APPL_H) | |
36 #include <pam/pam_appl.h> | |
37 #endif | |
38 | |
39 #ifdef DROPBEAR_PAM_AUTH | |
40 | |
41 struct UserDataS { | |
42 char* user; | |
43 char* passwd; | |
44 }; | |
45 | |
46 /* PAM conversation function */ | |
47 int | |
48 pamConvFunc(int num_msg, | |
49 const struct pam_message **msg, | |
50 struct pam_response **respp, | |
51 void *appdata_ptr) { | |
52 int rc = PAM_SUCCESS; | |
53 struct pam_response* resp = NULL; | |
54 struct UserDataS* userDatap = (struct UserDataS*) appdata_ptr; | |
55 | |
56 /* tbd only handles one msg */ | |
57 | |
58 switch((*msg)->msg_style) { | |
59 case PAM_PROMPT_ECHO_OFF: | |
60 dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_PROMPT_ECHO_OFF: (*msg)->msg=\"%s\"", (*msg)->msg); | |
61 | |
62 if (strcmp((*msg)->msg, "Password:") == 0) { | |
63 resp = (struct pam_response*) malloc(sizeof(struct pam_response)); | |
64 resp->resp = (char*) strdup(userDatap->passwd); | |
65 /* dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_PROMPT_ECHO_ON: userDatap->passwd=\"%s\"", userDatap->passwd); */ | |
66 resp->resp_retcode = 0; | |
67 (*respp) = resp; | |
68 } | |
69 else { | |
70 dropbear_log(LOG_WARNING, "pamConvFunc(): PAM_PROMPT_ECHO_OFF: unrecognized prompt, (*msg)->msg=\"%s\"", (*msg)->msg); | |
71 rc = PAM_CONV_ERR; | |
72 } | |
73 break; | |
74 case PAM_PROMPT_ECHO_ON: | |
75 dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_PROMPT_ECHO_ON: (*msg)->msg=\"%s\"", (*msg)->msg); | |
76 | |
77 if ((strcmp((*msg)->msg, "login: " ) == 0) || (strcmp((*msg)->msg, "Please enter username: " ) == 0)) { | |
78 resp = (struct pam_response*) malloc(sizeof(struct pam_response)); | |
79 resp->resp = (char*) strdup(userDatap->user); | |
80 dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_PROMPT_ECHO_ON: userDatap->user=\"%s\"", userDatap->user); | |
81 resp->resp_retcode = 0; | |
82 (*respp) = resp; | |
83 } | |
84 else { | |
85 dropbear_log(LOG_WARNING, "pamConvFunc(): PAM_PROMPT_ECHO_ON: unrecognized prompt, (*msg)->msg=\"%s\"", | |
86 (*msg)->msg); | |
87 rc = PAM_CONV_ERR; | |
88 } | |
89 break; | |
90 case PAM_ERROR_MSG: | |
91 dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_ERROR_MSG: (*msg)->msg=\"%s\"", (*msg)->msg); | |
92 /* printf("error msg: '%s'\n", (*msg)->msg); */ | |
93 rc = PAM_CONV_ERR; | |
94 break; | |
95 case PAM_TEXT_INFO: | |
96 dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_TEXT_INFO: (*msg)->msg=\"%s\"", (*msg)->msg); | |
97 /* printf("text info: '%s'\n", (*msg)->msg); */ | |
98 rc = PAM_CONV_ERR; | |
99 break; | |
100 case PAM_RADIO_TYPE: | |
101 dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_RADIO_TYPE: (*msg)->msg=\"%s\"", (*msg)->msg); | |
102 /* printf("radio type: '%s'\n", (*msg)->msg); */ | |
103 rc = PAM_CONV_ERR; | |
104 break; | |
105 case PAM_BINARY_PROMPT: | |
106 dropbear_log(LOG_DEBUG, "pamConvFunc(): PAM_BINARY_PROMPT: (*msg)->msg=\"%s\"", (*msg)->msg); | |
107 /* printf("binary prompt: '%s'\n", (*msg)->msg); */ | |
108 rc = PAM_CONV_ERR; | |
109 break; | |
110 default: | |
111 dropbear_log(LOG_DEBUG, "pamConvFunc(): Unknown PAM message"); | |
112 /* printf("unknown message\n"); */ | |
113 rc = PAM_CONV_ERR; | |
114 break; | |
115 } | |
116 | |
117 return rc; | |
118 } | |
119 | |
120 /* Process a password auth request, sending success or failure messages as | |
121 * appropriate */ | |
122 void svr_auth_pam() { | |
123 // PAM stuff | |
124 int rc = PAM_SUCCESS; | |
125 struct UserDataS userData; | |
126 struct pam_conv pamConv = { | |
127 pamConvFunc, | |
128 &userData /* submitted to pamvConvFunc as appdata_ptr */ | |
129 }; | |
130 pam_handle_t* pamHandlep = NULL; | |
131 unsigned char * password = NULL; | |
132 unsigned int passwordlen; | |
133 | |
134 unsigned char changepw; | |
135 | |
136 /* check if client wants to change password */ | |
137 changepw = buf_getbyte(ses.payload); | |
138 if (changepw) { | |
139 /* not implemented by this server */ | |
140 send_msg_userauth_failure(0, 1); | |
141 return; | |
142 } | |
143 | |
144 password = buf_getstring(ses.payload, &passwordlen); | |
145 | |
146 /* clear the buffer containing the password */ | |
147 buf_incrpos(ses.payload, -passwordlen - 4); | |
148 m_burn(buf_getptr(ses.payload, passwordlen + 4), passwordlen + 4); | |
149 | |
150 /* used to pass data to the PAM conversation function */ | |
151 userData.user = ses.authstate.printableuser; | |
152 TRACE(("user is %s\n", userData.user)); | |
153 userData.passwd = password; | |
154 | |
155 /* Init pam */ | |
156 if ((rc = pam_start("sshd", NULL, &pamConv, &pamHandlep)) != PAM_SUCCESS) { | |
157 dropbear_log(LOG_WARNING, "pam_start() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); | |
158 /* fprintf(stderr, "pam_start() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); */ | |
159 goto clean; | |
160 } | |
161 | |
162 /* | |
163 if ((rc = pam_set_item(pamHandlep, PAM_RHOST, webReqp->ipaddr) != PAM_SUCCESS)) { | |
164 dropbear_log(LOG_WARNING, "pam_set_item() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); | |
165 return; | |
166 } | |
167 */ | |
168 | |
169 /* just to set it to something */ | |
170 if ((rc = pam_set_item(pamHandlep, PAM_TTY, "ssh") != PAM_SUCCESS)) { | |
171 dropbear_log(LOG_WARNING, "pam_set_item() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); | |
172 goto clean; | |
173 } | |
174 | |
175 (void) pam_fail_delay(pamHandlep, 0 /* musec_delay */); | |
176 | |
177 /* (void) pam_set_item(pamHandlep, PAM_FAIL_DELAY, (void*) pamDelayFunc); */ | |
178 | |
179 if ((rc = pam_authenticate(pamHandlep, 0)) != PAM_SUCCESS) { | |
180 dropbear_log(LOG_WARNING, "pam_authenticate() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); | |
181 /* fprintf(stderr, "pam_authenticate() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); */ | |
182 dropbear_log(LOG_WARNING, | |
183 "bad pam password attempt for '%s'", | |
184 ses.authstate.printableuser); | |
185 send_msg_userauth_failure(0, 1); | |
186 goto clean; | |
187 } | |
188 | |
189 if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) { | |
190 dropbear_log(LOG_WARNING, "pam_acct_mgmt() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); | |
191 /* fprintf(stderr, "pam_acct_mgmt() failed, rc=%d, %s\n", rc, pam_strerror(pamHandlep, rc)); */ | |
192 dropbear_log(LOG_WARNING, | |
193 "bad pam password attempt for '%s'", | |
194 ses.authstate.printableuser); | |
195 send_msg_userauth_failure(0, 1); | |
196 goto clean; | |
197 } | |
198 | |
199 /* successful authentication */ | |
200 dropbear_log(LOG_NOTICE, | |
201 "password auth succeeded for '%s'", | |
202 ses.authstate.printableuser); | |
203 send_msg_userauth_success(); | |
204 | |
205 clean: | |
206 if (password != NULL) { | |
207 m_burn(password, passwordlen); | |
208 m_free(password); | |
209 } | |
210 if (pamHandlep != NULL) { | |
211 (void) pam_end(pamHandlep, 0 /* pam_status */); | |
212 } | |
213 } | |
214 | |
215 #endif /* DROPBEAR_PAM_AUTH */ |