/*
* Config file reader
*
* Copyright (C) 2007 Olaf Kirch <olaf.kirch@oracle.com>
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <libisns/isns.h>
#include <libisns/util.h>
#include <libisns/paths.h>
/*
* iSNS configuration
*/
struct isns_config isns_config = {
/* Security parameters */
.ic_security = -1,
.ic_auth_key_file = ISNS_ETCDIR "/auth_key",
.ic_server_key_file = ISNS_ETCDIR "/server_key.pub",
.ic_client_keystore = "DB:",
.ic_control_socket = ISNS_RUNDIR "/isnsctl",
.ic_pidfile = ISNS_RUNDIR "/isnsd.pid",
.ic_local_registry_file = ISNS_DEFAULT_LOCAL_REGISTRY,
.ic_control_name = "isns.control",
.ic_control_key_file = ISNS_ETCDIR "/control.key",
.ic_registration_period = 3600, /* 1 hour */
.ic_scn_timeout = 60,
.ic_scn_retries = 3,
.ic_esi_max_interval = 600, /* 10 minutes */
.ic_esi_min_interval = 60, /* 1 minute */
.ic_esi_retries = 3,
.ic_auth = {
.replay_window = 300, /* 5 min clock skew */
.timestamp_jitter = 1, /* 1 sec timestamp jitter */
.allow_unknown_peers = 1,
},
.ic_network = {
.max_sockets = 1024,
.connect_timeout = 5,
.reconnect_timeout = 10,
.call_timeout = 60,
.udp_retrans_timeout = 10,
.tcp_retrans_timeout = 60,
.idle_timeout = 300,
},
.ic_dsa = {
.param_file = ISNS_ETCDIR "/dsa.params",
},
};
/*
* Default string values need to be dup'ed,
* so that later assignment does't try to free
* these strings.
*/
static inline void
__isns_config_defaults(void)
{
static int defaults_init = 1;
if (!defaults_init)
return;
#define DUP(member) \
if (isns_config.member) \
isns_config.member = isns_strdup(isns_config.member)
DUP(ic_source_name);
DUP(ic_database);
DUP(ic_server_name);
DUP(ic_bind_address);
DUP(ic_auth_key_file);
DUP(ic_server_key_file);
DUP(ic_client_keystore);
DUP(ic_control_socket);
DUP(ic_pidfile);
DUP(ic_control_name);
DUP(ic_control_key_file);
DUP(ic_local_registry_file);
DUP(ic_dsa.param_file);
#undef DUP
defaults_init = 0;
}
/*
* read initiator name from supplied filename
*/
int
isns_read_initiatorname(const char *filename)
{
FILE *fp;
char *name, *pos;
if ((fp = fopen(filename, "r")) == NULL) {
perror(filename);
return -1;
}
while ((pos = parser_get_next_line(fp)) != NULL) {
pos[strcspn(pos, "#")] = '\0';
if (!(name = parser_get_next_word(&pos)))
continue;
if (strcmp(name, "InitiatorName"))
continue;
if (pos[0] == '=')
pos++;
if (!strncmp(pos, "iqn.", 4))
isns_assign_string(&isns_config.ic_source_name, pos);
}
fclose(fp);
return 0;
}
/*
* Read the iSNS configuration file
*/
int
isns_read_config(const char *filename)
{
FILE *fp;
char *name, *pos;
__isns_config_defaults();
if ((fp = fopen(filename, "r")) == NULL) {
perror(filename);
return -1;
}
while ((pos = parser_get_next_line(fp)) != NULL) {
pos[strcspn(pos, "#")] = '\0';
if (!(name = parser_get_next_word(&pos)))
continue;
isns_config_set(name, pos);
}
fclose(fp);
/* Massage the config file */
if (isns_config.ic_security < 0) {
/* By default, we will enable authentication
* whenever we find our private key, and
* the server's public key. */
if (access(isns_config.ic_auth_key_file, R_OK) == 0
&& access(isns_config.ic_server_key_file, R_OK) == 0)
isns_config.ic_security = 1;
else
isns_config.ic_security = 0;
}
return 0;
}
int
isns_config_set(const char *name, char *pos)
{
char *value;
value = parser_get_rest_of_line(&pos);
if (value)
while (isspace(*value) || *value == '=')
++value;
if (!strcasecmp(name, "HostName")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_host_name, value);
} else if (!strcasecmp(name, "SourceName")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_source_name, value);
} else if (!strcasecmp(name, "AuthName")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_auth_name, value);
} else if (!strcasecmp(name, "IQNPrefix")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_iqn_prefix, value);
} else if (!strcasecmp(name, "Database")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_database, value);
} else if (!strcasecmp(name, "ServerAddress")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_server_name, value);
} else if (!strcasecmp(name, "BindAddress")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_bind_address, value);
} else if (!strcasecmp(name, "ControlSocket")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_control_socket, value);
} else if (!strcasecmp(name, "PIDFile")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_pidfile, value);
} else if (!strcasecmp(name, "LocalRegistry")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_local_registry_file, value);
} else if (!strcasecmp(name, "RegistrationPeriod")) {
if (!value)
goto no_value;
isns_config.ic_registration_period = parse_timeout(value);
} else if (!strcasecmp(name, "SCNTimeout")) {
if (!value)
goto no_value;
isns_config.ic_scn_timeout = parse_timeout(value);
} else if (!strcasecmp(name, "SCNRetries")) {
if (!value)
goto no_value;
isns_config.ic_scn_retries = parse_int(value);
} else if (!strcasecmp(name, "SCNCallout")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_scn_callout, value);
} else if (!strcasecmp(name, "ESIMinInterval")) {
if (!value)
goto no_value;
isns_config.ic_esi_min_interval = parse_timeout(value);
} else if (!strcasecmp(name, "ESIMaxInterval")) {
if (!value)
goto no_value;
isns_config.ic_esi_max_interval = parse_timeout(value);
} else if (!strcasecmp(name, "ESIRetries")) {
if (!value)
goto no_value;
isns_config.ic_esi_retries = parse_int(value);
} else if (!strcasecmp(name, "DefaultDiscoveryDomain")) {
if (!value)
goto no_value;
isns_config.ic_use_default_domain = parse_int(value);
} else if (!strcasecmp(name, "SLPRegister")) {
if (!value)
goto no_value;
isns_config.ic_slp_register = parse_int(value);
} else if (!strcasecmp(name, "Security")) {
if (!value)
goto no_value;
isns_config.ic_security = parse_int(value);
} else if (!strcasecmp(name, "AuthKeyFile")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_auth_key_file, value);
} else if (!strcasecmp(name, "ServerKeyFile")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_server_key_file, value);
} else if (!strcasecmp(name, "ClientKeyStore")
|| !strcasecmp(name, "KeyStore")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_client_keystore, value);
} else if (!strcasecmp(name, "Control.SourceName")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_control_name, value);
} else if (!strcasecmp(name, "Control.AuthKeyFile")) {
if (!value)
goto no_value;
isns_assign_string(&isns_config.ic_control_key_file, value);
} else if (!strcasecmp(name, "Auth.ReplayWindow")) {
if (!value)
goto no_value;
isns_config.ic_auth.replay_window = parse_timeout(value);
} else if (!strcasecmp(name, "Auth.TimestampJitter")) {
if (!value)
goto no_value;
isns_config.ic_auth.timestamp_jitter = parse_timeout(value);
} else if (!strcasecmp(name, "Network.MaxSockets")) {
if (!value)
goto no_value;
isns_config.ic_network.max_sockets = parse_timeout(value);
} else if (!strcasecmp(name, "Network.ConnectTimeout")) {
if (!value)
goto no_value;
isns_config.ic_network.connect_timeout = parse_timeout(value);
} else if (!strcasecmp(name, "Network.ReconnectTimeout")) {
if (!value)
goto no_value;
isns_config.ic_network.reconnect_timeout = parse_timeout(value);
} else if (!strcasecmp(name, "Network.CallTimeout")) {
if (!value)
goto no_value;
isns_config.ic_network.call_timeout = parse_timeout(value);
} else {
fprintf(stderr, "Unknown config item %s=%s\n", name, value);
}
return 0;
no_value:
fprintf(stderr,
"*** Missing value in configuration assignment for %s ***\n",
name);
return -1;
}