summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c208
1 files changed, 136 insertions, 72 deletions
diff --git a/sshd.c b/sshd.c
index 059f31195..08fb30e3f 100644
--- a/sshd.c
+++ b/sshd.c
@@ -18,7 +18,7 @@ agent connections.
18*/ 18*/
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: sshd.c,v 1.1 1999/10/27 03:42:46 damien Exp $"); 21RCSID("$Id: sshd.c,v 1.2 1999/10/27 13:42:05 damien Exp $");
22 22
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "rsa.h" 24#include "rsa.h"
@@ -47,14 +47,6 @@ int deny_severity = LOG_WARNING;
47char *ticket = NULL; 47char *ticket = NULL;
48#endif /* KRB4 */ 48#endif /* KRB4 */
49 49
50#ifdef HAVE_PAM
51#include <security/pam_appl.h>
52struct pam_handle_t *pamh=NULL;
53char *pampasswd=NULL;
54int retval;
55int origretval;
56#endif /* HAVE_PAM */
57
58/* Local Xauthority file. */ 50/* Local Xauthority file. */
59char *xauthfile = NULL; 51char *xauthfile = NULL;
60 52
@@ -139,69 +131,127 @@ void do_child(const char *command, struct passwd *pw, const char *term,
139#ifdef HAVE_PAM 131#ifdef HAVE_PAM
140static int pamconv(int num_msg, const struct pam_message **msg, 132static int pamconv(int num_msg, const struct pam_message **msg,
141 struct pam_response **resp, void *appdata_ptr); 133 struct pam_response **resp, void *appdata_ptr);
134void do_pam_authentication(const char *username, const char *password,
135 const char *remote_user, const char *remote_host);
136void pam_cleanup_proc(void *context);
142 137
143static struct pam_conv conv = { 138static struct pam_conv conv = {
144 pamconv, 139 pamconv,
145 NULL 140 NULL
146}; 141};
142struct pam_handle_t *pamh = NULL;
143const char *pampasswd = NULL;
147 144
148static int pamconv(int num_msg, const struct pam_message **msg, 145static int pamconv(int num_msg, const struct pam_message **msg,
149 struct pam_response **resp, void *appdata_ptr) 146 struct pam_response **resp, void *appdata_ptr)
150{ 147{
151 int count = 0; 148 int count = 0;
152 int replies = 0;
153 struct pam_response *reply = NULL; 149 struct pam_response *reply = NULL;
154 int size = sizeof(struct pam_response);
155 150
151 /* PAM will free this later */
152 reply = malloc(num_msg * sizeof(*reply));
153 if (reply == NULL)
154 return PAM_CONV_ERR;
155
156 for(count = 0; count < num_msg; count++) 156 for(count = 0; count < num_msg; count++)
157 { 157 {
158 switch (msg[count]->msg_style) 158 switch (msg[count]->msg_style)
159 { 159 {
160 case PAM_PROMPT_ECHO_ON:
161 case PAM_PROMPT_ECHO_OFF: 160 case PAM_PROMPT_ECHO_OFF:
162 if (reply == NULL) 161 if (pampasswd == NULL)
163 reply = xmalloc(size); 162 {
164 else
165 reply = realloc(reply, size);
166
167 if (reply == NULL)
168 return PAM_CONV_ERR;
169
170 size += sizeof(struct pam_response);
171
172 reply[replies].resp_retcode = PAM_SUCCESS;
173
174 reply[replies++].resp = xstrdup(pampasswd);
175 /* PAM frees resp */
176 break;
177
178 case PAM_TEXT_INFO:
179 /* ignore it... */
180 break;
181
182 case PAM_ERROR_MSG:
183 default:
184 /* Must be an error of some sort... */
185 if (reply != NULL)
186 free(reply); 163 free(reply);
164 return PAM_CONV_ERR;
165 }
166 reply[count].resp_retcode = PAM_SUCCESS;
167 reply[count].resp = xstrdup(pampasswd);
168 break;
169
170 case PAM_TEXT_INFO:
171 reply[count].resp_retcode = PAM_SUCCESS;
172 reply[count].resp = xstrdup("");
173 break;
187 174
188 return PAM_CONV_ERR; 175 case PAM_PROMPT_ECHO_ON:
189 } 176 case PAM_ERROR_MSG:
177 default:
178 free(reply);
179 return PAM_CONV_ERR;
180 }
190 } 181 }
191 182
192 if (reply != NULL) 183 *resp = reply;
193 *resp = reply;
194 184
195 return PAM_SUCCESS; 185 return PAM_SUCCESS;
196} 186}
197 187
198void pam_cleanup_proc(void *context) 188void pam_cleanup_proc(void *context)
199{ 189{
200 if (retval == PAM_SUCCESS) 190 int retval;
191
192 if (pamh != NULL)
193 {
201 retval = pam_close_session((pam_handle_t *)pamh, 0); 194 retval = pam_close_session((pam_handle_t *)pamh, 0);
202 195
203 if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS) 196 if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
204 log("Cannot release PAM authentication."); 197 log("Cannot release PAM authentication.");
198 }
199}
200
201void do_pam_authentication(const char *username, const char *password, const char *remote_user, const char *remote_host)
202{
203 int pam_auth_ok = 1;
204
205 pampasswd = password;
206
207 do
208 {
209 if (PAM_SUCCESS != pam_start("ssh", username, &conv, (pam_handle_t**)&pamh))
210 {
211 pam_auth_ok = 0;
212 break;
213 }
214
215 fatal_add_cleanup(&pam_cleanup_proc, NULL);
216
217 if (remote_host && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RHOST, remote_host)))
218 {
219 pam_auth_ok = 0;
220 break;
221 }
222
223 if (remote_user && (PAM_SUCCESS != pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user)))
224 {
225 pam_auth_ok = 0;
226 break;
227 }
228
229 if (PAM_SUCCESS != pam_authenticate((pam_handle_t *)pamh, 0))
230 {
231 pam_auth_ok = 0;
232 break;
233 }
234
235 if (PAM_SUCCESS != pam_acct_mgmt((pam_handle_t *)pamh, 0))
236 {
237 pam_auth_ok = 0;
238 break;
239 }
240
241 if (PAM_SUCCESS != pam_open_session((pam_handle_t *)pamh, 0))
242 {
243 pam_auth_ok = 0;
244 break;
245 }
246 } while (0);
247
248 if (!pam_auth_ok)
249 {
250 packet_start(SSH_SMSG_FAILURE);
251 packet_send();
252 packet_write_wait();
253 packet_disconnect("PAM authentication failed.");
254 }
205} 255}
206#endif /* HAVE_PAM */ 256#endif /* HAVE_PAM */
207 257
@@ -788,13 +838,19 @@ main(int ac, char **av)
788 log("Closing connection to %.100s", inet_ntoa(sin.sin_addr)); 838 log("Closing connection to %.100s", inet_ntoa(sin.sin_addr));
789 839
790#ifdef HAVE_PAM 840#ifdef HAVE_PAM
791 if (retval == PAM_SUCCESS) 841 {
792 retval = pam_close_session((pam_handle_t *)pamh, 0); 842 int retval;
843
844 if (pamh != NULL)
845 {
846 retval = pam_close_session((pam_handle_t *)pamh, 0);
793 847
794 if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS) 848 if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS)
795 log("Cannot release PAM authentication."); 849 log("Cannot release PAM authentication.");
796 850
797 fatal_remove_cleanup(&pam_cleanup_proc, NULL); 851 fatal_remove_cleanup(&pam_cleanup_proc, NULL);
852 }
853 }
798#endif /* HAVE_PAM */ 854#endif /* HAVE_PAM */
799 855
800 packet_close(); 856 packet_close();
@@ -1078,14 +1134,11 @@ do_authentication(char *user, int privileged_port)
1078 int type; 1134 int type;
1079 int authenticated = 0; 1135 int authenticated = 0;
1080 int authentication_failures = 0; 1136 int authentication_failures = 0;
1081 char *password; 1137 char *password = NULL;
1082 struct passwd *pw, pwcopy; 1138 struct passwd *pw, pwcopy;
1083 char *client_user; 1139 char *client_user = NULL;
1084 unsigned int client_host_key_bits; 1140 unsigned int client_host_key_bits;
1085 BIGNUM *client_host_key_e, *client_host_key_n; 1141 BIGNUM *client_host_key_e, *client_host_key_n;
1086#ifdef HAVE_PAM
1087 int pam_auth_ok;
1088#endif /* HAVE_PAM */
1089 1142
1090#ifdef AFS 1143#ifdef AFS
1091 /* If machine has AFS, set process authentication group. */ 1144 /* If machine has AFS, set process authentication group. */
@@ -1097,21 +1150,7 @@ do_authentication(char *user, int privileged_port)
1097 1150
1098 /* Verify that the user is a valid user. */ 1151 /* Verify that the user is a valid user. */
1099 pw = getpwnam(user); 1152 pw = getpwnam(user);
1100#ifdef HAVE_PAM
1101 if ((pw != NULL) && allowed_user(pw))
1102 {
1103 /* Initialise PAM */
1104 retval = pam_start("ssh", pw->pw_name, &conv, (pam_handle_t **)&pamh);
1105 fatal_add_cleanup(&pam_cleanup_proc, NULL);
1106 origretval = retval;
1107 if (retval == PAM_SUCCESS)
1108 pam_auth_ok = 1;
1109 }
1110
1111 if (pam_auth_ok == 0)
1112#else /* HAVE_PAM */
1113 if (!pw || !allowed_user(pw)) 1153 if (!pw || !allowed_user(pw))
1114#endif /* HAVE_PAM */
1115 { 1154 {
1116 /* The user does not exist or access is denied, 1155 /* The user does not exist or access is denied,
1117 but fake indication that authentication is needed. */ 1156 but fake indication that authentication is needed. */
@@ -1306,12 +1345,16 @@ do_authentication(char *user, int privileged_port)
1306 log("Rhosts authentication accepted for %.100s, remote %.100s on %.700s.", 1345 log("Rhosts authentication accepted for %.100s, remote %.100s on %.700s.",
1307 user, client_user, get_canonical_hostname()); 1346 user, client_user, get_canonical_hostname());
1308 authenticated = 1; 1347 authenticated = 1;
1348#ifndef HAVE_PAM
1309 xfree(client_user); 1349 xfree(client_user);
1350#endif /* HAVE_PAM */
1310 break; 1351 break;
1311 } 1352 }
1312 log("Rhosts authentication failed for %.100s, remote %.100s.", 1353 log("Rhosts authentication failed for %.100s, remote %.100s.",
1313 user, client_user); 1354 user, client_user);
1355#ifndef HAVE_PAM
1314 xfree(client_user); 1356 xfree(client_user);
1357#endif /* HAVE_PAM */
1315 break; 1358 break;
1316 1359
1317 case SSH_CMSG_AUTH_RHOSTS_RSA: 1360 case SSH_CMSG_AUTH_RHOSTS_RSA:
@@ -1354,14 +1397,18 @@ do_authentication(char *user, int privileged_port)
1354 { 1397 {
1355 /* Authentication accepted. */ 1398 /* Authentication accepted. */
1356 authenticated = 1; 1399 authenticated = 1;
1400#ifndef HAVE_PAM
1357 xfree(client_user); 1401 xfree(client_user);
1402#endif /* HAVE_PAM */
1358 BN_clear_free(client_host_key_e); 1403 BN_clear_free(client_host_key_e);
1359 BN_clear_free(client_host_key_n); 1404 BN_clear_free(client_host_key_n);
1360 break; 1405 break;
1361 } 1406 }
1362 log("Rhosts authentication failed for %.100s, remote %.100s.", 1407 log("Rhosts authentication failed for %.100s, remote %.100s.",
1363 user, client_user); 1408 user, client_user);
1364 xfree(client_user); 1409#ifndef HAVE_PAM
1410 xfree(client_user);
1411#endif /* HAVE_PAM */
1365 BN_clear_free(client_host_key_e); 1412 BN_clear_free(client_host_key_e);
1366 BN_clear_free(client_host_key_n); 1413 BN_clear_free(client_host_key_n);
1367 break; 1414 break;
@@ -1412,6 +1459,12 @@ do_authentication(char *user, int privileged_port)
1412 packet_integrity_check(plen, 4 + passw_len, type); 1459 packet_integrity_check(plen, 4 + passw_len, type);
1413 } 1460 }
1414 1461
1462#ifdef HAVE_PAM
1463 /* Authentication will be handled later */
1464 /* keep password around until then */
1465 authenticated = 1;
1466 break;
1467#else /* HAVE_PAM */
1415 /* Try authentication with the password. */ 1468 /* Try authentication with the password. */
1416 if (auth_password(pw, password)) 1469 if (auth_password(pw, password))
1417 { 1470 {
@@ -1427,6 +1480,7 @@ do_authentication(char *user, int privileged_port)
1427 memset(password, 0, strlen(password)); 1480 memset(password, 0, strlen(password));
1428 xfree(password); 1481 xfree(password);
1429 break; 1482 break;
1483#endif /* HAVE_PAM */
1430 1484
1431 case SSH_CMSG_AUTH_TIS: 1485 case SSH_CMSG_AUTH_TIS:
1432 /* TIS Authentication is unsupported */ 1486 /* TIS Authentication is unsupported */
@@ -1464,6 +1518,20 @@ do_authentication(char *user, int privileged_port)
1464 get_canonical_hostname()); 1518 get_canonical_hostname());
1465 } 1519 }
1466 1520
1521#ifdef HAVE_PAM
1522 do_pam_authentication(pw->pw_name, password, client_user, get_canonical_hostname());
1523
1524 /* Clean up */
1525 if (client_user != NULL)
1526 xfree(client_user);
1527
1528 if (password != NULL)
1529 {
1530 memset(password, 0, strlen(password));
1531 xfree(password);
1532 }
1533#endif /* HAVE_PAM */
1534
1467 /* The user has been authenticated and accepted. */ 1535 /* The user has been authenticated and accepted. */
1468 packet_start(SSH_SMSG_SUCCESS); 1536 packet_start(SSH_SMSG_SUCCESS);
1469 packet_send(); 1537 packet_send();
@@ -2151,10 +2219,6 @@ void do_child(const char *command, struct passwd *pw, const char *term,
2151 exit(254); 2219 exit(254);
2152 } 2220 }
2153 2221
2154 /* Set login name in the kernel. */
2155 if (setlogin(pw->pw_name) < 0)
2156 error("setlogin failed: %s", strerror(errno));
2157
2158 /* Set uid, gid, and groups. */ 2222 /* Set uid, gid, and groups. */
2159 /* Login(1) does this as well, and it needs uid 0 for the "-h" switch, 2223 /* Login(1) does this as well, and it needs uid 0 for the "-h" switch,
2160 so we let login(1) to this for us. */ 2224 so we let login(1) to this for us. */