#endif
void microhttpd_logger(void *arg, const char *fmt, va_list ap) {
- _cleanup_free_ char *f = NULL;
+ char *f;
- if (asprintf(&f, "microhttpd: %s", fmt) <= 0) {
- log_oom();
- return;
- }
+ f = strappenda("microhttpd: ", fmt);
DISABLE_WARNING_FORMAT_NONLITERAL;
log_metav(LOG_INFO, NULL, 0, NULL, f, ap);
}
-int respond_oom_internal(struct MHD_Connection *connection) {
- const char *m = "Out of memory.\n";
-
+static int mhd_respond_internal(struct MHD_Connection *connection,
+ enum MHD_RequestTerminationCode code,
+ char *buffer,
+ size_t size,
+ enum MHD_ResponseMemoryMode mode) {
struct MHD_Response *response;
- int ret;
+ int r;
assert(connection);
- response = MHD_create_response_from_buffer(strlen(m), (char*) m, MHD_RESPMEM_PERSISTENT);
+ response = MHD_create_response_from_buffer(size, buffer, mode);
if (!response)
return MHD_NO;
+ log_debug("Queing response %u: %s", code, buffer);
MHD_add_response_header(response, "Content-Type", "text/plain");
- ret = MHD_queue_response(connection, MHD_HTTP_SERVICE_UNAVAILABLE, response);
+ r = MHD_queue_response(connection, code, response);
MHD_destroy_response(response);
- return ret;
+ return r;
+}
+
+int mhd_respond(struct MHD_Connection *connection,
+ enum MHD_RequestTerminationCode code,
+ const char *message) {
+
+ return mhd_respond_internal(connection, code,
+ (char*) message, strlen(message),
+ MHD_RESPMEM_PERSISTENT);
}
-_printf_(3,4)
-int respond_error(struct MHD_Connection *connection,
- unsigned code,
- const char *format, ...) {
+int mhd_respond_oom(struct MHD_Connection *connection) {
+ return mhd_respond(connection, MHD_HTTP_SERVICE_UNAVAILABLE, "Out of memory.\n");
+}
+
+int mhd_respondf(struct MHD_Connection *connection,
+ enum MHD_RequestTerminationCode code,
+ const char *format, ...) {
- struct MHD_Response *response;
char *m;
int r;
va_list ap;
if (r < 0)
return respond_oom(connection);
- response = MHD_create_response_from_buffer(strlen(m), m, MHD_RESPMEM_MUST_FREE);
- if (!response) {
- free(m);
- return respond_oom(connection);
- }
-
- log_debug("Queing response %u: %s", code, m);
- MHD_add_response_header(response, "Content-Type", "text/plain");
- r = MHD_queue_response(connection, code, response);
- MHD_destroy_response(response);
-
- return r;
+ return mhd_respond_internal(connection, code, m, r, MHD_RESPMEM_MUST_FREE);
}
#ifdef HAVE_GNUTLS
if (0 <= level && level < (int) ELEMENTSOF(log_level_map))
ourlevel = log_level_map[level];
else
- level = LOG_DEBUG;
+ ourlevel = LOG_DEBUG;
log_meta(ourlevel, NULL, 0, NULL, "gnutls: %s", message);
}
const union MHD_ConnectionInfo *ci;
gnutls_session_t session;
gnutls_x509_crt_t client_cert;
- char _cleanup_free_ *buf = NULL;
+ _cleanup_free_ char *buf = NULL;
int r;
assert(connection);
MHD_CONNECTION_INFO_GNUTLS_SESSION);
if (!ci) {
log_error("MHD_get_connection_info failed: session is unencrypted");
- *code = respond_error(connection, MHD_HTTP_FORBIDDEN,
- "Encrypted connection is required");
+ *code = mhd_respond(connection, MHD_HTTP_FORBIDDEN,
+ "Encrypted connection is required");
return -EPERM;
}
session = ci->tls_session;
r = get_client_cert(session, &client_cert);
if (r < 0) {
- *code = respond_error(connection, MHD_HTTP_UNAUTHORIZED,
- "Authorization through certificate is required");
+ *code = mhd_respond(connection, MHD_HTTP_UNAUTHORIZED,
+ "Authorization through certificate is required");
return -EPERM;
}
r = get_auth_dn(client_cert, &buf);
if (r < 0) {
- *code = respond_error(connection, MHD_HTTP_UNAUTHORIZED,
- "Failed to determine distinguished name from certificate");
+ *code = mhd_respond(connection, MHD_HTTP_UNAUTHORIZED,
+ "Failed to determine distinguished name from certificate");
return -EPERM;
}
- log_info("Connection from DN %s", buf);
+ log_info("Connection from %s", buf);
r = verify_cert_authorized(session);
if (r < 0) {
log_warning("Client is not authorized");
- *code = respond_error(connection, MHD_HTTP_UNAUTHORIZED,
- "Client certificate not signed by recognized authority");
+ *code = mhd_respond(connection, MHD_HTTP_UNAUTHORIZED,
+ "Client certificate not signed by recognized authority");
}
return r;
}