};
/* Lock for reading and writing system_wide_config */
-GNUTLS_STATIC_RWLOCK(system_wide_config_rwlock);
+GNUTLS_RWLOCK(system_wide_config_rwlock);
static struct cfg system_wide_config;
static unsigned fail_on_invalid_config = 0;
return 1;
}
-static void _gnutls_update_system_priorities(void)
+static int _gnutls_update_system_priorities(void)
{
- int ret = 0;
+ int ret, err = 0;
struct stat sb;
FILE *fp;
- GNUTLS_STATIC_RWLOCK_RDLOCK(system_wide_config_rwlock);
+ ret = gnutls_rwlock_rdlock(&system_wide_config_rwlock);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
if (stat(system_priority_file, &sb) < 0) {
_gnutls_debug_log("cfg: unable to access: %s: %d\n",
system_priority_file, errno);
goto out;
}
- GNUTLS_STATIC_RWLOCK_UNLOCK(system_wide_config_rwlock);
+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock);
- GNUTLS_STATIC_RWLOCK_WRLOCK(system_wide_config_rwlock);
+ ret = gnutls_rwlock_wrlock(&system_wide_config_rwlock);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
/* Another thread has successfully updated the system wide config (with
* the same modification time as checked above), while upgrading to
system_priority_file, errno);
goto out;
}
- ret = ini_parse_file(fp, cfg_ini_handler, NULL);
+ err = ini_parse_file(fp, cfg_ini_handler, NULL);
fclose(fp);
- if (ret != 0) {
+ if (err) {
_gnutls_debug_log("cfg: unable to parse: %s: %d\n",
- system_priority_file, ret);
+ system_priority_file, err);
goto out;
}
system_priority_last_mod = sb.st_mtime;
out:
- GNUTLS_STATIC_RWLOCK_UNLOCK(system_wide_config_rwlock);
+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock);
- if (ret != 0 && fail_on_invalid_config) {
+ if (err && fail_on_invalid_config) {
exit(1);
}
+
+ return ret;
}
void _gnutls_load_system_priorities(void)
{
const char *p;
+ int ret;
p = secure_getenv("GNUTLS_SYSTEM_PRIORITY_FILE");
if (p != NULL)
if (p != NULL && p[0] == '1' && p[1] == 0)
fail_on_invalid_config = 1;
- _gnutls_update_system_priorities();
+ ret = _gnutls_update_system_priorities();
+ if (ret < 0) {
+ _gnutls_debug_log("failed to update system priorities: %s\n",
+ gnutls_strerror(ret));
+ }
}
void _gnutls_unload_system_priorities(void)
{
const char *p = priorities;
char *additional = NULL;
- char *ret = NULL;
+ char *resolved = NULL;
const char *ss, *ss_next;
unsigned ss_len, ss_next_len;
size_t n, n2 = 0;
+ int ret;
- while (c_isspace(*p))
+ while (c_isspace(*p)) {
p++;
+ }
- if (*p == '@') {
- ss = p+1;
- additional = strchr(ss, ':');
- if (additional != NULL) {
- additional++;
- }
+ /* Cannot reduce further. */
+ if (*p != '@') {
+ return gnutls_strdup(p);
+ }
- /* Always try to refresh the cached data, to
- * allow it to be updated without restarting
- * all applications
- */
- _gnutls_update_system_priorities();
-
- do {
- ss_next = strchr(ss, ',');
- if (ss_next != NULL) {
- if (additional && ss_next > additional)
- ss_next = NULL;
- else
- ss_next++;
- }
+ ss = p+1;
+ additional = strchr(ss, ':');
+ if (additional) {
+ additional++;
+ }
+
+ /* Always try to refresh the cached data, to allow it to be
+ * updated without restarting all applications.
+ */
+ ret = _gnutls_update_system_priorities();
+ if (ret < 0) {
+ _gnutls_debug_log("failed to update system priorities: %s\n",
+ gnutls_strerror(ret));
+ }
- if (ss_next) {
- ss_len = ss_next - ss - 1;
- ss_next_len = additional - ss_next - 1;
- } else if (additional) {
- ss_len = additional - ss - 1;
- ss_next_len = 0;
+ do {
+ ss_next = strchr(ss, ',');
+ if (ss_next) {
+ if (additional && ss_next > additional) {
+ ss_next = NULL;
} else {
- ss_len = strlen(ss);
- ss_next_len = 0;
+ ss_next++;
}
+ }
+
+ if (ss_next) {
+ ss_len = ss_next - ss - 1;
+ ss_next_len = additional - ss_next - 1;
+ } else if (additional) {
+ ss_len = additional - ss - 1;
+ ss_next_len = 0;
+ } else {
+ ss_len = strlen(ss);
+ ss_next_len = 0;
+ }
- GNUTLS_STATIC_RWLOCK_RDLOCK(system_wide_config_rwlock);
- p = _name_val_array_value(system_wide_config.priority_strings, ss, ss_len);
+ ret = gnutls_rwlock_rdlock(&system_wide_config_rwlock);
+ if (ret < 0) {
+ _gnutls_debug_log("cannot read system priority strings: %s\n",
+ gnutls_strerror(ret));
+ break;
+ }
- _gnutls_debug_log("resolved '%.*s' to '%s', next '%.*s'\n",
- ss_len, ss, S(p), ss_next_len, S(ss_next));
+ p = _name_val_array_value(system_wide_config.priority_strings,
+ ss, ss_len);
- if (p) {
- n = strlen(p);
- if (additional) {
- n2 = strlen(additional);
- }
+ _gnutls_debug_log("resolved '%.*s' to '%s', next '%.*s'\n",
+ ss_len, ss, S(p), ss_next_len, S(ss_next));
- ret = gnutls_malloc(n+n2+1+1);
- if (ret) {
- memcpy(ret, p, n);
- if (additional != NULL) {
- ret[n] = ':';
- memcpy(&ret[n+1], additional, n2);
- ret[n+n2+1] = 0;
- } else {
- ret[n] = 0;
- }
+ if (p) {
+ n = strlen(p);
+ if (additional) {
+ n2 = strlen(additional);
+ }
+
+ resolved = gnutls_malloc(n+n2+1+1);
+ if (resolved) {
+ memcpy(resolved, p, n);
+ if (additional) {
+ resolved[n] = ':';
+ memcpy(&resolved[n+1], additional, n2);
+ resolved[n+n2+1] = 0;
+ } else {
+ resolved[n] = 0;
}
}
- GNUTLS_STATIC_RWLOCK_UNLOCK(system_wide_config_rwlock);
+ }
- ss = ss_next;
- } while (ss && ret == NULL);
+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock);
- if (ret == NULL) {
- _gnutls_debug_log("unable to resolve %s\n", priorities);
- }
- } else {
- return gnutls_strdup(p);
- }
+ ss = ss_next;
+ } while (ss && !resolved);
- if (ret != NULL) {
- _gnutls_debug_log("selected priority string: %s\n", ret);
+ if (resolved) {
+ _gnutls_debug_log("selected priority string: %s\n", resolved);
+ } else {
+ _gnutls_debug_log("unable to resolve %s\n", priorities);
}
- return ret;
+ return resolved;
}
static void add_ec(gnutls_priority_t priority_cache)
/* The following requires a lock so there are no inconsistencies in the
* members of system_wide_config loaded from the config file. */
- GNUTLS_STATIC_RWLOCK_RDLOCK(system_wide_config_rwlock);
+ ret = gnutls_rwlock_rdlock(&system_wide_config_rwlock);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
/* disable key exchanges which are globally disabled */
z = 0;
}
out:
- GNUTLS_STATIC_RWLOCK_UNLOCK(system_wide_config_rwlock);
+ gnutls_rwlock_unlock(&system_wide_config_rwlock);
return ret;
}