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;
/* 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;
+}
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);
GeneralSSLError
HostNotFound
ResolverError
+NoClientCertificate
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
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 *
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)
{
ssl_accept,
ssl_close,
ssl_read,
- ssl_write
+ ssl_write,
+ ssl_get_peer,
};