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

Collapse All | Expand All

(-)openssh-5.9p1/auth2-pubkey.c.akc (-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 0;
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
	u_int success, i;
598
	u_int success, i;
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.9p1/configure.ac.akc (+13 lines)
Lines 1421-1426 AC_ARG_WITH([audit], Link Here
1421
	esac ]
1421
	esac ]
1422
)
1422
)
1423
1423
1424
# Check whether user wants AuthorizedKeysCommand support
1425
AKC_MSG="no"
1426
AC_ARG_WITH(authorized-keys-command,
1427
	[  --with-authorized-keys-command      Enable AuthorizedKeysCommand support],
1428
	[
1429
		if test "x$withval" != "xno" ; then
1430
			AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support])
1431
			AKC_MSG="yes"
1432
		fi
1433
	]
1434
)
1435
1424
dnl    Checks for library functions. Please keep in alphabetical order
1436
dnl    Checks for library functions. Please keep in alphabetical order
1425
AC_CHECK_FUNCS([ \
1437
AC_CHECK_FUNCS([ \
1426
	arc4random \
1438
	arc4random \
Lines 4235-4240 echo " SELinux support Link Here
4235
echo "                 Smartcard support: $SCARD_MSG"
4247
echo "                 Smartcard support: $SCARD_MSG"
4236
echo "                     S/KEY support: $SKEY_MSG"
4248
echo "                     S/KEY support: $SKEY_MSG"
4237
echo "              TCP Wrappers support: $TCPW_MSG"
4249
echo "              TCP Wrappers support: $TCPW_MSG"
4250
echo "     AuthorizedKeysCommand support: $AKC_MSG"
4238
echo "              MD5 password support: $MD5_MSG"
4251
echo "              MD5 password support: $MD5_MSG"
4239
echo "                   libedit support: $LIBEDIT_MSG"
4252
echo "                   libedit support: $LIBEDIT_MSG"
4240
echo "  Solaris process contract support: $SPC_MSG"
4253
echo "  Solaris process contract support: $SPC_MSG"
(-)openssh-5.9p1/servconf.c.akc (+28 lines)
Lines 132-137 initialize_server_options(ServerOptions Link Here
132
	options->num_permitted_opens = -1;
132
	options->num_permitted_opens = -1;
133
	options->adm_forced_command = NULL;
133
	options->adm_forced_command = NULL;
134
	options->chroot_directory = NULL;
134
	options->chroot_directory = NULL;
135
	options->authorized_keys_command = NULL;
136
	options->authorized_keys_command_runas = NULL;
135
	options->zero_knowledge_password_authentication = -1;
137
	options->zero_knowledge_password_authentication = -1;
136
	options->revoked_keys_file = NULL;
138
	options->revoked_keys_file = NULL;
137
	options->trusted_user_ca_keys = NULL;
139
	options->trusted_user_ca_keys = NULL;
Lines 324-329 typedef enum { Link Here
324
	sZeroKnowledgePasswordAuthentication, sHostCertificate,
326
	sZeroKnowledgePasswordAuthentication, sHostCertificate,
325
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
327
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
326
	sKexAlgorithms, sIPQoS,
328
	sKexAlgorithms, sIPQoS,
329
	sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs,
327
	sDeprecated, sUnsupported
330
	sDeprecated, sUnsupported
328
} ServerOpCodes;
331
} ServerOpCodes;
329
332
Lines 448-453 static struct { Link Here
448
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
451
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
449
	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
452
	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
450
	{ "ipqos", sIPQoS, SSHCFG_ALL },
453
	{ "ipqos", sIPQoS, SSHCFG_ALL },
454
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
455
	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
456
	{ "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
457
#else
458
	{ "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
459
	{ "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
460
#endif
451
	{ NULL, sBadOption, 0 }
461
	{ NULL, sBadOption, 0 }
452
};
462
};
453
463
Lines 1395-1400 process_server_config_line(ServerOptions Link Here
1395
		}
1405
		}
1396
		break;
1406
		break;
1397
1407
1408
	case sAuthorizedKeysCommand:
1409
		len = strspn(cp, WHITESPACE);
1410
		if (*activep && options->authorized_keys_command == NULL)
1411
			options->authorized_keys_command = xstrdup(cp + len);
1412
		return 0;
1413
1414
	case sAuthorizedKeysCommandRunAs:
1415
		charptr = &options->authorized_keys_command_runas;
1416
1417
		arg = strdelim(&cp);
1418
		if (*activep && *charptr == NULL)
1419
			*charptr = xstrdup(arg);
1420
		break;
1421
1398
	case sDeprecated:
1422
	case sDeprecated:
1399
		logit("%s line %d: Deprecated option %s",
1423
		logit("%s line %d: Deprecated option %s",
1400
		    filename, linenum, arg);
1424
		    filename, linenum, arg);
Lines 1499-1504 copy_set_server_options(ServerOptions *d Link Here
1499
	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1523
	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1500
	M_CP_INTOPT(kbd_interactive_authentication);
1524
	M_CP_INTOPT(kbd_interactive_authentication);
1501
	M_CP_INTOPT(zero_knowledge_password_authentication);
1525
	M_CP_INTOPT(zero_knowledge_password_authentication);
1526
	M_CP_STROPT(authorized_keys_command);
1527
	M_CP_STROPT(authorized_keys_command_runas);
1502
	M_CP_INTOPT(permit_root_login);
1528
	M_CP_INTOPT(permit_root_login);
1503
	M_CP_INTOPT(permit_empty_passwd);
1529
	M_CP_INTOPT(permit_empty_passwd);
1504
1530
Lines 1758-1763 dump_config(ServerOptions *o) Link Here
1758
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1784
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1759
	dump_cfg_string(sAuthorizedPrincipalsFile,
1785
	dump_cfg_string(sAuthorizedPrincipalsFile,
1760
	    o->authorized_principals_file);
1786
	    o->authorized_principals_file);
1787
	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
1788
	dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas);
1761
1789
1762
	/* string arguments requiring a lookup */
1790
	/* string arguments requiring a lookup */
1763
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1791
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
(-)openssh-5.9p1/servconf.h.akc (+2 lines)
Lines 166-171 typedef struct { Link Here
166
	char   *revoked_keys_file;
166
	char   *revoked_keys_file;
167
	char   *trusted_user_ca_keys;
167
	char   *trusted_user_ca_keys;
168
	char   *authorized_principals_file;
168
	char   *authorized_principals_file;
169
	char   *authorized_keys_command;
170
	char   *authorized_keys_command_runas;
169
}       ServerOptions;
171
}       ServerOptions;
170
172
171
/*
173
/*
(-)openssh-5.9p1/sshd_config.0.akc (-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 401-407 DESCRIPTION Link Here
401
418
402
             Only a subset of keywords may be used on the lines following a
419
             Only a subset of keywords may be used on the lines following a
403
             Match keyword.  Available keywords are AllowAgentForwarding,
420
             Match keyword.  Available keywords are AllowAgentForwarding,
404
             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile,
421
             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand,
422
             AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile,
405
             Banner, ChrootDirectory, ForceCommand, GatewayPorts,
423
             Banner, ChrootDirectory, ForceCommand, GatewayPorts,
406
             GSSAPIAuthentication, HostbasedAuthentication,
424
             GSSAPIAuthentication, HostbasedAuthentication,
407
             HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
425
             HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
(-)openssh-5.9p1/sshd_config.5.akc (+17 lines)
Lines 706-711 Available keywords are Link Here
706
.Cm AllowAgentForwarding ,
706
.Cm AllowAgentForwarding ,
707
.Cm AllowTcpForwarding ,
707
.Cm AllowTcpForwarding ,
708
.Cm AuthorizedKeysFile ,
708
.Cm AuthorizedKeysFile ,
709
.Cm AuthorizedKeysCommand ,
710
.Cm AuthorizedKeysCommandRunAs ,
709
.Cm AuthorizedPrincipalsFile ,
711
.Cm AuthorizedPrincipalsFile ,
710
.Cm Banner ,
712
.Cm Banner ,
711
.Cm ChrootDirectory ,
713
.Cm ChrootDirectory ,
Lines 718-723 Available keywords are Link Here
718
.Cm KerberosAuthentication ,
720
.Cm KerberosAuthentication ,
719
.Cm MaxAuthTries ,
721
.Cm MaxAuthTries ,
720
.Cm MaxSessions ,
722
.Cm MaxSessions ,
723
.Cm PubkeyAuthentication ,
721
.Cm PasswordAuthentication ,
724
.Cm PasswordAuthentication ,
722
.Cm PermitEmptyPasswords ,
725
.Cm PermitEmptyPasswords ,
723
.Cm PermitOpen ,
726
.Cm PermitOpen ,
Lines 920-925 Specifies a list of revoked public keys. Link Here
920
Keys listed in this file will be refused for public key authentication.
923
Keys listed in this file will be refused for public key authentication.
921
Note that if this file is not readable, then public key authentication will
924
Note that if this file is not readable, then public key authentication will
922
be refused for all users.
925
be refused for all users.
926
.It Cm AuthorizedKeysCommand
927
Specifies a program to be used for lookup of the user's
928
public keys.  The program will be invoked with its first
929
argument the name of the user being authorized, and should produce 
930
on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
931
in sshd(8)).  By default (or when set to the empty string) there is no
932
AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
933
authorize the user, authorization falls through to the
934
AuthorizedKeysFile.  Note that this option has an effect
935
only with PubkeyAuthentication turned on.
936
.It Cm AuthorizedKeysCommandRunAs
937
Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
938
string (the default value) means the user being authorized is used.
939
.Dq 
923
.It Cm RhostsRSAAuthentication
940
.It Cm RhostsRSAAuthentication
924
Specifies whether rhosts or /etc/hosts.equiv authentication together
941
Specifies whether rhosts or /etc/hosts.equiv authentication together
925
with successful RSA host authentication is allowed.
942
with successful RSA host authentication is allowed.
(-)openssh-5.9p1/sshd_config.akc (+3 lines)
Lines 49-54 Link Here
49
# but this is overridden so installations will only check .ssh/authorized_keys
49
# but this is overridden so installations will only check .ssh/authorized_keys
50
AuthorizedKeysFile	.ssh/authorized_keys
50
AuthorizedKeysFile	.ssh/authorized_keys
51
51
52
#AuthorizedKeysCommand none
53
#AuthorizedKeysCommandRunAs nobody
54
52
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
55
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
53
#RhostsRSAAuthentication no
56
#RhostsRSAAuthentication no
54
# similar for protocol version 2
57
# similar for protocol version 2

Return to bug 1663