Skip to content

Commit

Permalink
sssctl: add cert-eval-rule sub-command
Browse files Browse the repository at this point in the history
The new 'cert-eval-rule' sub-command of sssctl show the results of given
matching and mapping rules on a given certificate. This should help to
find suitable mapping and matching rules and to understand why given
certificate is matched or not.

Resolves: SSSD#6403

Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
  • Loading branch information
sumit-bose authored and alexey-tikhonov committed Dec 2, 2022
1 parent c4085c9 commit 11483f1
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/tools/sssctl/sssctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ int main(int argc, const char **argv)
SSS_TOOL_DELIMITER("Certificate related tools:"),
SSS_TOOL_COMMAND("cert-show", "Print information about the certificate", 0, sssctl_cert_show),
SSS_TOOL_COMMAND("cert-map", "Show users mapped to the certificate", 0, sssctl_cert_map),
SSS_TOOL_COMMAND("cert-eval-rule", "Check mapping and matching rule with a certificate", 0, sssctl_cert_eval_rule),
#ifdef BUILD_PASSKEY
SSS_TOOL_DELIMITER("Passkey related tools:"),
SSS_TOOL_COMMAND_FLAGS("passkey-exec", "Perform passkey related operations", 0, sssctl_passkey_exec, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK),
Expand Down
4 changes: 4 additions & 0 deletions src/tools/sssctl/sssctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,8 @@ errno_t sssctl_passkey_exec(struct sss_cmdline *cmdline,
struct sss_tool_ctx *tool_ctx,
void *pvt);
#endif /* BUILD_PASSKEY */

errno_t sssctl_cert_eval_rule(struct sss_cmdline *cmdline,
struct sss_tool_ctx *tool_ctx,
void *pvt);
#endif /* _SSSCTL_H_ */
114 changes: 114 additions & 0 deletions src/tools/sssctl/sssctl_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,117 @@ errno_t sssctl_cert_map(struct sss_cmdline *cmdline,

return ret;
}

struct priv_sss_debug {
bool verbose;
};

void certmap_ext_debug(void *private, const char *file, long line,
const char *function, const char *format, ...)
{
va_list ap;
struct priv_sss_debug *data = private;

if (data != NULL && data->verbose) {
va_start(ap, format);
fprintf(stdout, "%s:%ld [%s]: ", file, line, function);
vfprintf(stdout, format, ap);
fprintf(stdout, "\n");
va_end(ap);
}
}

errno_t sssctl_cert_eval_rule(struct sss_cmdline *cmdline,
struct sss_tool_ctx *tool_ctx,
void *pvt)
{
TALLOC_CTX *tmp_ctx = NULL;
errno_t ret;
int verbose = 0;
const char *cert_b64 = NULL;
const char *map = NULL;
const char *match = NULL;
struct sss_certmap_ctx *sss_certmap_ctx = NULL;
struct priv_sss_debug priv_sss_debug;
uint8_t *der_cert = NULL;
size_t der_size;
char *filter = NULL;
char **domains = NULL;

/* Parse command line. */
struct poptOption options[] = {
{"map", 'p', POPT_ARG_STRING, &map, 0, _("Mapping rule"), NULL },
{"match", 't', POPT_ARG_STRING, &match, 0, _("Matching rule"), NULL },
{"verbose", 'v', POPT_ARG_NONE, &verbose, 0, _("Show debug information"), NULL },
POPT_TABLEEND
};

ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL,
NULL, NULL, "CERTIFICATE-BASE64-ENCODED",
_("Specify base64 encoded certificate."),
SSS_TOOL_OPT_REQUIRED, &cert_b64, NULL);
if (ret != EOK) {
ERROR("Unable to parse command arguments\n");
return ret;
}

tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
ERROR("Out of memory!\n");
return ENOMEM;
}

priv_sss_debug.verbose = (verbose != 0);

ret = sss_certmap_init(tmp_ctx, certmap_ext_debug, &priv_sss_debug,
&sss_certmap_ctx);
if (ret != EOK) {
ERROR("Failed to setup certmap context.\n");
goto done;
}

ret = sss_certmap_add_rule(sss_certmap_ctx, 1, match, map, NULL);
if (ret != EOK) {
ERROR("Failed to add mapping and matching rules with error [%d][%s].\n",
ret, sss_strerror(ret));
goto done;
}

der_cert = sss_base64_decode(tmp_ctx, cert_b64, &der_size);
if (der_cert == NULL) {
ERROR("Failed to decode base64 string.\n");
ret = EINVAL;
goto done;
}

ret = sss_certmap_match_cert(sss_certmap_ctx, der_cert, der_size);
switch (ret) {
case 0:
PRINT("Certificate matches rule.\n");
break;
case ENOENT:
PRINT("Certificate does not match rule.\n");
break;
default:
ERROR("Error during certificate matching [%d][%s].\n",
ret, sss_strerror(ret));
}

ret = sss_certmap_get_search_filter(sss_certmap_ctx, der_cert, der_size,
&filter, &domains);
if (ret != 0) {
ERROR("Failed to generate mapping filter [%d][%s].\n",
ret, sss_strerror(ret));
goto done;
}
PRINT("Mapping filter:\n\n %s\n\n", filter);
sss_certmap_free_filter_and_domains(filter, domains);

ret = EOK;

done:

talloc_free(tmp_ctx);

return ret;
}

0 comments on commit 11483f1

Please sign in to comment.