[mod_gnutls] use key-value list for parameters, allows duplicate listen/pemfile parameters

personal/stbuehler/wip
Stefan Bühler 9 years ago
parent 969818083e
commit c372d21f2c
  1. 161
      src/modules/mod_gnutls.c

@ -570,17 +570,17 @@ static void gnutls_setup_listen_cb(liServer *srv, int fd, gpointer data) {
static gboolean gnutls_setup(liServer *srv, liPlugin* p, liValue *val, gpointer userdata) {
mod_context *ctx;
GHashTableIter hti;
gpointer hkey, hvalue;
GString *htkey;
liValue *htval;
int r;
guint i;
/* setup defaults */
GString *ipstr = NULL;
gboolean have_listen_parameter = FALSE;
gboolean have_pemfile_parameter = FALSE;
gboolean have_protect_beast_parameter = FALSE;
gboolean have_session_db_size_parameter = FALSE;
const char
*priority = NULL, *dh_params_file = NULL,
*pemfile = NULL, *ca_file = NULL
*ca_file = NULL
#ifdef USE_SNI
,*sni_backend = NULL, *sni_fallback_pemfile = NULL
#endif
@ -591,90 +591,127 @@ static gboolean gnutls_setup(liServer *srv, liPlugin* p, liValue *val, gpointer
UNUSED(p); UNUSED(userdata);
if (val->type != LI_VALUE_HASH) {
ERROR(srv, "%s", "gnutls expects a hash as parameter");
if (NULL == (val = li_value_to_key_value_list(val))) {
ERROR(srv, "%s", "gnutls expects a hash/key-value list as parameter");
return FALSE;
}
g_hash_table_iter_init(&hti, val->data.hash);
while (g_hash_table_iter_next(&hti, &hkey, &hvalue)) {
htkey = hkey; htval = hvalue;
for (i = 0; i < val->data.list->len; ++i) {
liValue *entryKey = g_array_index(g_array_index(val->data.list, liValue*, i)->data.list, liValue*, 0);
liValue *entryValue = g_array_index(g_array_index(val->data.list, liValue*, i)->data.list, liValue*, 1);
GString *entryKeyStr;
if (g_str_equal(htkey->str, "listen")) {
if (htval->type != LI_VALUE_STRING) {
if (entryKey->type == LI_VALUE_NONE) {
ERROR(srv, "%s", "gnutls doesn't take null keys");
return FALSE;
}
entryKeyStr = entryKey->data.string; /* keys are either NONE or STRING */
if (g_str_equal(entryKeyStr->str, "listen")) {
if (entryValue->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "gnutls listen expects a string as parameter");
return FALSE;
}
ipstr = htval->data.string;
} else if (g_str_equal(htkey->str, "pemfile")) {
if (htval->type != LI_VALUE_STRING) {
have_listen_parameter = TRUE;
} else if (g_str_equal(entryKeyStr->str, "pemfile")) {
if (entryValue->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "gnutls pemfile expects a string as parameter");
return FALSE;
}
pemfile = htval->data.string->str;
} else if (g_str_equal(htkey->str, "dh-params")) {
if (htval->type != LI_VALUE_STRING) {
have_pemfile_parameter = TRUE;
} else if (g_str_equal(entryKeyStr->str, "dh-params")) {
if (entryValue->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "gnutls dh-params expects a string as parameter");
return FALSE;
}
dh_params_file = htval->data.string->str;
} else if (g_str_equal(htkey->str, "ca-file")) {
if (htval->type != LI_VALUE_STRING) {
if (NULL != dh_params_file) {
ERROR(srv, "gnutls unexpected duplicate parameter %s", entryKeyStr->str);
return FALSE;
}
dh_params_file = entryValue->data.string->str;
} else if (g_str_equal(entryKeyStr->str, "ca-file")) {
if (entryValue->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "gnutls ca-file expects a string as parameter");
return FALSE;
}
ca_file = htval->data.string->str;
} else if (g_str_equal(htkey->str, "priority")) {
if (htval->type != LI_VALUE_STRING) {
if (NULL != ca_file) {
ERROR(srv, "gnutls unexpected duplicate parameter %s", entryKeyStr->str);
return FALSE;
}
ca_file = entryValue->data.string->str;
} else if (g_str_equal(entryKeyStr->str, "priority")) {
if (entryValue->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "gnutls priority expects a string as parameter");
return FALSE;
}
priority = htval->data.string->str;
} else if (g_str_equal(htkey->str, "protect-against-beast")) {
if (htval->type != LI_VALUE_BOOLEAN) {
if (NULL != priority) {
ERROR(srv, "gnutls unexpected duplicate parameter %s", entryKeyStr->str);
return FALSE;
}
priority = entryValue->data.string->str;
} else if (g_str_equal(entryKeyStr->str, "protect-against-beast")) {
if (entryValue->type != LI_VALUE_BOOLEAN) {
ERROR(srv, "%s", "gnutls protect-against-beast expects a boolean as parameter");
return FALSE;
}
protect_against_beast = htval->data.boolean;
} else if (g_str_equal(htkey->str, "session-db-size")) {
if (htval->type != LI_VALUE_NUMBER) {
if (have_protect_beast_parameter) {
ERROR(srv, "gnutls unexpected duplicate parameter %s", entryKeyStr->str);
return FALSE;
}
have_protect_beast_parameter = TRUE;
protect_against_beast = entryValue->data.boolean;
} else if (g_str_equal(entryKeyStr->str, "session-db-size")) {
if (entryValue->type != LI_VALUE_NUMBER) {
ERROR(srv, "%s", "gnutls session-db-size expects an integer as parameter");
return FALSE;
}
session_db_size = htval->data.number;
if (have_session_db_size_parameter) {
ERROR(srv, "gnutls unexpected duplicate parameter %s", entryKeyStr->str);
return FALSE;
}
have_session_db_size_parameter = TRUE;
session_db_size = entryValue->data.number;
#ifdef USE_SNI
} else if (g_str_equal(htkey->str, "sni-backend")) {
if (htval->type != LI_VALUE_STRING) {
} else if (g_str_equal(entryKeyStr->str, "sni-backend")) {
if (entryValue->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "gnutls sni-backend expects a string as parameter");
return FALSE;
}
sni_backend = htval->data.string->str;
} else if (g_str_equal(htkey->str, "sni-fallback-pemfile")) {
if (htval->type != LI_VALUE_STRING) {
if (NULL != sni_backend) {
ERROR(srv, "gnutls unexpected duplicate parameter %s", entryKeyStr->str);
return FALSE;
}
sni_backend = entryValue->data.string->str;
} else if (g_str_equal(entryKeyStr->str, "sni-fallback-pemfile")) {
if (entryValue->type != LI_VALUE_STRING) {
ERROR(srv, "%s", "gnutls sni-fallback-pemfile expects a string as parameter");
return FALSE;
}
sni_fallback_pemfile = htval->data.string->str;
if (NULL != sni_fallback_pemfile) {
ERROR(srv, "gnutls unexpected duplicate parameter %s", entryKeyStr->str);
return FALSE;
}
sni_fallback_pemfile = entryValue->data.string->str;
#else
} else if (g_str_equal(htkey->str, "sni-backend")) {
} else if (g_str_equal(entryKeyStr->str, "sni-backend")) {
ERROR(srv, "%s", "mod_gnutls was build without SNI support, invalid option sni-backend");
return FALSE;
} else if (g_str_equal(htkey->str, "sni-fallback-pemfile")) {
} else if (g_str_equal(entryKeyStr->str, "sni-fallback-pemfile")) {
ERROR(srv, "%s", "mod_gnutls was build without SNI support, invalid option gnutls sni-fallback-pemfile");
return FALSE;
#endif
} else {
ERROR(srv, "invalid option for mod_gnutls: %s", htkey->str);
ERROR(srv, "invalid option for mod_gnutls: %s", entryKeyStr->str);
return FALSE;
}
}
if (!ipstr) {
if (!have_listen_parameter) {
ERROR(srv, "%s", "gnutls needs a listen parameter");
return FALSE;
}
if (!pemfile) {
if (!have_pemfile_parameter) {
ERROR(srv, "%s", "gnutls needs a pemfile");
return FALSE;
}
@ -711,11 +748,23 @@ static gboolean gnutls_setup(liServer *srv, liPlugin* p, liValue *val, gpointer
}
#endif
if (GNUTLS_E_SUCCESS != (r = gnutls_certificate_set_x509_key_file(ctx->server_cert, pemfile, pemfile, GNUTLS_X509_FMT_PEM))) {
ERROR(srv, "gnutls_certificate_set_x509_key_file failed(certfile '%s', keyfile '%s', PEM) (%s): %s",
pemfile, pemfile,
gnutls_strerror_name(r), gnutls_strerror(r));
goto error_free_ctx;
for (i = 0; i < val->data.list->len; ++i) {
liValue *entryKey = g_array_index(g_array_index(val->data.list, liValue*, i)->data.list, liValue*, 0);
liValue *entryValue = g_array_index(g_array_index(val->data.list, liValue*, i)->data.list, liValue*, 1);
GString *entryKeyStr;
if (entryKey->type == LI_VALUE_NONE) continue;
entryKeyStr = entryKey->data.string; /* keys are either NONE or STRING */
if (g_str_equal(entryKeyStr->str, "pemfile")) {
const char *pemfile = entryValue->data.string->str;
if (GNUTLS_E_SUCCESS != (r = gnutls_certificate_set_x509_key_file(ctx->server_cert, pemfile, pemfile, GNUTLS_X509_FMT_PEM))) {
ERROR(srv, "gnutls_certificate_set_x509_key_file failed(certfile '%s', keyfile '%s', PEM) (%s): %s",
pemfile, pemfile,
gnutls_strerror_name(r), gnutls_strerror(r));
goto error_free_ctx;
}
}
}
if (session_db_size > 0) ctx->session_db = li_ssl_session_db_new(session_db_size);
@ -799,7 +848,21 @@ static gboolean gnutls_setup(liServer *srv, liPlugin* p, liValue *val, gpointer
}
}
li_angel_listen(srv, ipstr, gnutls_setup_listen_cb, ctx);
for (i = 0; i < val->data.list->len; ++i) {
liValue *entryKey = g_array_index(g_array_index(val->data.list, liValue*, i)->data.list, liValue*, 0);
liValue *entryValue = g_array_index(g_array_index(val->data.list, liValue*, i)->data.list, liValue*, 1);
GString *entryKeyStr;
if (entryKey->type == LI_VALUE_NONE) continue;
entryKeyStr = entryKey->data.string; /* keys are either NONE or STRING */
if (g_str_equal(entryKeyStr->str, "listen")) {
mod_gnutls_context_acquire(ctx);
li_angel_listen(srv, entryValue->data.string, gnutls_setup_listen_cb, ctx);
}
}
mod_gnutls_context_release(ctx);
return TRUE;

Loading…
Cancel
Save