From 6bb908898b833ec69c66e918de732af5bad68934 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 16 Dec 2015 14:58:07 +0200 Subject: Implement authentication on control socket. * Makefile.am (SUBDIRS): Add src. * configure.ac: Check for crypt.h and PAM Build ident/Makefile * grecs: Update. * ident/Makefile.am: New file. * ident/ident.c: New file. * ident/ident.h: New file. * ident/identity.h: New file. * ident/pam.c: New file. * ident/provider.c: New file. * ident/system.c: New file. * lib/Makefile.am: Add arraymember.c * lib/arraymember.c: New file. * lib/libpies.h (is_array_member): New proto. * src/Makefile.am (LDADD): Add libident.a and @PAM_LIBS@ * src/acl.c (acl_entry): Remove groups. Add new members: names and name_match. (pies_acl_create): Deep copy the locus. Set free_entry function for the list. (pies_acl_free): Free locus. (_parse_from): Set free_entry function for the list. (_parse_group): Parse the "user" construct. (parse_acl_line): Deep copy the locus. Allow for null value. (acl_keywords): Update docstrings. (_acl_check): Rewrite identity checks. * src/acl.h (acl_input): Remove. : New member. (pies_acl_free): New proto. * src/ctl.c (identity): New global. (cmdtab): New command: auth (ctlio) : New members. (ctlio_create): Start from authenticated state only if no identity_providers are configured. (cmd_auth): New function. (cmd_help): Print only commands that are available in the current state. (ctl_accept): Initialize io->addr and io->addrlen. * src/inetd-bi.c: Change call to check_acl * src/pies.c: Include identity.h (control_keywords): New statement "identity-acl" (pies_keywords): New statement "identity-provider" (config_init): Register identity mechanisms. (config_parse): New function. (config_help): Print help on identity-provider statements. (main): Use config_parse to parse grecs-style configurations. * src/pies.h: Include identity.h (check_acl): Change argument list. All callers changed. (control): Remove acl. Add conn_acl and id_acl instead. * src/progman.c (check_acl): Change argument list. Take identity as the 3rd argument. --- src/ctl.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 5 deletions(-) (limited to 'src/ctl.c') diff --git a/src/ctl.c b/src/ctl.c index f9f2d76..20c16e1 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -17,11 +17,14 @@ #include "pies.h" #include "prog.h" #include "xvasprintf.h" +#include "identity.h" #define DEFAULT_CONTROL_URL "unix:///tmp/%s.ctl" struct control control; +pies_identity_t identity; + struct ctlbuf { @@ -107,6 +110,7 @@ ctlbuf_chomp (struct ctlbuf *buf) struct ctlio; +static void cmd_auth (struct ctlio *, size_t, char **); static void cmd_quit (struct ctlio *, size_t, char **); static void cmd_noop (struct ctlio *, size_t, char **); static void cmd_help (struct ctlio *, size_t, char **); @@ -129,6 +133,8 @@ struct ctlio_command }; static struct ctlio_command cmdtab[] = { + { "auth", "authenticate", + CTL_INITIAL_STATE, 3, 3, cmd_auth }, { "noop", "no operation", CTL_ALL_STATES, 1, 1, cmd_noop }, { "id", "identify the instance", @@ -167,6 +173,8 @@ ctlio_command_find (char const *verb) struct ctlio { + union pies_sockaddr_storage addr; + socklen_t addrlen; int state; int action; struct ctlbuf ibuf; @@ -181,7 +189,8 @@ ctlio_create (void) struct ctlio *io; io = xmalloc (sizeof (*io)); - io->state = CTL_AUTHENTICATED_STATE; //FIXME CTL_INITIAL_STATE; + io->state = identity_provider_list + ? CTL_INITIAL_STATE : CTL_AUTHENTICATED_STATE; io->action = ACTION_CONT; ctlbuf_init (&io->ibuf); ctlbuf_init (&io->obuf); @@ -308,11 +317,55 @@ static void ctlio_initial_reply (struct ctlio *io) { ctlio_printf (io, "220 %s", instance); - ctlio_printf (io, " <%s>", "foobarbaz"); //FIXME: auth mechanisms ctlio_eol (io); } +static void +cmd_auth (struct ctlio *io, size_t argc, char **argv) +{ + struct grecs_list_entry *ep; + pies_identity_t id = pies_identity_create (argv[1]); + int auth = 0; + + for (ep = identity_provider_list->head; ep; ep = ep->next) + { + pies_identity_provider_t provider = ep->data; + char const *pname = pies_identity_provider_name (provider); + + debug(1, ("trying %s...", pname)); + if (pies_authenticate (provider, id, argv[2]) == 0) + { + if (check_acl (control.id_acl, + (struct sockaddr *)&io->addr, io->addrlen, id)) + { + logmsg (LOG_AUTH, "%s authenticated via %s, but failed ACL check", + argv[1], pname); + auth = 0; + } + else + { + logmsg (LOG_AUTH, "%s authenticated via %s", + argv[1], pname); + auth = 1; + } + break; + } + } + + if (auth) + { + ctlio_reply (io, "230", "authentication successful"); + identity = id; + io->state = CTL_AUTHENTICATED_STATE; + } + else + { + pies_identity_destroy (id); + ctlio_reply (io, "531", "access denied"); + } +} + static void cmd_noop (struct ctlio *io, size_t argc, char **argv) { @@ -347,8 +400,11 @@ cmd_help (struct ctlio *io, size_t argc, char **argv) ctlio_reply (io, "113", "help text follows"); for (cp = cmdtab; cp->verb; cp++) { - ctlio_printf (io, "%-9s%s", cp->verb, cp->descr); - ctlio_eol (io); + if (cp->states & io->state) + { + ctlio_printf (io, "%-9s%s", cp->verb, cp->descr); + ctlio_eol (io); + } } ctlio_eot (io); } @@ -1000,7 +1056,7 @@ ctl_accept (int socket, void *data) free (s); } - if (check_acl (control.acl, (struct sockaddr *)&addr, addrlen)) + if (check_acl (control.conn_acl, (struct sockaddr *)&addr, addrlen, NULL)) { close (fd); return 1; @@ -1008,6 +1064,8 @@ ctl_accept (int socket, void *data) /* FIXME: Check number of connections? */ io = ctlio_create (); + io->addr = addr; + io->addrlen = addrlen; ctlio_initial_reply (io); register_socket (fd, NULL, ctlwr, NULL, io); -- cgit v1.2.1