forked from mirrors/kore
Improvements for client certificates.
Double check we actually get a certificate if we are asking for one. Even though we set SSL_VERIFY_FAIL_IF_NO_PEER_CERT it's a sane thing to do. Start logging the CN for the received client certificate in the access logs. As a bonus re-arrange some accesslog stuff for sanity.
This commit is contained in:
parent
75c4bb0754
commit
1375190936
|
@ -66,6 +66,12 @@
|
||||||
#define NETBUF_CALL_CB_ALWAYS 0x01
|
#define NETBUF_CALL_CB_ALWAYS 0x01
|
||||||
#define NETBUF_FORCE_REMOVE 0x02
|
#define NETBUF_FORCE_REMOVE 0x02
|
||||||
|
|
||||||
|
#define X509_GET_CN(c, o, l) \
|
||||||
|
X509_NAME_get_text_by_NID(X509_get_subject_name(c), \
|
||||||
|
NID_commonName, o, l)
|
||||||
|
|
||||||
|
#define X509_CN_LENGTH (ub_common_name + 1)
|
||||||
|
|
||||||
/* XXX hackish. */
|
/* XXX hackish. */
|
||||||
struct http_request;
|
struct http_request;
|
||||||
struct spdy_stream;
|
struct spdy_stream;
|
||||||
|
@ -135,6 +141,7 @@ struct connection {
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
u_int8_t flags;
|
u_int8_t flags;
|
||||||
void *hdlr_extra;
|
void *hdlr_extra;
|
||||||
|
X509 *cert;
|
||||||
|
|
||||||
u_int8_t addrtype;
|
u_int8_t addrtype;
|
||||||
union {
|
union {
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct kore_log_packet {
|
||||||
char host[KORE_DOMAINNAME_LEN];
|
char host[KORE_DOMAINNAME_LEN];
|
||||||
char path[HTTP_URI_LEN];
|
char path[HTTP_URI_LEN];
|
||||||
char agent[HTTP_USERAGENT_LEN];
|
char agent[HTTP_USERAGENT_LEN];
|
||||||
|
char cn[X509_CN_LENGTH];
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -55,13 +56,12 @@ kore_accesslog_wait(void)
|
||||||
{
|
{
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
time_t now;
|
time_t now;
|
||||||
size_t slen;
|
|
||||||
int nfds;
|
|
||||||
struct kore_domain *dom;
|
struct kore_domain *dom;
|
||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
|
int nfds, l;
|
||||||
struct kore_log_packet logpacket;
|
struct kore_log_packet logpacket;
|
||||||
char addr[INET6_ADDRSTRLEN];
|
char addr[INET6_ADDRSTRLEN];
|
||||||
char *method, buf[4096], *tbuf;
|
char *method, *buf, *tbuf, *cn;
|
||||||
|
|
||||||
pfd[0].fd = accesslog_fd[0];
|
pfd[0].fd = accesslog_fd[0];
|
||||||
pfd[0].events = POLLIN;
|
pfd[0].events = POLLIN;
|
||||||
|
@ -94,10 +94,22 @@ kore_accesslog_wait(void)
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logpacket.method == HTTP_METHOD_GET)
|
switch (logpacket.method) {
|
||||||
|
case HTTP_METHOD_GET:
|
||||||
method = "GET";
|
method = "GET";
|
||||||
else
|
break;
|
||||||
|
case HTTP_METHOD_POST:
|
||||||
method = "POST";
|
method = "POST";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
method = "UNKNOWN";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logpacket.cn[0] != '\0')
|
||||||
|
cn = logpacket.cn;
|
||||||
|
else
|
||||||
|
cn = "none";
|
||||||
|
|
||||||
if (inet_ntop(logpacket.addrtype, &(logpacket.addr),
|
if (inet_ntop(logpacket.addrtype, &(logpacket.addr),
|
||||||
addr, sizeof(addr)) == NULL)
|
addr, sizeof(addr)) == NULL)
|
||||||
|
@ -105,20 +117,25 @@ kore_accesslog_wait(void)
|
||||||
|
|
||||||
time(&now);
|
time(&now);
|
||||||
tbuf = kore_time_to_date(now);
|
tbuf = kore_time_to_date(now);
|
||||||
snprintf(buf, sizeof(buf), "[%s] %s %d %s %s (w#%d) (%dms) (%s)\n",
|
l = asprintf(&buf, "[%s] %s %d %s %s (w#%d) (%dms) (%s) (%s)\n",
|
||||||
tbuf, addr, logpacket.status, method,
|
tbuf, addr, logpacket.status, method, logpacket.path,
|
||||||
logpacket.path, logpacket.worker_id, logpacket.time_req,
|
logpacket.worker_id, logpacket.time_req, cn, logpacket.agent);
|
||||||
logpacket.agent);
|
if (l == -1) {
|
||||||
slen = strlen(buf);
|
kore_log(LOG_WARNING,
|
||||||
|
"kore_accesslog_wait(): asprintf() == -1");
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = write(dom->accesslog, buf, l);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
len = write(dom->accesslog, buf, slen);
|
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
kore_log(LOG_WARNING,
|
kore_log(LOG_WARNING,
|
||||||
"kore_accesslog_wait(): write(): %s", errno_s);
|
"kore_accesslog_wait(): write(): %s", errno_s);
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size_t)len != slen)
|
if (len != l)
|
||||||
kore_log(LOG_NOTICE, "accesslog: %s", buf);
|
kore_log(LOG_NOTICE, "accesslog: %s", buf);
|
||||||
|
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
|
@ -157,6 +174,14 @@ kore_accesslog(struct http_request *req)
|
||||||
sizeof(logpacket.agent));
|
sizeof(logpacket.agent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(logpacket.cn, '\0', sizeof(logpacket.cn));
|
||||||
|
if (req->owner->cert != NULL) {
|
||||||
|
if (X509_GET_CN(req->owner->cert,
|
||||||
|
logpacket.cn, sizeof(logpacket.cn)) == -1) {
|
||||||
|
kore_log(LOG_WARNING, "client cert without a CN?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
len = send(accesslog_fd[1], &logpacket, sizeof(logpacket), 0);
|
len = send(accesslog_fd[1], &logpacket, sizeof(logpacket), 0);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
kore_log(LOG_WARNING, "kore_accesslog(): send(): %s", errno_s);
|
kore_log(LOG_WARNING, "kore_accesslog(): send(): %s", errno_s);
|
||||||
|
|
|
@ -70,6 +70,7 @@ kore_connection_accept(struct listener *l, struct connection **out)
|
||||||
c->owner = l;
|
c->owner = l;
|
||||||
c->ssl = NULL;
|
c->ssl = NULL;
|
||||||
c->flags = 0;
|
c->flags = 0;
|
||||||
|
c->cert = NULL;
|
||||||
c->hdlr_extra = NULL;
|
c->hdlr_extra = NULL;
|
||||||
c->inflate_started = 0;
|
c->inflate_started = 0;
|
||||||
c->deflate_started = 0;
|
c->deflate_started = 0;
|
||||||
|
@ -108,6 +109,7 @@ kore_connection_handle(struct connection *c)
|
||||||
int r;
|
int r;
|
||||||
u_int32_t len;
|
u_int32_t len;
|
||||||
const u_char *data;
|
const u_char *data;
|
||||||
|
char cn[X509_CN_LENGTH];
|
||||||
|
|
||||||
kore_debug("kore_connection_handle(%p)", c);
|
kore_debug("kore_connection_handle(%p)", c);
|
||||||
|
|
||||||
|
@ -139,6 +141,21 @@ kore_connection_handle(struct connection *c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SSL_get_verify_mode(c->ssl) & SSL_VERIFY_PEER) {
|
||||||
|
c->cert = SSL_get_peer_certificate(c->ssl);
|
||||||
|
if (c->cert == NULL) {
|
||||||
|
kore_log(LOG_NOTICE,
|
||||||
|
"no client certificate presented?");
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (X509_GET_CN(c->cert, cn, sizeof(cn)) == -1) {
|
||||||
|
kore_log(LOG_NOTICE,
|
||||||
|
"no CN found in client certificate");
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r = SSL_get_verify_result(c->ssl);
|
r = SSL_get_verify_result(c->ssl);
|
||||||
if (r != X509_V_OK) {
|
if (r != X509_V_OK) {
|
||||||
kore_debug("SSL_get_verify_result(): %d, %s",
|
kore_debug("SSL_get_verify_result(): %d, %s",
|
||||||
|
@ -219,6 +236,9 @@ kore_connection_remove(struct connection *c)
|
||||||
SSL_free(c->ssl);
|
SSL_free(c->ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->cert != NULL)
|
||||||
|
X509_free(c->cert);
|
||||||
|
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
|
|
||||||
if (c->hdlr_extra != NULL)
|
if (c->hdlr_extra != NULL)
|
||||||
|
|
Loading…
Reference in New Issue