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

Collapse All | Expand All

(-)openssh-5.6p1/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 264-290 match_principals_file(char *file, struct Link Here
264
265
265
/* return 1 if user allows given key */
266
/* return 1 if user allows given key */
266
static int
267
static int
267
user_key_allowed2(struct passwd *pw, Key *key, char *file)
268
user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw)
268
{
269
{
269
	char line[SSH_MAX_PUBKEY_BYTES];
270
	char line[SSH_MAX_PUBKEY_BYTES];
270
	const char *reason;
271
	const char *reason;
271
	int found_key = 0;
272
	int found_key = 0;
272
	FILE *f;
273
	u_long linenum = 0;
273
	u_long linenum = 0;
274
	Key *found;
274
	Key *found;
275
	char *fp;
275
	char *fp;
276
276
277
	/* Temporarily use the user's uid. */
278
	temporarily_use_uid(pw);
279
280
	debug("trying public key file %s", file);
281
	f = auth_openkeyfile(file, pw, options.strict_modes);
282
283
	if (!f) {
284
		restore_uid();
285
		return 0;
286
	}
287
288
	found_key = 0;
277
	found_key = 0;
289
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
278
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
290
279
Lines 377-384 user_key_allowed2(struct passwd *pw, Key Link Here
377
			break;
366
			break;
378
		}
367
		}
379
	}
368
	}
380
	restore_uid();
381
	fclose(f);
382
	key_free(found);
369
	key_free(found);
383
	if (!found_key)
370
	if (!found_key)
384
		debug2("key not found");
371
		debug2("key not found");
Lines 440-452 user_cert_trusted_ca(struct passwd *pw, Link Here
440
	return ret;
427
	return ret;
441
}
428
}
442
429
443
/* check whether given key is in .ssh/authorized_keys* */
430
/* return 1 if user allows given key */
431
static int
432
user_key_allowed2(struct passwd *pw, Key *key, char *file)
433
{
434
	FILE *f;
435
	int found_key = 0;
436
437
	/* Temporarily use the user's uid. */
438
	temporarily_use_uid(pw);
439
440
	debug("trying public key file %s", file);
441
	f = auth_openkeyfile(file, pw, options.strict_modes);
442
443
 	if (f) {
444
 		found_key = user_search_key_in_file (f, file, key, pw);
445
		fclose(f);
446
	}
447
448
	restore_uid();
449
	return found_key;
450
}
451
452
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
453
454
#define WHITESPACE " \t\r\n"
455
456
/* return 1 if user allows given key */
457
static int
458
user_key_via_command_allowed2(struct passwd *pw, Key *key)
459
{
460
	FILE *f;
461
	int found_key = 0;
462
	char *progname = NULL;
463
	char *cp;
464
	struct passwd *runas_pw;
465
	struct stat st;
466
	int childdescriptors[2], i;
467
	pid_t pstat, pid, child;
468
469
	if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/')
470
		return -1;
471
472
	/* get the run as identity from config */
473
	runas_pw = (options.authorized_keys_command_runas == NULL)? pw
474
	    : getpwnam (options.authorized_keys_command_runas);
475
	if (!runas_pw) {
476
		error("%s: getpwnam(\"%s\"): %s", __func__,
477
		    options.authorized_keys_command_runas, strerror(errno));
478
		return 0;
479
	}
480
481
	/* Temporarily use the specified uid. */
482
	if (runas_pw->pw_uid != 0)
483
		temporarily_use_uid(runas_pw);
484
485
	progname = xstrdup(options.authorized_keys_command);
486
487
	debug3("%s: checking program '%s'", __func__, progname);
488
489
	if (stat (progname, &st) < 0) {
490
		error("%s: stat(\"%s\"): %s", __func__,
491
		    progname, strerror(errno));
492
		goto go_away;
493
	}
494
495
	if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
496
		error("bad ownership or modes for AuthorizedKeysCommand \"%s\"",
497
		    progname);
498
		goto go_away;
499
	}
500
501
	if (!S_ISREG(st.st_mode)) {
502
		error("AuthorizedKeysCommand \"%s\" is not a regular file",
503
		    progname);
504
		goto go_away;
505
	}
506
507
	/*
508
	 * Descend the path, checking that each component is a
509
	 * root-owned directory with strict permissions.
510
	 */
511
	do {
512
		if ((cp = strrchr(progname, '/')) == NULL)
513
			break;
514
		else 
515
			*cp = '\0';
516
	
517
		debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname));
518
519
		if (stat((*progname == '\0' ? "/" : progname), &st) != 0) {
520
			error("%s: stat(\"%s\"): %s", __func__,
521
			    progname, strerror(errno));
522
			goto go_away;
523
		}
524
		if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
525
			error("bad ownership or modes for AuthorizedKeysCommand path component \"%s\"",
526
			    progname);
527
			goto go_away;
528
		}
529
		if (!S_ISDIR(st.st_mode)) {
530
			error("AuthorizedKeysCommand path component \"%s\" is not a directory",
531
			    progname);
532
			goto go_away;
533
		}
534
	} while (1);
535
536
	/* open the pipe and read the keys */
537
	if (pipe(childdescriptors)) {
538
		error("failed to pipe(2) for AuthorizedKeysCommand: %s",
539
		    strerror(errno));
540
		goto go_away;
541
	}
542
543
	child = fork();
544
	if (child == -1) {
545
		error("failed to fork(2) for AuthorizedKeysCommand: %s",
546
		    strerror(errno));
547
		goto go_away;
548
	} else if (child == 0) {
549
		/* we're in the child process here -- we should never return from this block. */
550
		/* permanently drop privs in child process */
551
		if (runas_pw->pw_uid != 0) {
552
			restore_uid();
553
			permanently_set_uid(runas_pw);
554
	  	}
555
556
		close(childdescriptors[0]);
557
		/* put the write end of the pipe on stdout (FD 1) */
558
		if (dup2(childdescriptors[1], 1) == -1) {
559
			error("failed to dup2(2) from AuthorizedKeysCommand: %s",
560
			    strerror(errno));
561
			_exit(127);
562
		}
563
564
		debug3("about to execl() AuthorizedKeysCommand: \"%s\" \"%s\"", options.authorized_keys_command, pw->pw_name);
565
		/* see session.c:child_close_fds() */
566
		for (i = 3; i < 64; ++i) {
567
			close(i);
568
		}
569
570
		execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL);
571
572
		/* if we got here, it didn't work */
573
		error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */
574
		_exit(127);
575
	}
576
	
577
	close(childdescriptors[1]);
578
	f = fdopen(childdescriptors[0], "r");
579
	if (!f) {
580
		error("%s: could not buffer FDs from AuthorizedKeysCommand (\"%s\", \"r\"): %s", __func__,
581
		    options.authorized_keys_command, strerror (errno));
582
		goto go_away;
583
	}
584
585
	found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw);
586
	fclose (f);
587
	do {
588
		pid = waitpid(child, &pstat, 0);
589
	} while (pid == -1 && errno == EINTR);
590
591
	/* what about the return value from the child process? */
592
go_away:
593
	if (progname)
594
		xfree (progname);
595
596
	if (runas_pw->pw_uid != 0)
597
		restore_uid();
598
	return found_key;
599
}
600
#endif
601
602
/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */
444
int
603
int
445
user_key_allowed(struct passwd *pw, Key *key)
604
user_key_allowed(struct passwd *pw, Key *key)
446
{
605
{
447
	int success;
606
	int success;
448
	char *file;
607
	char *file;
449
608
609
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
610
	success = user_key_via_command_allowed2(pw, key);
611
	if (success > 0)
612
		return success;
613
#endif
614
450
	if (auth_key_is_revoked(key))
615
	if (auth_key_is_revoked(key))
451
		return 0;
616
		return 0;
452
	if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
617
	if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
(-)openssh-5.6p1/configure.ac.akc (+13 lines)
Lines 1346-1351 AC_ARG_WITH(audit, 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 4209-4214 echo " Linux audit support Link Here
4209
echo "                 Smartcard support: $SCARD_MSG"
4221
echo "                 Smartcard support: $SCARD_MSG"
4210
echo "                     S/KEY support: $SKEY_MSG"
4222
echo "                     S/KEY support: $SKEY_MSG"
4211
echo "              TCP Wrappers support: $TCPW_MSG"
4223
echo "              TCP Wrappers support: $TCPW_MSG"
4224
echo "     AuthorizedKeysCommand support: $AKC_MSG"
4212
echo "              MD5 password support: $MD5_MSG"
4225
echo "              MD5 password support: $MD5_MSG"
4213
echo "                   libedit support: $LIBEDIT_MSG"
4226
echo "                   libedit support: $LIBEDIT_MSG"
4214
echo "  Solaris process contract support: $SPC_MSG"
4227
echo "  Solaris process contract support: $SPC_MSG"
(-)openssh-5.6p1/servconf.c.akc (+28 lines)
Lines 129-134 initialize_server_options(ServerOptions Link Here
129
	options->num_permitted_opens = -1;
129
	options->num_permitted_opens = -1;
130
	options->adm_forced_command = NULL;
130
	options->adm_forced_command = NULL;
131
	options->chroot_directory = NULL;
131
	options->chroot_directory = NULL;
132
	options->authorized_keys_command = NULL;
133
	options->authorized_keys_command_runas = NULL;
132
	options->zero_knowledge_password_authentication = -1;
134
	options->zero_knowledge_password_authentication = -1;
133
	options->revoked_keys_file = NULL;
135
	options->revoked_keys_file = NULL;
134
	options->trusted_user_ca_keys = NULL;
136
	options->trusted_user_ca_keys = NULL;
Lines 316-321 typedef enum { Link Here
316
	sUsePrivilegeSeparation, sAllowAgentForwarding,
318
	sUsePrivilegeSeparation, sAllowAgentForwarding,
317
	sZeroKnowledgePasswordAuthentication, sHostCertificate,
319
	sZeroKnowledgePasswordAuthentication, sHostCertificate,
318
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
320
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
321
	sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs,
319
	sDeprecated, sUnsupported
322
	sDeprecated, sUnsupported
320
} ServerOpCodes;
323
} ServerOpCodes;
321
324
Lines 439-444 static struct { Link Here
439
	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
442
	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
440
	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
443
	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
441
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
444
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
445
#ifdef WITH_AUTHORIZED_KEYS_COMMAND
446
	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
447
	{ "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
448
#else
449
	{ "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
450
	{ "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
451
#endif
442
	{ NULL, sBadOption, 0 }
452
	{ NULL, sBadOption, 0 }
443
};
453
};
444
454
Lines 1360-1365 process_server_config_line(ServerOptions Link Here
1360
		charptr = &options->revoked_keys_file;
1370
		charptr = &options->revoked_keys_file;
1361
		goto parse_filename;
1371
		goto parse_filename;
1362
1372
1373
	case sAuthorizedKeysCommand:
1374
		len = strspn(cp, WHITESPACE);
1375
		if (*activep && options->authorized_keys_command == NULL)
1376
			options->authorized_keys_command = xstrdup(cp + len);
1377
		return 0;
1378
1379
	case sAuthorizedKeysCommandRunAs:
1380
		charptr = &options->authorized_keys_command_runas;
1381
1382
		arg = strdelim(&cp);
1383
		if (*activep && *charptr == NULL)
1384
			*charptr = xstrdup(arg);
1385
		break;
1386
1363
	case sDeprecated:
1387
	case sDeprecated:
1364
		logit("%s line %d: Deprecated option %s",
1388
		logit("%s line %d: Deprecated option %s",
1365
		    filename, linenum, arg);
1389
		    filename, linenum, arg);
Lines 1453-1458 copy_set_server_options(ServerOptions *d Link Here
1453
	M_CP_INTOPT(gss_authentication);
1477
	M_CP_INTOPT(gss_authentication);
1454
	M_CP_INTOPT(rsa_authentication);
1478
	M_CP_INTOPT(rsa_authentication);
1455
	M_CP_INTOPT(pubkey_authentication);
1479
	M_CP_INTOPT(pubkey_authentication);
1480
	M_CP_STROPT(authorized_keys_command);
1481
	M_CP_STROPT(authorized_keys_command_runas);
1456
	M_CP_INTOPT(kerberos_authentication);
1482
	M_CP_INTOPT(kerberos_authentication);
1457
	M_CP_INTOPT(hostbased_authentication);
1483
	M_CP_INTOPT(hostbased_authentication);
1458
	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1484
	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
Lines 1705-1710 dump_config(ServerOptions *o) Link Here
1705
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1731
	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1706
	dump_cfg_string(sAuthorizedPrincipalsFile,
1732
	dump_cfg_string(sAuthorizedPrincipalsFile,
1707
	    o->authorized_principals_file);
1733
	    o->authorized_principals_file);
1734
	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
1735
	dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas);
1708
1736
1709
	/* string arguments requiring a lookup */
1737
	/* string arguments requiring a lookup */
1710
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1738
	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
(-)openssh-5.6p1/servconf.h.akc (+2 lines)
Lines 158-163 typedef struct { Link Here
158
	char   *revoked_keys_file;
158
	char   *revoked_keys_file;
159
	char   *trusted_user_ca_keys;
159
	char   *trusted_user_ca_keys;
160
	char   *authorized_principals_file;
160
	char   *authorized_principals_file;
161
	char   *authorized_keys_command;
162
	char   *authorized_keys_command_runas;
161
}       ServerOptions;
163
}       ServerOptions;
162
164
163
void	 initialize_server_options(ServerOptions *);
165
void	 initialize_server_options(ServerOptions *);
(-)openssh-5.6p1/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 375-381 DESCRIPTION Link Here
375
392
376
             Only a subset of keywords may be used on the lines following a
393
             Only a subset of keywords may be used on the lines following a
377
             Match keyword.  Available keywords are AllowAgentForwarding,
394
             Match keyword.  Available keywords are AllowAgentForwarding,
378
             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile,
395
             AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand,
396
             AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile,
379
             Banner, ChrootDirectory, ForceCommand, GatewayPorts,
397
             Banner, ChrootDirectory, ForceCommand, GatewayPorts,
380
             GSSAPIAuthentication, HostbasedAuthentication,
398
             GSSAPIAuthentication, HostbasedAuthentication,
381
             HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
399
             HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
(-)openssh-5.6p1/sshd_config.5.akc (+17 lines)
Lines 654-659 Available keywords are Link Here
654
.Cm AllowAgentForwarding ,
654
.Cm AllowAgentForwarding ,
655
.Cm AllowTcpForwarding ,
655
.Cm AllowTcpForwarding ,
656
.Cm AuthorizedKeysFile ,
656
.Cm AuthorizedKeysFile ,
657
.Cm AuthorizedKeysCommand ,
658
.Cm AuthorizedKeysCommandRunAs ,
657
.Cm AuthorizedPrincipalsFile ,
659
.Cm AuthorizedPrincipalsFile ,
658
.Cm Banner ,
660
.Cm Banner ,
659
.Cm ChrootDirectory ,
661
.Cm ChrootDirectory ,
Lines 666-671 Available keywords are Link Here
666
.Cm KerberosAuthentication ,
668
.Cm KerberosAuthentication ,
667
.Cm MaxAuthTries ,
669
.Cm MaxAuthTries ,
668
.Cm MaxSessions ,
670
.Cm MaxSessions ,
671
.Cm PubkeyAuthentication ,
669
.Cm PasswordAuthentication ,
672
.Cm PasswordAuthentication ,
670
.Cm PermitEmptyPasswords ,
673
.Cm PermitEmptyPasswords ,
671
.Cm PermitOpen ,
674
.Cm PermitOpen ,
Lines 868-873 Specifies a list of revoked public keys. Link Here
868
Keys listed in this file will be refused for public key authentication.
871
Keys listed in this file will be refused for public key authentication.
869
Note that if this file is not readable, then public key authentication will
872
Note that if this file is not readable, then public key authentication will
870
be refused for all users.
873
be refused for all users.
874
.It Cm AuthorizedKeysCommand
875
Specifies a program to be used for lookup of the user's
876
public keys.  The program will be invoked with its first
877
argument the name of the user being authorized, and should produce 
878
on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS 
879
in sshd(8)).  By default (or when set to the empty string) there is no
880
AuthorizedKeysCommand run.  If the AuthorizedKeysCommand does not successfully
881
authorize the user, authorization falls through to the
882
AuthorizedKeysFile.  Note that this option has an effect
883
only with PubkeyAuthentication turned on.
884
.It Cm AuthorizedKeysCommandRunAs
885
Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
886
string (the default value) means the user being authorized is used.
887
.Dq 
871
.It Cm RhostsRSAAuthentication
888
.It Cm RhostsRSAAuthentication
872
Specifies whether rhosts or /etc/hosts.equiv authentication together
889
Specifies whether rhosts or /etc/hosts.equiv authentication together
873
with successful RSA host authentication is allowed.
890
with successful RSA host authentication is allowed.
(-)openssh-5.6p1/sshd_config.akc (+2 lines)
Lines 45-50 SyslogFacility AUTHPRIV 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

Return to bug 1663