diff options
Diffstat (limited to 'src/ctl.c')
-rw-r--r-- | src/ctl.c | 64 |
1 files changed, 61 insertions, 3 deletions
@@ -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,12 +317,56 @@ 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) { ctlio_reply (io, "220", "%s attending", instance); @@ -347,9 +400,12 @@ cmd_help (struct ctlio *io, size_t argc, char **argv) ctlio_reply (io, "113", "help text follows"); for (cp = cmdtab; cp->verb; cp++) { + 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); |