Further cleanup of tr_gss and usage for tids handling
authorJennifer Richards <jennifer@painless-security.com>
Fri, 13 Apr 2018 14:16:00 +0000 (10:16 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Fri, 13 Apr 2018 14:16:52 +0000 (10:16 -0400)
The trust router now builds, but the monitoring parser tests do not.

  * Eliminate extra layer of auth callback when using tr_gss.c, services
    using it now need only one auth callback
  * Document tr_gss.c's intended usage
  * Flesh out the MONS_INSTANCE structure
  * Fix a couple more pedantic data typing errors

common/tr_gss.c
include/mon_internal.h
include/tr_gss.h
include/trust_router/tid.h
mon/mons.c
tid/tids.c
tr/tr_tid.c

index 495f8f8..39a13a9 100644 (file)
 #include <gsscon.h>
 #include <tr_gss.h>
 
+/**
+ * tr_gss.c - GSS connection handler
+ *
+ * The chief entry point to this module is tr_gss_handle_connection(). This
+ * function accepts an incoming socket connection, runs the GSS authorization
+ * and authentication process, accepts a request, processes it, then sends
+ * the reply and returns without closing the connection.
+ *
+ * Callers need to provide two callbacks, each with a cookie for passing
+ * custom data to the callback.
+ *
+ *   * TR_GSS_AUTH_FN auth_cb: Authorization callback
+ *     - This callback is used during the GSS auth process to determine whether
+ *       a credential should be authorized to connect.
+ *
+ *   * TR_GSS_HANDLE_REQ_FN req_cb: Request handler callback
+ *     - After auth, this callback is passed the string form of the incoming request.
+ *       It should process the request and return a string form of the outgoing
+ *       response, if any.
+ */
+
+typedef struct tr_gss_cookie {
+  TR_GSS_AUTH_FN *auth_cb;
+  void *auth_cookie;
+} TR_GSS_COOKIE;
+
+static int tr_gss_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void *data)
+{
+  TR_GSS_COOKIE *cookie = talloc_get_type_abort(data, TR_GSS_COOKIE);
+  TR_NAME name ={(char *) displayName->value, (int) displayName->length};
+  int result=0;
+
+  if (cookie->auth_cb(clientName, &name, cookie->auth_cookie)) {
+    tr_debug("tr_gss_auth_cb: client '%.*s' denied authorization.", name.len, name.buf);
+    result=EACCES; /* denied */
+  }
+
+  return result;
+}
+
 
 /**
- * Callback to handle GSS authentication and authorization
+ * Handle GSS authentication and authorization
  *
  * @param conn connection file descriptor
  * @param acceptor_name name of acceptor to present to initiator
@@ -63,6 +103,7 @@ static int tr_gss_auth_connection(int conn,
   int rc = 0;
   int auth, autherr = 0;
   gss_buffer_desc nameBuffer = {0, NULL};
+  TR_GSS_COOKIE *cookie = NULL;
 
   nameBuffer.value = talloc_asprintf(NULL, "%s@%s", acceptor_name, acceptor_realm);
   if (nameBuffer.value == NULL) {
@@ -71,7 +112,16 @@ static int tr_gss_auth_connection(int conn,
   }
   nameBuffer.length = strlen(nameBuffer.value);
 
-  rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, auth_cb, auth_cookie);
+  /* Set up for the auth callback. There are two layers of callbacks here: we
+   * use our own, which handles gsscon interfacing and calls the auth_cb parameter
+   * to do the actual auth. Store the auth_cb information in a metacookie. */
+  cookie = talloc(NULL, TR_GSS_COOKIE);
+  cookie->auth_cb=auth_cb;
+  cookie->auth_cookie=auth_cookie;
+
+  /* Now call gsscon with *our* auth callback and cookie */
+  rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, tr_gss_auth_cb, cookie);
+  talloc_free(cookie);
   talloc_free(nameBuffer.value);
   if (rc) {
     tr_debug("tr_gss_auth_connection: Error from gsscon_passive_authenticate(), rc = %d.", rc);
index f49889a..db9d1b4 100644 (file)
@@ -119,8 +119,11 @@ struct mon_resp {
 
 /* Monitoring server instance */
 struct mons_instance {
+  char *hostname;
   unsigned int port;
   TR_GSS_NAMES *authorized_gss_names;
+  TIDS_INSTANCE *tids;
+  TRPS_INSTANCE *trps;
   MONS_REQ_FUNC *req_handler;
   MONS_AUTH_FUNC *auth_handler;
   void *cookie;
@@ -161,5 +164,6 @@ json_t *mon_resp_encode(MON_RESP *resp);
 MONS_INSTANCE *mons_new(TALLOC_CTX *mem_ctx);
 int mons_get_listener(MONS_INSTANCE *mons, MONS_REQ_FUNC *req_handler, MONS_AUTH_FUNC *auth_handler, unsigned int port,
                       void *cookie, int *fd_out, size_t max_fd);
+int mons_accept(MONS_INSTANCE *mons, int listen);
 
 #endif //TRUST_ROUTER_MON_REQ_H
index 9cd378e..30abc6d 100644 (file)
@@ -37,7 +37,7 @@
 
 #include <tr_msg.h>
 
-typedef int (TR_GSS_AUTH_FN)(gss_name_t, gss_buffer_t, void *);
+typedef int (TR_GSS_AUTH_FN)(gss_name_t, TR_NAME *, void *);
 typedef char *(TR_GSS_HANDLE_REQ_FN)(TALLOC_CTX *, const char *, void *);
 
 void tr_gss_handle_connection(int conn, const char *acceptor_name, const char *acceptor_realm, TR_GSS_AUTH_FN auth_cb,
index f442af5..91a9816 100644 (file)
@@ -44,6 +44,7 @@
 #include <trust_router/tr_versioning.h>
 
 #include <gssapi.h>
+#include <poll.h>
 
 
 #define TID_PORT       12309
@@ -156,9 +157,9 @@ TR_EXPORT TIDS_INSTANCE *tids_create (void);
 TR_EXPORT int tids_start (TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler,
                           tids_auth_func *auth_handler, const char *hostname,
                           unsigned int port, void *cookie);
-TR_EXPORT int tids_get_listener (TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler,
-                                 tids_auth_func *auth_handler, const char *hostname,
-                                 unsigned int port, void *cookie, int *fd_out, size_t max_fd);
+TR_EXPORT nfds_t tids_get_listener(TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler,
+                                   tids_auth_func *auth_handler, const char *hostname,
+                                   unsigned int port, void *cookie, int *fd_out, size_t max_fd);
 TR_EXPORT int tids_accept(TIDS_INSTANCE *tids, int listen);
 TR_EXPORT int tids_send_response (TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp);
 TR_EXPORT int tids_send_err_response (TIDS_INSTANCE *tids, TID_REQ *req, const char *err_msg);
index 29f405b..31ecb15 100644 (file)
@@ -42,6 +42,7 @@
 #include <mon_internal.h>
 #include <tr_socket.h>
 #include <sys/wait.h>
+#include <tr_gss.h>
 
 /**
  * Allocate a new MONS_INSTANCE
@@ -149,7 +150,11 @@ int mons_accept(MONS_INSTANCE *mons, int listen)
 
   if (pid == 0) {
     close(listen);
-    mons_handle_connection(mons, conn);
+    tr_gss_handle_connection(conn,
+                             "trustmonitor", mons->hostname, /* acceptor name */
+                             mons->auth_handler, mons->cookie, /* auth callback and cookie */
+                             mons_req_cb, mons /* req callback and cookie */
+    );
     close(conn);
     exit(0); /* exit to kill forked child process */
   } else {
index 3d37739..9e6f4d9 100644 (file)
@@ -86,22 +86,6 @@ cleanup:
   return resp;
 }
 
-/* returns EACCES if authorization is denied */
-static int tids_auth_cb(gss_name_t clientName, gss_buffer_t displayName,
-                       void *data)
-{
-  struct tids_instance *inst = (struct tids_instance *) data;
-  TR_NAME name ={(char *) displayName->value, (int) displayName->length};
-  int result=0;
-
-  if (0!=inst->auth_handler(clientName, &name, inst->cookie)) {
-    tr_debug("tids_auth_cb: client '%.*s' denied authorization.", name.len, name.buf);
-    result=EACCES; /* denied */
-  }
-
-  return result;
-}
-
 static int tids_handle_request(TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp)
 {
   int rc=-1;
@@ -337,14 +321,14 @@ TIDS_INSTANCE *tids_create(void)
 }
 /* Get a listener for tids requests, returns its socket fd. Accept
  * connections with tids_accept() */
-int tids_get_listener(TIDS_INSTANCE *tids,
-                      TIDS_REQ_FUNC *req_handler,
-                      tids_auth_func *auth_handler,
-                      const char *hostname,
-                      unsigned int port,
-                      void *cookie,
-                      int *fd_out,
-                      size_t max_fd)
+nfds_t tids_get_listener(TIDS_INSTANCE *tids,
+                         TIDS_REQ_FUNC *req_handler,
+                         tids_auth_func *auth_handler,
+                         const char *hostname,
+                         unsigned int port,
+                         void *cookie,
+                         int *fd_out,
+                         size_t max_fd)
 {
   nfds_t n_fd = 0;
   nfds_t ii = 0;
@@ -403,7 +387,7 @@ int tids_accept(TIDS_INSTANCE *tids, int listen)
     close(listen);
     tr_gss_handle_connection(conn,
                              "trustidentity", tids->hostname, /* acceptor name */
-                             tids_auth_cb, tids, /* auth callback and cookie */
+                             tids->auth_handler, tids->cookie, /* auth callback and cookie */
                              tids_req_cb, tids /* req callback and cookie */
     );
     close(conn);
@@ -431,7 +415,7 @@ int tids_start (TIDS_INSTANCE *tids,
   struct pollfd poll_fd[TR_MAX_SOCKETS]={{0}};
   int ii=0;
 
-  n_fd=tids_get_listener(tids, req_handler, auth_handler, hostname, port, cookie, fd, TR_MAX_SOCKETS);
+  n_fd = tids_get_listener(tids, req_handler, auth_handler, hostname, port, cookie, fd, TR_MAX_SOCKETS);
   if (n_fd <= 0) {
     perror ("Error from tids_listen()");
     return 1;
index 464ebd4..6cd0eb5 100644 (file)
@@ -698,14 +698,14 @@ int tr_tids_event_init(struct event_base *base,
   talloc_steal(tids, cookie);
 
   /* get a tids listener */
-  tids_ev->n_sock_fd = tids_get_listener(tids,
-                                         tr_tids_req_handler,
-                                         tr_tids_gss_handler,
-                                         cfg_mgr->active->internal->hostname,
-                                         cfg_mgr->active->internal->tids_port,
-                                         (void *)cookie,
-                                         tids_ev->sock_fd,
-                                         TR_MAX_SOCKETS);
+  tids_ev->n_sock_fd = (int)tids_get_listener(tids,
+                                              tr_tids_req_handler,
+                                              tr_tids_gss_handler,
+                                              cfg_mgr->active->internal->hostname,
+                                              cfg_mgr->active->internal->tids_port,
+                                              (void *)cookie,
+                                              tids_ev->sock_fd,
+                                              TR_MAX_SOCKETS);
   if (tids_ev->n_sock_fd==0) {
     tr_crit("Error opening TID server socket.");
     retval=1;