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

Collapse All | Expand All

(-)openssh-5.8p2.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 256-282 match_principals_file(char *file, struct Link Here
256
257
257
/* return 1 if user allows given key */
258
/* return 1 if user allows given key */
258
static int
259
static int
259
user_key_allowed2(struct passwd *pw, Key *key, char *file)
260
user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw)
260
{
261
{
261
	char line[SSH_MAX_PUBKEY_BYTES];
262
	char line[SSH_MAX_PUBKEY_BYTES];
262
	const char *reason;
263
	const char *reason;
263
	int found_key = 0;
264
	int found_key = 0;
264
	FILE *f;
265
	u_long linenum = 0;
265
	u_long linenum = 0;
266
	Key *found;
266
	Key *found;
267
	char *fp;
267
	char *fp;
268
268
269
	/* Temporarily use the user's uid. */
270
	temporarily_use_uid(pw);
271
272
	debug("trying public key file %s", file);
273
	f = auth_openkeyfile(file, pw, options.strict_modes);
274
275
	if (!f) {
276
		restore_uid();
277
		return 0;
278
	}
279
280
	found_key = 0;
269
	found_key = 0;
281
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
270
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
282
271
Lines 369-376 user_key_allowed2(struct passwd *pw, Key Link Here
369
			break;
358
			break;
370
		}
359
		}
371
	}
360
	}
372
	restore_uid();
373
	fclose(f);
374
	key_free(found);
361
	key_free(found);
375
	if (!found_key)
362
	if (!found_key)
376
		debug2("key not found");
363
		debug2("key not found");
Lines 432-444 user_cert_trusted_ca(struct passwd *pw, Link Here
432
	return ret;
419
	return ret;
433
}
420
}
434
421
435
/* check whether given key is in .ssh/authorized_keys* */
422
/* return 1 if user allows given key */
423
static int
424
user_key_allowed2(struct passwd *pw, Key *key, char *file)
425
{
426
	FILE *f;
427
	int found_key = 0;
428
429
	/* Temporarily use the user's uid. */
430
	temporarily_use_uid(pw);
431
432
	debug("trying public key file %s", file);
433
	f = auth_openkeyfile(file, pw, options.strict_modes);
434
435
 	if (f) {
436
 		found_key = user_search_key_in_file (f, file, key, pw);
437
		fclose(f);
438
	}
439
440
	restore_uid();
441
	return found_key;
442
}
443
444
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
445
446
#define WHITESPACE " \t\r\n"
447
448
/* return 1 if user allows given key */
449
static int
450
user_key_via_command_allowed2(struct passwd *pw, Key *key)
451
{
452
	FILE *f;
453
	int found_key = 0;
454
	char *progname = NULL;
455
	char *cp;
456
	struct passwd *runas_pw;
457
	struct stat st;
458
	int childdescriptors[2], i;
459
	pid_t pstat, pid, child;
460
461
	if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/')
462
		return -1;
463
464
	/* get the run as identity from config */
465
	runas_pw = (options.authorized_keys_command_runas == NULL)? pw
466
	    : getpwnam (options.authorized_keys_command_runas);
467
	if (!runas_pw) {
468
		error("%s: getpwnam(\"%s\"): %s", __func__,
469
		    options.authorized_keys_command_runas, strerror(errno));
470
		return 0;
471
	}
472
473
	/* Temporarily use the specified uid. */
474
	if (runas_pw->pw_uid != 0)
475
		temporarily_use_uid(runas_pw);
476
477
	progname = xstrdup(options.authorized_keys_command);
478
479
	debug3("%s: checking program '%s'", __func__, progname);
480
481
	if (stat (progname, &st) < 0) {
482
		error("%s: stat(\"%s\"): %s", __func__,
483
		    progname, strerror(errno));
484
		goto go_away;
485
	}
486
487
	if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
488
		error("bad ownership or modes for AuthorizedKeysCommand \"%s\"",
489
		    progname);
490
		goto go_away;
491
	}
492
493
	if (!S_ISREG(st.st_mode)) {
494
		error("AuthorizedKeysCommand \"%s\" is not a regular file",
495
		    progname);
496
		goto go_away;
497
	}
498
499
	/*
500
	 * Descend the path, checking that each component is a
501
	 * root-owned directory with strict permissions.
502
	 */
503
	do {
504
		if ((cp = strrchr(progname, '/')) == NULL)
505
			break;
506
		else 
507
			*cp = '\0';
508
	
509
		debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname));
510
511
		if (stat((*progname == '\0' ? "/" : progname), &st) != 0) {
512
			error("%s: stat(\"%s\"): %s", __func__,
513
			    progname, strerror(errno));
514
			goto go_away;
515
		}
516
		if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
517
			error("bad ownership or modes for AuthorizedKeysCommand path component \"%s\"",
518
			    progname);
519
			goto go_away;
520
		}
521
		if (!S_ISDIR(st.st_mode)) {
522
			error("AuthorizedKeysCommand path component \"%s\" is not a directory",
523
			    progname);
524
			goto go_away;
525
		}
526
	} while (1);
527
528
	/* open the pipe and read the keys */
529
	if (pipe(childdescriptors)) {
530
		error("failed to pipe(2) for AuthorizedKeysCommand: %s",
531
		    strerror(errno));
532
		goto go_away;
533
	}
534
535
	child = fork();
536
	if (child == -1) {
537
		error("failed to fork(2) for AuthorizedKeysCommand: %s",
538
		    strerror(errno));
539
		goto go_away;
540
	} else if (child == 0) {
541
		/* we're in the child process here -- we should never return from this block. */
542
		/* permanently drop privs in child process */
543
		if (runas_pw->pw_uid != 0) {
544
			restore_uid();
545
			permanently_set_uid(runas_pw);
546
	  	}
547
548
		close(childdescriptors[0]);
549
		/* put the write end of the pipe on stdout (FD 1) */
550
		if (dup2(childdescriptors[1], 1) == -1) {
551
			error("failed to dup2(2) from AuthorizedKeysCommand: %s",
552
			    strerror(errno));
553
			_exit(127);
554
		}
555
556
		debug3("about to execl() AuthorizedKeysCommand: \"%s\" \"%s\"", options.authorized_keys_command, pw->pw_name);
557
		/* see session.c:child_close_fds() */
558
		for (i = 3; i < 64; ++i) {
559
			close(i);
560
		}
561
562
		execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL);
563
564
		/* if we got here, it didn't work */
565
		error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */
566
		_exit(127);
567
	}
568
	
569
	close(childdescriptors[1]);
570
	f = fdopen(childdescriptors[0], "r");
571
	if (!f) {
572
		error("%s: could not buffer FDs from AuthorizedKeysCommand (\"%s\", \"r\"): %s", __func__,
573
		    options.authorized_keys_command, strerror (errno));
574
		goto go_away;
575
	}
576
577
	found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw);
578
	fclose (f);
579
	do {
580
		pid = waitpid(child, &pstat, 0);
581
	} while (pid == -1 && errno == EINTR);
582
583
	/* what about the return value from the child process? */
584
go_away:
585
	if (progname)
586
		xfree (progname);
587
588
	if (runas_pw->pw_uid != 0)
589
		restore_uid();
590
	return found_key;
591
}
592
#endif
593
594
/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */
436
int
595
int
437
user_key_allowed(struct passwd *pw, Key *key)
596
user_key_allowed(struct passwd *pw, Key *key)
438
{
597
{
439
	int success;
598
	int success;
440
	char *file;
599
	char *file;
441
600
601
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
602
	success = user_key_via_command_allowed2(pw, key);
603
	if (success > 0)
604
		return success;
605
#endif
606
442
	if (auth_key_is_revoked(key))
607
	if (auth_key_is_revoked(key))
443
		return 0;
608
		return 0;
444
	if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
609
	if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
(-)openssh-5.8p2.orig/configure.ac (+13 lines)
Lines 1422-1427 AC_ARG_WITH(audit, Link Here
1422
	esac ]
1422
	esac ]
1423
)
1423
)
1424
1424
1425
# Check whether user wants AuthorizedKeysCommand support
1426
AKC_MSG="no"
1427
AC_ARG_WITH(authorized-keys-command,
1428
	[  --with-authorized-keys-command      Enable AuthorizedKeysCommand support],
1429
	[
1430
		if test "x$withval" != "xno" ; then
1431
			AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support])
1432
			AKC_MSG="yes"
1433
		fi
1434
	]
1435
)
1436
1425
dnl    Checks for library functions. Please keep in alphabetical order
1437
dnl    Checks for library functions. Please keep in alphabetical order
1426
AC_CHECK_FUNCS( \
1438
AC_CHECK_FUNCS( \
1427
	arc4random \
1439
	arc4random \
Lines 4319-4324 echo " SELinux support Link Here
4319
echo "                 Smartcard support: $SCARD_MSG"
4331
echo "                 Smartcard support: $SCARD_MSG"
4320
echo "                     S/KEY support: $SKEY_MSG"
4332
echo "                     S/KEY support: $SKEY_MSG"
4321
echo "              TCP Wrappers support: $TCPW_MSG"
4333
echo "              TCP Wrappers support: $TCPW_MSG"
4334
echo "     AuthorizedKeysCommand support: $AKC_MSG"
4322
echo "              MD5 password support: $MD5_MSG"
4335
echo "              MD5 password support: $MD5_MSG"
4323
echo "                   libedit support: $LIBEDIT_MSG"
4336
echo "                   libedit support: $LIBEDIT_MSG"
4324
echo "  Solaris process contract support: $SPC_MSG"
4337
echo "  Solaris process contract support: $SPC_MSG"
(-)openssh-5.8p2.orig/servconf.c (+27 lines)
Lines 133-138 initialize_server_options(ServerOptions Link Here
133
	options->num_permitted_opens = -1;
133
	options->num_permitted_opens = -1;
134
	options->adm_forced_command = NULL;
134
	options->adm_forced_command = NULL;
135
	options->chroot_directory = NULL;
135
	options->chroot_directory = NULL;
136
	options->authorized_keys_command = NULL;
137
	options->authorized_keys_command_runas = NULL;
136
	options->zero_knowledge_password_authentication = -1;
138
	options->zero_knowledge_password_authentication = -1;
137
	options->revoked_keys_file = NULL;
139
	options->revoked_keys_file = NULL;
138
	options->trusted_user_ca_keys = NULL;
140
	options->trusted_user_ca_keys = NULL;
Lines 452-457 static struct { Link Here
452
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
454
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
453
	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
455
	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
454
	{ "ipqos", sIPQoS, SSHCFG_ALL },
456
	{ "ipqos", sIPQoS, SSHCFG_ALL },
457
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
458
	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
459
	{ "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
460
#else
461
	{ "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
462
	{ "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
463
#endif
455
	{ NULL, sBadOption, 0 }
464
	{ NULL, sBadOption, 0 }
456
};
465
};
457
466
Lines 1398-1403 process_server_config_line(ServerOptions Link Here
1398
		}
1407
		}
1399
		break;
1408
		break;
1400
1409
1410
	case sAuthorizedKeysCommand:
1411
		len = strspn(cp, WHITESPACE);
1412
		if (*activep && options->authorized_keys_command == NULL)
1413
			options->authorized_keys_command = xstrdup(cp + len);
1414
		return 0;
1415
1416
	case sAuthorizedKeysCommandRunAs:
1417
		charptr = &options->authorized_keys_command_runas;
1418
1419
		arg = strdelim(&cp);
1420
		if (*activep && *charptr == NULL)
1421
			*charptr = xstrdup(arg);
1422
		break;
1423
1401
	case sDeprecated:
1424
	case sDeprecated:
1402
		logit("%s line %d: Deprecated option %s",
1425
		logit("%s line %d: Deprecated option %s",
1403
		    filename, linenum, arg);
1426
		    filename, linenum, arg);
Lines 1491-1496 copy_set_server_options(ServerOptions *d Link Here
1491
	M_CP_INTOPT(gss_authentication);
1514
	M_CP_INTOPT(gss_authentication);
1492
	M_CP_INTOPT(rsa_authentication);
1515
	M_CP_INTOPT(rsa_authentication);
1493
	M_CP_INTOPT(pubkey_authentication);
1516
	M_CP_INTOPT(pubkey_authentication);
1517
	M_CP_STROPT(authorized_keys_command);
1518
	M_CP_STROPT(authorized_keys_command_runas);
1494
	M_CP_INTOPT(kerberos_authentication);
1519
	M_CP_INTOPT(kerberos_authentication);
1495
	M_CP_INTOPT(hostbased_authentication);
1520
	M_CP_INTOPT(hostbased_authentication);
1496
	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1521
	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
Lines 1744-1749 dump_config(ServerOptions *o) Link Here
1744
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1769
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1745
	dump_cfg_string(sAuthorizedPrincipalsFile,
1770
	dump_cfg_string(sAuthorizedPrincipalsFile,
1746
	    o->authorized_principals_file);
1771
	    o->authorized_principals_file);
1772
	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
1773
	dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas);
1747
1774
1748
	/* string arguments requiring a lookup */
1775
	/* string arguments requiring a lookup */
1749
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1776
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
(-)openssh-5.8p2.orig/servconf.h (+2 lines)
Lines 160-165 typedef struct { Link Here
160
	char   *revoked_keys_file;
160
	char   *revoked_keys_file;
161
	char   *trusted_user_ca_keys;
161
	char   *trusted_user_ca_keys;
162
	char   *authorized_principals_file;
162
	char   *authorized_principals_file;
163
	char   *authorized_keys_command;
164
	char   *authorized_keys_command_runas;
163
}       ServerOptions;
165
}       ServerOptions;
164
166
165
void	 initialize_server_options(ServerOptions *);
167
void	 initialize_server_options(ServerOptions *);
(-)openssh-5.8p2.orig/sshd_config (+2 lines)
Lines 45-50 Link Here
45
#RSAAuthentication yes
45
#RSAAuthentication yes
46
#PubkeyAuthentication yes
46
#PubkeyAuthentication yes
47
#AuthorizedKeysFile	.ssh/authorized_keys
47
#AuthorizedKeysFile	.ssh/authorized_keys
48
#AuthorizedKeysCommand none
49
#AuthorizedKeysCommandRunAs nobody
48
50
49
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
51
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
50
#RhostsRSAAuthentication no
52
#RhostsRSAAuthentication no
(-)openssh-5.8p2.orig/sshd_config.0 (-1 / +19 lines)
Lines 71-76 DESCRIPTION Link Here
71
71
72
             See PATTERNS in ssh_config(5) for more information on patterns.
72
             See PATTERNS in ssh_config(5) for more information on patterns.
73
73
74
     AuthorizedKeysCommand
75
76
             Specifies a program to be used for lookup of the user's
77
	     public keys.  The program will be invoked with its first
78
	     argument the name of the user being authorized, and should produce 
79
	     on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
80
	     in sshd(8)).  By default (or when set to the empty string) there is no
81
	     AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
82
	     authorize the user, authorization falls through to the
83
	     AuthorizedKeysFile.  Note that this option has an effect
84
	     only with PubkeyAuthentication turned on.
85
86
     AuthorizedKeysCommandRunAs
87
             Specifies the user under whose account the AuthorizedKeysCommand is run.
88
             Empty string (the default value) means the user being authorized
89
             is used.
90
74
     AuthorizedKeysFile
91
     AuthorizedKeysFile
75
             Specifies the file that contains the public keys that can be used
92
             Specifies the file that contains the public keys that can be used
76
             for user authentication.  The format is described in the
93
             for user authentication.  The format is described in the
Lines 398-404 DESCRIPTION Link Here
398
415
399
             Only a subset of keywords may be used on the lines following a
416
             Only a subset of keywords may be used on the lines following a
400
             Match keyword.  Available keywords are AllowAgentForwarding,
417
             Match keyword.  Available keywords are AllowAgentForwarding,
401
             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile,
418
             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand,
419
             AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile,
402
             Banner, ChrootDirectory, ForceCommand, GatewayPorts,
420
             Banner, ChrootDirectory, ForceCommand, GatewayPorts,
403
             GSSAPIAuthentication, HostbasedAuthentication,
421
             GSSAPIAuthentication, HostbasedAuthentication,
404
             HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
422
             HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
(-)openssh-5.8p2.orig/sshd_config.5 (+17 lines)
Lines 703-708 Available keywords are Link Here
703
.Cm AllowAgentForwarding ,
703
.Cm AllowAgentForwarding ,
704
.Cm AllowTcpForwarding ,
704
.Cm AllowTcpForwarding ,
705
.Cm AuthorizedKeysFile ,
705
.Cm AuthorizedKeysFile ,
706
.Cm AuthorizedKeysCommand ,
707
.Cm AuthorizedKeysCommandRunAs ,
706
.Cm AuthorizedPrincipalsFile ,
708
.Cm AuthorizedPrincipalsFile ,
707
.Cm Banner ,
709
.Cm Banner ,
708
.Cm ChrootDirectory ,
710
.Cm ChrootDirectory ,
Lines 715-720 Available keywords are Link Here
715
.Cm KerberosAuthentication ,
717
.Cm KerberosAuthentication ,
716
.Cm MaxAuthTries ,
718
.Cm MaxAuthTries ,
717
.Cm MaxSessions ,
719
.Cm MaxSessions ,
720
.Cm PubkeyAuthentication ,
718
.Cm PasswordAuthentication ,
721
.Cm PasswordAuthentication ,
719
.Cm PermitEmptyPasswords ,
722
.Cm PermitEmptyPasswords ,
720
.Cm PermitOpen ,
723
.Cm PermitOpen ,
Lines 917-922 Specifies a list of revoked public keys. Link Here
917
Keys listed in this file will be refused for public key authentication.
920
Keys listed in this file will be refused for public key authentication.
918
Note that if this file is not readable, then public key authentication will
921
Note that if this file is not readable, then public key authentication will
919
be refused for all users.
922
be refused for all users.
923
.It Cm AuthorizedKeysCommand
924
Specifies a program to be used for lookup of the user's
925
public keys.  The program will be invoked with its first
926
argument the name of the user being authorized, and should produce 
927
on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
928
in sshd(8)).  By default (or when set to the empty string) there is no
929
AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
930
authorize the user, authorization falls through to the
931
AuthorizedKeysFile.  Note that this option has an effect
932
only with PubkeyAuthentication turned on.
933
.It Cm AuthorizedKeysCommandRunAs
934
Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
935
string (the default value) means the user being authorized is used.
936
.Dq 
920
.It Cm RhostsRSAAuthentication
937
.It Cm RhostsRSAAuthentication
921
Specifies whether rhosts or /etc/hosts.equiv authentication together
938
Specifies whether rhosts or /etc/hosts.equiv authentication together
922
with successful RSA host authentication is allowed.
939
with successful RSA host authentication is allowed.

Return to bug 1663