Iterate over (potentially) multiple available authentication methods
authorDaniel Kouřil <kouril@ics.muni.cz>
Tue, 17 Jan 2012 20:12:55 +0000 (20:12 +0000)
committerDaniel Kouřil <kouril@ics.muni.cz>
Tue, 17 Jan 2012 20:12:55 +0000 (20:12 +0000)
- some cleanup of the authN "object" methods

emi.canl.canl-c/src/canl.c
emi.canl.canl-c/src/canl_locl.h
emi.canl.canl-c/src/canl_ssl.c

index bb7b299..0d1a380 100644 (file)
@@ -90,6 +90,8 @@ canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *s
     int addr_types[] = {AF_INET, AF_INET6}; //TODO ip versions policy?
     int ipver = AF_INET6;
     int j = 0;
+    struct canl_mech *mech;
+    gss_OID oid;
 
     memset(&ar, 0, sizeof(ar));
 
@@ -101,10 +103,6 @@ canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *s
         return set_error(glb_cc, EINVAL, posix_error, 
                 "IO handler not initialized");
 
-    err = ssl_client_init(glb_cc, glb_cc->ssl_ctx, (void **) &io_cc->s_ctx->ssl_io);
-    if (err)
-       return err;
-
     for (j = 0; j< sizeof(addr_types)/sizeof(*addr_types); j++) {
         ipver = addr_types[j];
        if (ar.ent) {
@@ -135,16 +133,38 @@ canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *s
         }
 
        err = ECONNREFUSED;
-       for (i = 0; ar.ent->h_addr_list[i]; i++) {
-            err = try_connect(glb_cc, io_cc, ar.ent->h_addr_list[i], 
-                    ar.ent->h_addrtype, port, timeout);//TODO timeout
-           if (err)
-               continue;
-
-           err = ssl_connect(glb_cc, io_cc, timeout, host); //TODO timeout
-           if (err)
-               continue;
-        }
+       j = 0;
+       do {
+           if (auth_mechs == GSS_C_NO_OID_SET || auth_mechs->count == 0)
+               oid = GSS_C_NO_OID;
+           else
+               oid = &auth_mechs->elements[j];
+
+           mech = find_mech(oid);
+
+           for (i = 0; ar.ent->h_addr_list[i]; i++) {
+               void *ctx = NULL;
+
+               err = try_connect(glb_cc, io_cc, ar.ent->h_addr_list[i], 
+                       ar.ent->h_addrtype, port, timeout);//TODO timeout
+               if (err)
+                   continue;
+
+               err = mech->client_init(glb_cc, mech->global_context, &ctx);
+               if (err)
+                   continue;
+
+               err = mech->connect(glb_cc, io_cc, mech->global_context,
+                                   ctx, timeout, host); //TODO timeout
+               if (err) {
+                   mech->free_ctx(glb_cc, ctx);
+                   continue;
+               }
+               io_cc->authn_mech.ctx = ctx;
+               io_cc->authn_mech.type = mech->mech;
+           }
+           j++;
+       } while (auth_mechs != GSS_C_NO_OID_SET && j < auth_mechs->count);
 
         free_hostent(ar.ent);
         ar.ent = NULL;
@@ -408,3 +428,10 @@ int canl_set_ctx_own_cert_file(canl_ctx cc, char *cert, char *key,
         return err;
 }
 #endif
+
+struct canl_mech *
+find_mech(gss_OID oid)
+{
+    /* XXX */
+    return &canl_mech_ssl;
+}
index 334b1d9..3cec90b 100644 (file)
@@ -105,33 +105,36 @@ typedef struct canl_mech {
         (glb_ctx *, void **);
 
     canl_err_code (*finish)
-       (void *);
+       (glb_ctx *, void *);
 
     canl_err_code (*client_init)
-        (glb_ctx *, void **);
+        (glb_ctx *, void *, void **);
 
     canl_err_code (*server_init)
-        (glb_ctx *, void **);
+        (glb_ctx *, void *, void **);
 
     canl_err_code (*free_ctx)
        (glb_ctx *, void *);
 
     canl_err_code (*connect)
-        (glb_ctx *, void *, io_handler *, struct timeval *, const char *);
+        (glb_ctx *, io_handler *, void *, void *, struct timeval *, const char *);
 
     canl_err_code (*accept)
-        (glb_ctx *, void *, io_handler *, struct timeval *);
+        (glb_ctx *, io_handler *, void *, void *, struct timeval *);
 
     canl_err_code (*close)
-        (glb_ctx *, void *, io_handler *);
+        (glb_ctx *, io_handler *, void *);
 
     canl_err_code (*read)
-        (glb_ctx *, void *, io_handler *, void *, size_t, struct timeval *);
+        (glb_ctx *, io_handler *, void *, size_t, struct timeval *);
 
     canl_err_code (*write)
         (glb_ctx *, void *, io_handler *, void *, size_t, struct timeval *);
 } canl_mech;
 
+struct canl_mech *
+find_mech(gss_OID oid);
+
 extern struct canl_mech canl_mech_ssl;
 
 void reset_error (glb_ctx *cc, unsigned long err_code);
index 9ebd095..bde33b6 100644 (file)
@@ -210,8 +210,11 @@ int ssl_client_init(glb_ctx *cc, void *mech_ctx, void **ctx)
     return 0;
 }
 
-int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout, const char * host)
+int ssl_connect(glb_ctx *cc, io_handler *io, void *mech_ctx, void *auth_ctx,
+               struct timeval *timeout, const char * host)
 {
+    SSL_ctx *ctx = (SSL_ctx *) mech_ctx;
+    SSL *ssl = (SSL *) auth_ctx;
     int err = 0, flags;
 
     if (!cc) {
@@ -226,7 +229,7 @@ int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout, const char
     (void)fcntl(io->sock, F_SETFL, flags | O_NONBLOCK);
 
     //setup_SSL_proxy_handler(cc->ssl_ctx, cacertdir);
-    SSL_set_fd(io->s_ctx->ssl_io, io->sock);
+    SSL_set_fd(ssl, io->sock);
 
     err = do_ssl_connect(cc, io, timeout); 
     if (err) {
@@ -318,9 +321,11 @@ end:
     }
 }
 
-int ssl_accept(glb_ctx *cc, io_handler *io,
+int ssl_accept(glb_ctx *cc, io_handler *io, void *mech_ctx, void *auth_ctx,
         struct timeval *timeout)
 {
+    SSL_ctx *ctx = (SSL_ctx *) mech_ctx;
+    SSL *ssl = (SSL *) auth_ctx;
     int err = 0, flags;
 
     if (!cc) {
@@ -667,8 +672,10 @@ int ssl_read(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct time
  * ret = 0 connection closed successfully (one direction)
  * ret = 1 connection closed successfully (both directions)
  * ret < 0 error occured (e.g. timeout reached) */
-int ssl_close(glb_ctx *cc, io_handler *io)
+int ssl_close(glb_ctx *cc, io_handler *io, void *auth_ctx)
 {
+    SSL_ctx *ctx = (SSL_ctx *) mech_ctx;
+    SSL *ssl = (SSL *) auth_ctx;
     int timeout = DESTROY_TIMEOUT;
     time_t starttime, curtime;
     int expected = 0, error = 0, ret = 0, ret2 = 0;