Skip to content

Commit

Permalink
fixup! support authentication indicators in GSSAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
abbra committed Jun 27, 2024
1 parent 447fdd7 commit 8bb5003
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 89 deletions.
57 changes: 19 additions & 38 deletions gss-serv-krb5.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "match.h"

#include "ssh-gss.h"

Expand Down Expand Up @@ -79,46 +80,26 @@ ssh_gssapi_krb5_init(void)
/* Check if any of the indicators in the Kerberos ticket match
* one of indicators in the list of allowed/denied rules.
* In case of the match, apply the decision from the rule.
* If there is no match:
* - if there were both denial and allow rules, deny
* - if there were only denial rules, allow
* - if there were only allow rules, deny
* In case of no indicator from the ticket matching the rule, deny
*/

static int
ssh_gssapi_check_indicators(ssh_gssapi_client *client, int *matched)
{
char *chptr;
int denial, allows = 0, denials = 0;
u_int i, j;
int ret;
u_int i;

/* Check indicators */
for (i = 0; i < options.num_gss_indicators; i++) {
for (j = 0; client->indicators[j] != NULL; j++) {
chptr = strchr(options.gss_indicators[i], '=');
chptr[0] = '\0';
if (strcmp(client->indicators[j],
options.gss_indicators[i]) == 0) {
*matched = j;
}
chptr[0] = '=';
denial = (chptr[1] == 'd' || chptr[1] == 'D') ? 1 : 0;
denials |= denial;
allows |= !denial;
if (*matched) {
return (1 - denial);
}
for (i = 0; client->indicators[i] != NULL; i++) {
ret = match_pattern_list(client->indicators[i],
options.gss_indicators, 1);
/* negative or positive match */
if (ret != 0) {
*matched = i;
return ret;
}
}
/* No matches.
* If there were both types of rules, deny */
if (denials && allows)
return 0;
/* If there are only denials, allow the rest */
if (denials) {
return 1;
}
/* If there are only allows, deny the rest */
/* No rule matched */
return 0;
}

Expand All @@ -131,9 +112,8 @@ static int
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
{
krb5_principal princ;
int retval;
int retval, matched;
const char *errmsg;
int matched;

if (ssh_gssapi_krb5_init() == 0)
return 0;
Expand All @@ -151,20 +131,21 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
} else
retval = 0;

if ((retval == 1) && (options.num_gss_indicators != 0)) {
matched = -1;
if ((retval == 1) && (options.gss_indicators != NULL)) {
if (client->indicators) {
matched = -1;
retval = ssh_gssapi_check_indicators(client, &matched);
if (matched != -1) {
if (retval != 0) {
retval = (retval == 1);
logit("Ticket contains indicator %s, "
"krb5 principal %s is %s",
client->indicators[matched],
(char *)client->displayname.value,
retval ? "allowed" : "denied");
retval ? "allowed" : "denied");
goto cont;
}
}
if ((matched == -1) && (retval == 0)) {
if (retval == 0) {
logit("GSSAPI authentication indicators enforced "
"but not matched. krb5 principal %s denied",
(char *)client->displayname.value);
Expand Down
3 changes: 1 addition & 2 deletions readconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ typedef struct {
int hostbased_authentication; /* ssh2's rhosts_rsa */
int gss_authentication; /* Try GSS authentication */
int gss_deleg_creds; /* Delegate GSS credentials */
u_int num_gss_indicators;
char **gss_indicators; /* GSSAPI authentication indicators */
char *gss_indicators; /* GSSAPI authentication indicators */
int password_authentication; /* Try password
* authentication. */
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
Expand Down
40 changes: 6 additions & 34 deletions servconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ initialize_server_options(ServerOptions *options)
options->gss_cleanup_creds = -1;
options->gss_strict_acceptor = -1;
options->gss_indicators = NULL;
options->num_gss_indicators = 0;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->permit_empty_passwd = -1;
Expand Down Expand Up @@ -1598,38 +1597,12 @@ process_server_config_line_depth(ServerOptions *options, char *line,
goto parse_flag;

case sGssIndicators:
found = options->num_gss_indicators == 0;
while ((arg = argv_next(&ac, &av)) != NULL) {
if (*arg == '\0') {
error("%s line %d: keyword %s empty argument",
filename, linenum, keyword);
goto out;
}
p = strchr(arg, '=');
if (p == NULL) {
error("%s line %d: Invalid %s, must be name=accept|deny",
filename, linenum, keyword);
goto out;
}
p++;
if (!(*p == 'a' || *p == 'A' || *p == 'd' || *p == 'D')) {
error("%s line %d: Invalid %s, must be name=accept|deny",
filename, linenum, keyword);
goto out;
}
opt_array_append(filename, linenum, keyword,
&strs, &nstrs, arg);
}
if (nstrs == 0) {
fatal("%s line %d: no %s specified",
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
}
if (found && *activep) {
options->gss_indicators = strs;
options->num_gss_indicators = nstrs;
strs = NULL; /* transferred */
nstrs = 0;
}
if (options->gss_indicators == NULL)
options->gss_indicators = xstrdup(arg);
break;

case sPasswordAuthentication:
Expand Down Expand Up @@ -3217,8 +3190,7 @@ dump_config(ServerOptions *o)
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
dump_cfg_strarray_oneline(sGssIndicators, o->num_gss_indicators,
o->gss_indicators);
dump_cfg_string(sGssIndicators, o->gss_indicators);
#endif
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(sKbdInteractiveAuthentication,
Expand Down
5 changes: 2 additions & 3 deletions servconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ typedef struct {
char **allow_groups;
u_int num_deny_groups;
char **deny_groups;
u_int num_gss_indicators;
char **gss_indicators;
char *gss_indicators;

u_int num_subsystems;
char **subsystem_name;
Expand Down Expand Up @@ -298,12 +297,12 @@ TAILQ_HEAD(include_list, include_item);
M_CP_STROPT(routing_domain); \
M_CP_STROPT(permit_user_env_allowlist); \
M_CP_STROPT(pam_service_name); \
M_CP_STROPT(gss_indicators); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
M_CP_STRARRAYOPT(deny_users, num_deny_users); \
M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \
M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
M_CP_STRARRAYOPT(gss_indicators, num_gss_indicators); \
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
M_CP_STRARRAYOPT(setenv, num_setenv); \
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
Expand Down
21 changes: 9 additions & 12 deletions sshd_config.5
Original file line number Diff line number Diff line change
Expand Up @@ -756,15 +756,11 @@ The default is
.It Cm GSSAPIIndicators
Specifies whether to accept or deny GSSAPI authenticated access if Kerberos
mechanism is used and Kerberos ticket contains a particular set of
authentication indicators. The values can be specified as a pair of
.Cm name=accept|deny .
When
.Cm accept
is used, then presence of the authentication indicator 'name' is required to
allow the access. When
.Cm deny
is used, then the presence of the authentication indicator 'name' will deny
access to the system. Once
authentication indicators. The values can be specified as a comma-separated list
.Cm [!]name1,[!]name2,... .
When indicator's name is prefixed with !, the authentication indicator 'name'
will deny access to the system. Otherwise, one of non-negated authentication
indicators must be present in the Kerberos ticket to allow access. If
.Cm GSSAPIIndicators
is defined, a Kerberos ticket that has indicators but does not match the
policy will get denial. If at least one indicator is configured, whether for
Expand All @@ -776,16 +772,17 @@ indicators. SPAKE and PKINIT methods add authentication indicators
to all successful authentications. The SPAKE pre-authentication method is
preferred over an encrypted timestamp pre-authentication when passwords used to
authenticate user principals. Kerberos KDCs built with Heimdal Kerberos
(including Samba AD DC built with Heimdal) do not add authentication indicators
but are able to inquire them.
(including Samba AD DC built with Heimdal) do not add authentication
indicators. However, OpenSSH built against Heimdal Kerberos library is able to
inquire authentication indicators and thus can be used to check for their presence.
.Pp
Indicator name is case-sensitive and depends on the configuration of a
particular Kerberos deployment. Indicators available in MIT Kerberos and
FreeIPA environments:
.Pp
.Bl -tag -width XXXX -offset indent -compact
.It Cm hardened
SPAKE pre-authentication in MIT Kerberos and FreeIPA
SPAKE or encrypted timestamp pre-authentication mechanisms in MIT Kerberos and FreeIPA
.It Cm pkinit
smartcard or PKCS11 token-based pre-authentication in MIT Kerberos and FreeIPA
.It Cm radius
Expand Down

0 comments on commit 8bb5003

Please sign in to comment.