- return the client's description after successful authentication
authorDaniel Kouřil <kouril@ics.muni.cz>
Tue, 31 Jan 2012 13:44:21 +0000 (13:44 +0000)
committerDaniel Kouřil <kouril@ics.muni.cz>
Tue, 31 Jan 2012 13:44:21 +0000 (13:44 +0000)
- added routines to obtain principal's name and to free the structure

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

index ef66074..a09854c 100644 (file)
@@ -272,6 +272,12 @@ canl_io_accept(canl_ctx cc, canl_io_handler io, int new_fd,
     if (err)
        goto end;
 
+    if (peer) {
+       err = mech->get_peer(glb_cc, io_cc, conn_ctx, peer);
+       if (err)
+           goto end;
+    }
+
     io_cc->authn_mech.ctx = conn_ctx;
     io_cc->authn_mech.type = mech->mech;
     io_cc->authn_mech.oid = GSS_C_NO_OID;
@@ -472,3 +478,40 @@ find_mech(gss_OID oid)
     /* XXX */
     return &canl_mech_ssl;
 }
+
+canl_err_code 
+canl_princ_name(canl_ctx cc, const canl_principal princ, char **name)
+{
+    struct _principal_int *p = (struct _principal_int *) princ;
+
+    if (cc == NULL)
+       return -1;
+    if (princ == NULL)
+       return set_error(cc, EINVAL, POSIX_ERROR, "Principal not initialized");
+
+    if (name == NULL)
+       return set_error(cc, EINVAL, POSIX_ERROR, "invalid parameter value");
+
+    *name = strdup(p->name);
+    if (*name == NULL)
+       return set_error(cc, ENOMEM, POSIX_ERROR, "not enough memory");
+
+    return 0;
+}
+
+void
+canl_princ_free(canl_ctx cc, canl_principal princ)
+{
+    struct _principal_int *p = (struct _principal_int *) princ;
+
+    if (cc == NULL)
+       return;
+    if (princ == NULL)
+       return;
+
+    if (p->name)
+       free(p->name);
+    free(princ);
+
+    return;
+}
index 02ef8a3..5df93f7 100644 (file)
@@ -66,6 +66,9 @@ canl_princ_name(canl_ctx, const canl_principal, char **);
 canl_err_code CANL_CALLCONV
 canl_princ_mech(canl_ctx, const canl_principal, gss_OID *);
 
+void CANL_CALLCONV
+canl_princ_free(canl_ctx, canl_principal);
+
 char * CANL_CALLCONV
 canl_mech2str(canl_ctx, gss_OID);
 
index acaf883..7795b38 100644 (file)
@@ -103,3 +103,4 @@ trustPubKeyError
 GeneralSSLError
 HostNotFound
 ResolverError
+NoClientCertificate
index a15c61f..32c7e79 100644 (file)
@@ -74,8 +74,8 @@ typedef struct _asyn_result {
 
 typedef struct _principal_int {
     char *name;
-    CANL_AUTH_MECHANISM mech_oid;
-    char *raw;  /* e.g. the PEM encoded cert/chain */
+//    CANL_AUTH_MECHANISM mech_oid;
+//    char *raw;  /* e.g. the PEM encoded cert/chain */
 } principal_int;
 
 typedef struct _io_handler
@@ -122,6 +122,10 @@ typedef struct canl_mech {
 
     canl_err_code (*write)
         (glb_ctx *, io_handler *, void *, void *, size_t, struct timeval *);
+
+    canl_err_code (*get_peer)
+        (glb_ctx *, io_handler *, void *, canl_principal *);
+
 } canl_mech;
 
 struct canl_mech *
index 219df98..f69b1aa 100644 (file)
@@ -810,6 +810,44 @@ canl_ctx_set_ssl_cred(canl_ctx cc, char *cert, char *key,
     return err;
 }
 
+static canl_err_code
+ssl_get_peer(glb_ctx *cc, io_handler *io, void *auth_ctx, canl_principal *peer)
+{
+    struct _principal_int *princ;
+    SSL *ssl = (SSL *) auth_ctx;
+    X509 *cert = NULL;
+    X509_NAME *subject = NULL;
+    int ret;
+
+    if (peer == NULL)
+       return set_error(cc, EINVAL, POSIX_ERROR, "invalid parameter value");
+
+    cert = SSL_get_peer_certificate(ssl);
+    if (cert == NULL)
+       return set_error(cc, CANL_ERR_NoClientCertificate, CANL_ERROR, "No peer certificate");
+
+    princ = calloc(1, sizeof(*princ));
+    if (princ == NULL)
+       return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory");
+
+    subject = X509_get_subject_name(cert);
+    princ->name = strdup(X509_NAME_oneline(subject, NULL, 0));
+    if (princ->name == NULL) {
+       ret = set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory");
+       goto end;
+    }
+
+    *peer = princ;
+    princ = NULL;
+    ret = 0;
+
+end:
+    if (princ)
+       free(princ);
+
+    return ret;
+}
+
 #ifdef DEBUG
 static void dbg_print_ssl_error(int errorcode)
 {
@@ -861,5 +899,6 @@ struct canl_mech canl_mech_ssl = {
     ssl_accept,
     ssl_close,
     ssl_read,
-    ssl_write
+    ssl_write,
+    ssl_get_peer,
 };