View | Details | Raw Unified | Return to bug 1663 | Differences between
and this patch

Collapse All | Expand All

(-)openssh-5.5p1.orig/auth2-pubkey.c (-16 / +181 lines)
Lines 27-32 Link Here
27
27
28
#include <sys/types.h>
28
#include <sys/types.h>
29
#include <sys/stat.h>
29
#include <sys/stat.h>
30
#include <sys/wait.h>
30
31
31
#include <fcntl.h>
32
#include <fcntl.h>
32
#include <pwd.h>
33
#include <pwd.h>
Lines 178-204 Link Here
178
178
179
/* return 1 if user allows given key */
179
/* return 1 if user allows given key */
180
static int
180
static int
181
user_key_allowed2(struct passwd *pw, Key *key, char *file)
181
user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw)
182
{
182
{
183
	char line[SSH_MAX_PUBKEY_BYTES];
183
	char line[SSH_MAX_PUBKEY_BYTES];
184
	const char *reason;
184
	const char *reason;
185
	int found_key = 0;
185
	int found_key = 0;
186
	FILE *f;
187
	u_long linenum = 0;
186
	u_long linenum = 0;
188
	Key *found;
187
	Key *found;
189
	char *fp;
188
	char *fp;
190
189
191
	/* Temporarily use the user's uid. */
192
	temporarily_use_uid(pw);
193
194
	debug("trying public key file %s", file);
195
	f = auth_openkeyfile(file, pw, options.strict_modes);
196
197
	if (!f) {
198
		restore_uid();
199
		return 0;
200
	}
201
202
	found_key = 0;
190
	found_key = 0;
203
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
191
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
204
192
Lines 273-280 Link Here
273
			break;
261
			break;
274
		}
262
		}
275
	}
263
	}
276
	restore_uid();
277
	fclose(f);
278
	key_free(found);
264
	key_free(found);
279
	if (!found_key)
265
	if (!found_key)
280
		debug2("key not found");
266
		debug2("key not found");
Lines 321-333 Link Here
321
	return ret;
307
	return ret;
322
}
308
}
323
309
324
/* check whether given key is in .ssh/authorized_keys* */
310
/* return 1 if user allows given key */
311
static int
312
user_key_allowed2(struct passwd *pw, Key *key, char *file)
313
{
314
	FILE *f;
315
	int found_key = 0;
316
317
	/* Temporarily use the user's uid. */
318
	temporarily_use_uid(pw);
319
320
	debug("trying public key file %s", file);
321
	f = auth_openkeyfile(file, pw, options.strict_modes);
322
323
 	if (f) {
324
 		found_key = user_search_key_in_file (f, file, key, pw);
325
		fclose(f);
326
	}
327
328
	restore_uid();
329
	return found_key;
330
}
331
332
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
333
334
#define WHITESPACE " \t\r\n"
335
336
/* return 1 if user allows given key */
337
static int
338
user_key_via_command_allowed2(struct passwd *pw, Key *key)
339
{
340
	FILE *f;
341
	int found_key = 0;
342
	char *progname = NULL;
343
	char *cp;
344
	struct passwd *runas_pw;
345
	struct stat st;
346
	int childdescriptors[2], i;
347
	pid_t pstat, pid, child;
348
349
	if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/')
350
		return -1;
351
352
	/* get the run as identity from config */
353
	runas_pw = (options.authorized_keys_command_runas == NULL)? pw
354
	    : getpwnam (options.authorized_keys_command_runas);
355
	if (!runas_pw) {
356
		error("%s: getpwnam(\"%s\"): %s", __func__,
357
		    options.authorized_keys_command_runas, strerror(errno));
358
		return 0;
359
	}
360
361
	/* Temporarily use the specified uid. */
362
	if (runas_pw->pw_uid != 0)
363
		temporarily_use_uid(runas_pw);
364
365
	progname = xstrdup(options.authorized_keys_command);
366
367
	debug3("%s: checking program '%s'", __func__, progname);
368
369
	if (stat (progname, &st) < 0) {
370
		error("%s: stat(\"%s\"): %s", __func__,
371
		    progname, strerror(errno));
372
		goto go_away;
373
	}
374
375
	if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
376
		error("bad ownership or modes for AuthorizedKeysCommand \"%s\"",
377
		    progname);
378
		goto go_away;
379
	}
380
381
	if (!S_ISREG(st.st_mode)) {
382
		error("AuthorizedKeysCommand \"%s\" is not a regular file",
383
		    progname);
384
		goto go_away;
385
	}
386
387
	/*
388
	 * Descend the path, checking that each component is a
389
	 * root-owned directory with strict permissions.
390
	 */
391
	do {
392
		if ((cp = strrchr(progname, '/')) == NULL)
393
			break;
394
		else 
395
			*cp = '\0';
396
	
397
		debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname));
398
399
		if (stat((*progname == '\0' ? "/" : progname), &st) != 0) {
400
			error("%s: stat(\"%s\"): %s", __func__,
401
			    progname, strerror(errno));
402
			goto go_away;
403
		}
404
		if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
405
			error("bad ownership or modes for AuthorizedKeysCommand path component \"%s\"",
406
			    progname);
407
			goto go_away;
408
		}
409
		if (!S_ISDIR(st.st_mode)) {
410
			error("AuthorizedKeysCommand path component \"%s\" is not a directory",
411
			    progname);
412
			goto go_away;
413
		}
414
	} while (1);
415
416
	/* open the pipe and read the keys */
417
	if (pipe(childdescriptors)) {
418
		error("failed to pipe(2) for AuthorizedKeysCommand: %s",
419
		    strerror(errno));
420
		goto go_away;
421
	}
422
423
	child = fork();
424
	if (child == -1) {
425
		error("failed to fork(2) for AuthorizedKeysCommand: %s",
426
		    strerror(errno));
427
		goto go_away;
428
	} else if (child == 0) {
429
		/* we're in the child process here -- we should never return from this block. */
430
		/* permanently drop privs in child process */
431
		if (runas_pw->pw_uid != 0) {
432
			restore_uid();
433
			permanently_set_uid(runas_pw);
434
	  	}
435
436
		close(childdescriptors[0]);
437
		/* put the write end of the pipe on stdout (FD 1) */
438
		if (dup2(childdescriptors[1], 1) == -1) {
439
			error("failed to dup2(2) from AuthorizedKeysCommand: %s",
440
			    strerror(errno));
441
			_exit(127);
442
		}
443
444
		debug3("about to execl() AuthorizedKeysCommand: \"%s\" \"%s\"", options.authorized_keys_command, pw->pw_name);
445
		/* see session.c:child_close_fds() */
446
		for (i = 3; i < 64; ++i) {
447
			close(i);
448
		}
449
450
		execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL);
451
452
		/* if we got here, it didn't work */
453
		error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */
454
		_exit(127);
455
	}
456
	
457
	close(childdescriptors[1]);
458
	f = fdopen(childdescriptors[0], "r");
459
	if (!f) {
460
		error("%s: could not buffer FDs from AuthorizedKeysCommand (\"%s\", \"r\"): %s", __func__,
461
		    options.authorized_keys_command, strerror (errno));
462
		goto go_away;
463
	}
464
465
	found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw);
466
	fclose (f);
467
	do {
468
		pid = waitpid(child, &pstat, 0);
469
	} while (pid == -1 && errno == EINTR);
470
471
	/* what about the return value from the child process? */
472
go_away:
473
	if (progname)
474
		xfree (progname);
475
476
	if (runas_pw->pw_uid != 0)
477
		restore_uid();
478
	return found_key;
479
}
480
#endif
481
482
/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */
325
int
483
int
326
user_key_allowed(struct passwd *pw, Key *key)
484
user_key_allowed(struct passwd *pw, Key *key)
327
{
485
{
328
	int success;
486
	int success;
329
	char *file;
487
	char *file;
330
488
489
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
490
	success = user_key_via_command_allowed2(pw, key);
491
	if (success > 0)
492
		return success;
493
#endif
494
331
	if (auth_key_is_revoked(key))
495
	if (auth_key_is_revoked(key))
332
		return 0;
496
		return 0;
333
	if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
497
	if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
(-)openssh-5.5p1.orig/configure.ac (+13 lines)
Lines 1346-1351 Link Here
1346
	esac ]
1346
	esac ]
1347
)
1347
)
1348
1348
1349
# Check whether user wants AuthorizedKeysCommand support
1350
AKC_MSG="no"
1351
AC_ARG_WITH(authorized-keys-command,
1352
	[  --with-authorized-keys-command      Enable AuthorizedKeysCommand support],
1353
	[
1354
		if test "x$withval" != "xno" ; then
1355
			AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support])
1356
			AKC_MSG="yes"
1357
		fi
1358
	]
1359
)
1360
1349
dnl    Checks for library functions. Please keep in alphabetical order
1361
dnl    Checks for library functions. Please keep in alphabetical order
1350
AC_CHECK_FUNCS( \
1362
AC_CHECK_FUNCS( \
1351
	arc4random \
1363
	arc4random \
Lines 4181-4186 Link Here
4181
echo "                 Smartcard support: $SCARD_MSG"
4193
echo "                 Smartcard support: $SCARD_MSG"
4182
echo "                     S/KEY support: $SKEY_MSG"
4194
echo "                     S/KEY support: $SKEY_MSG"
4183
echo "              TCP Wrappers support: $TCPW_MSG"
4195
echo "              TCP Wrappers support: $TCPW_MSG"
4196
echo "     AuthorizedKeysCommand support: $AKC_MSG"
4184
echo "              MD5 password support: $MD5_MSG"
4197
echo "              MD5 password support: $MD5_MSG"
4185
echo "                   libedit support: $LIBEDIT_MSG"
4198
echo "                   libedit support: $LIBEDIT_MSG"
4186
echo "  Solaris process contract support: $SPC_MSG"
4199
echo "  Solaris process contract support: $SPC_MSG"
(-)openssh-5.5p1.orig/servconf.c (+28 lines)
Lines 128-133 Link Here
128
	options->num_permitted_opens = -1;
128
	options->num_permitted_opens = -1;
129
	options->adm_forced_command = NULL;
129
	options->adm_forced_command = NULL;
130
	options->chroot_directory = NULL;
130
	options->chroot_directory = NULL;
131
	options->authorized_keys_command = NULL;
132
	options->authorized_keys_command_runas = NULL;
131
	options->zero_knowledge_password_authentication = -1;
133
	options->zero_knowledge_password_authentication = -1;
132
	options->revoked_keys_file = NULL;
134
	options->revoked_keys_file = NULL;
133
	options->trusted_user_ca_keys = NULL;
135
	options->trusted_user_ca_keys = NULL;
Lines 311-316 Link Here
311
	sUsePrivilegeSeparation, sAllowAgentForwarding,
313
	sUsePrivilegeSeparation, sAllowAgentForwarding,
312
	sZeroKnowledgePasswordAuthentication, sHostCertificate,
314
	sZeroKnowledgePasswordAuthentication, sHostCertificate,
313
	sRevokedKeys, sTrustedUserCAKeys,
315
	sRevokedKeys, sTrustedUserCAKeys,
316
	sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs,
314
	sDeprecated, sUnsupported
317
	sDeprecated, sUnsupported
315
} ServerOpCodes;
318
} ServerOpCodes;
316
319
Lines 432-437 Link Here
432
	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
435
	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
433
	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
436
	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
434
	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
437
	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
438
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
439
	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
440
	{ "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
441
#else
442
	{ "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
443
	{ "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
444
#endif
435
	{ NULL, sBadOption, 0 }
445
	{ NULL, sBadOption, 0 }
436
};
446
};
437
447
Lines 1345-1350 Link Here
1345
		charptr = &options->revoked_keys_file;
1355
		charptr = &options->revoked_keys_file;
1346
		goto parse_filename;
1356
		goto parse_filename;
1347
1357
1358
	case sAuthorizedKeysCommand:
1359
		len = strspn(cp, WHITESPACE);
1360
		if (*activep && options->authorized_keys_command == NULL)
1361
			options->authorized_keys_command = xstrdup(cp + len);
1362
		return 0;
1363
1364
	case sAuthorizedKeysCommandRunAs:
1365
		charptr = &options->authorized_keys_command_runas;
1366
1367
		arg = strdelim(&cp);
1368
		if (*activep && *charptr == NULL)
1369
			*charptr = xstrdup(arg);
1370
		break;
1371
1348
	case sDeprecated:
1372
	case sDeprecated:
1349
		logit("%s line %d: Deprecated option %s",
1373
		logit("%s line %d: Deprecated option %s",
1350
		    filename, linenum, arg);
1374
		    filename, linenum, arg);
Lines 1438-1443 Link Here
1438
	M_CP_INTOPT(gss_authentication);
1462
	M_CP_INTOPT(gss_authentication);
1439
	M_CP_INTOPT(rsa_authentication);
1463
	M_CP_INTOPT(rsa_authentication);
1440
	M_CP_INTOPT(pubkey_authentication);
1464
	M_CP_INTOPT(pubkey_authentication);
1465
	M_CP_STROPT(authorized_keys_command);
1466
	M_CP_STROPT(authorized_keys_command_runas);
1441
	M_CP_INTOPT(kerberos_authentication);
1467
	M_CP_INTOPT(kerberos_authentication);
1442
	M_CP_INTOPT(hostbased_authentication);
1468
	M_CP_INTOPT(hostbased_authentication);
1443
	M_CP_INTOPT(kbd_interactive_authentication);
1469
	M_CP_INTOPT(kbd_interactive_authentication);
Lines 1682-1687 Link Here
1682
	dump_cfg_string(sChrootDirectory, o->chroot_directory);
1708
	dump_cfg_string(sChrootDirectory, o->chroot_directory);
1683
	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
1709
	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
1684
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1710
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1711
	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
1712
	dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas);
1685
1713
1686
	/* string arguments requiring a lookup */
1714
	/* string arguments requiring a lookup */
1687
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1715
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
(-)openssh-5.5p1.orig/servconf.h (+2 lines)
Lines 156-161 Link Here
156
	char   *chroot_directory;
156
	char   *chroot_directory;
157
	char   *revoked_keys_file;
157
	char   *revoked_keys_file;
158
	char   *trusted_user_ca_keys;
158
	char   *trusted_user_ca_keys;
159
	char   *authorized_keys_command;
160
	char   *authorized_keys_command_runas;
159
}       ServerOptions;
161
}       ServerOptions;
160
162
161
void	 initialize_server_options(ServerOptions *);
163
void	 initialize_server_options(ServerOptions *);
(-)openssh-5.5p1.orig/sshd_config (+2 lines)
Lines 44-49 Link Here
44
#RSAAuthentication yes
44
#RSAAuthentication yes
45
#PubkeyAuthentication yes
45
#PubkeyAuthentication yes
46
#AuthorizedKeysFile	.ssh/authorized_keys
46
#AuthorizedKeysFile	.ssh/authorized_keys
47
#AuthorizedKeysCommand none
48
#AuthorizedKeysCommandRunAs nobody
47
49
48
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
50
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
49
#RhostsRSAAuthentication no
51
#RhostsRSAAuthentication no
(-)openssh-5.5p1.orig/sshd_config.0 (-1 / +19 lines)
Lines 352-358 Link Here
352
             KbdInteractiveAuthentication, KerberosAuthentication,
352
             KbdInteractiveAuthentication, KerberosAuthentication,
353
             MaxAuthTries, MaxSessions, PasswordAuthentication,
353
             MaxAuthTries, MaxSessions, PasswordAuthentication,
354
             PermitEmptyPasswords, PermitOpen, PermitRootLogin,
354
             PermitEmptyPasswords, PermitOpen, PermitRootLogin,
355
             PubkeyAuthentication, RhostsRSAAuthentication, RSAAuthentication,
355
             PubkeyAuthentication, AuthorizedKeysCommand, AuthorizedKeysCommandRunAs,
356
             RhostsRSAAuthentication, RSAAuthentication,
356
             X11DisplayOffset, X11Forwarding and X11UseLocalHost.
357
             X11DisplayOffset, X11Forwarding and X11UseLocalHost.
357
358
358
     MaxAuthTries
359
     MaxAuthTries
Lines 467-472 Link Here
467
             this file is not readable, then public key authentication will be
468
             this file is not readable, then public key authentication will be
468
             refused for all users.
469
             refused for all users.
469
470
471
     AuthorizedKeysCommand
472
473
             Specifies a program to be used for lookup of the user's
474
	      public keys.  The program will be invoked with its first
475
	      argument the name of the user being authorized, and should produce 
476
	      on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
477
	      in sshd(8)).  By default (or when set to the empty string) there is no
478
	      AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
479
	      authorize the user, authorization falls through to the
480
	      AuthorizedKeysFile.  Note that this option has an effect
481
	      only with PubkeyAuthentication turned on.
482
483
     AuthorizedKeysCommandRunAs
484
             Specifies the user under whose account the AuthorizedKeysCommand is run.
485
             Empty string (the default value) means the user being authorized
486
             is used.
487
470
     RhostsRSAAuthentication
488
     RhostsRSAAuthentication
471
             Specifies whether rhosts or /etc/hosts.equiv authentication to-
489
             Specifies whether rhosts or /etc/hosts.equiv authentication to-
472
             gether with successful RSA host authentication is allowed.  The
490
             gether with successful RSA host authentication is allowed.  The
(-)openssh-5.5p1.orig/sshd_config.5 (+17 lines)
Lines 618-623 Link Here
618
.Cm KerberosAuthentication ,
618
.Cm KerberosAuthentication ,
619
.Cm MaxAuthTries ,
619
.Cm MaxAuthTries ,
620
.Cm MaxSessions ,
620
.Cm MaxSessions ,
621
.Cm PubkeyAuthentication ,
622
.Cm AuthorizedKeysCommand ,
623
.Cm AuthorizedKeysCommandRunAs ,
621
.Cm PasswordAuthentication ,
624
.Cm PasswordAuthentication ,
622
.Cm PermitEmptyPasswords ,
625
.Cm PermitEmptyPasswords ,
623
.Cm PermitOpen ,
626
.Cm PermitOpen ,
Lines 819-824 Link Here
819
Keys listed in this file will be refused for public key authentication.
822
Keys listed in this file will be refused for public key authentication.
820
Note that if this file is not readable, then public key authentication will
823
Note that if this file is not readable, then public key authentication will
821
be refused for all users.
824
be refused for all users.
825
.It Cm AuthorizedKeysCommand
826
Specifies a program to be used for lookup of the user's
827
public keys.  The program will be invoked with its first
828
argument the name of the user being authorized, and should produce 
829
on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
830
in sshd(8)).  By default (or when set to the empty string) there is no
831
AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
832
authorize the user, authorization falls through to the
833
AuthorizedKeysFile.  Note that this option has an effect
834
only with PubkeyAuthentication turned on.
835
.It Cm AuthorizedKeysCommandRunAs
836
Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
837
string (the default value) means the user being authorized is used.
838
.Dq 
822
.It Cm RhostsRSAAuthentication
839
.It Cm RhostsRSAAuthentication
823
Specifies whether rhosts or /etc/hosts.equiv authentication together
840
Specifies whether rhosts or /etc/hosts.equiv authentication together
824
with successful RSA host authentication is allowed.
841
with successful RSA host authentication is allowed.

Return to bug 1663