keydctl
maxpath
onak-mail.pl
-onak.conf
+onak.ini
sixdegrees
splitkeys
stripkey
OBJS = stats.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ)
-all: .depend $(PROGS) testparse maxpath sixdegrees splitkeys onak.conf \
+all: .depend $(PROGS) testparse maxpath sixdegrees splitkeys onak.ini \
wotsap $(BACKENDS)
test: onak $(BACKENDS)
@./runtests
-install: $(PROGS) onak.conf $(BACKENDS)
+install: $(PROGS) onak.ini $(BACKENDS)
install -d $(DESTDIR)/@bindir@
install -d $(DESTDIR)/@libdir@/onak/backends
install -d $(DESTDIR)/@localstatedir@/lib/onak
$(CORE_OBJS) $(KEYDB_OBJ) $(LIBS) $(PROGS_LDFLAGS_EXTRA)
onak-conf.o: onak-conf.c onak-conf.h
- $(CC) $(CFLAGS) -DCONFIGFILE=\"@sysconfdir@/onak.conf\" \
+ $(CC) $(CFLAGS) -DCONFIGDIR=\"@sysconfdir@\" \
-DDBINIT=keydb_@DBTYPE@_init -c onak-conf.c
# HACK: onak-conf.o needs to be able to see keydb_@DBTYPE@_funcs, but
%: %.in
sed -e 's:@BINDIR@:@bindir@:g' \
- -e 's:@CONFIG@:@sysconfdir@/onak.conf:g' \
+ -e 's:@CONFIG@:@sysconfdir@/onak.ini:g' \
+ -e 's:@CONFIGOLD@:@sysconfdir@/onak.conf:g' \
-e 's:@LIBDIR@:@libdir@:g' \
-e 's:@RUNDIR@:@runstatedir@:g' \
-e 's:@SBINDIR@:@sbindir@:g' \
clean:
$(RM) $(PROGS) $(OBJS) Makefile.bak testparse maxpath *.core core \
gpgwww.o add.o lookup.o main.o maxpath.o onak.o sixdegrees \
- sixdegrees.o splitkeys.o stripkey.o onak.conf keyd.o \
+ sixdegrees.o splitkeys.o stripkey.o onak.ini keyd.o \
keydctl.o hashquery.o wotsap.o version.h \
TAGS cscope.out cscope.files \
$(foreach be,@BACKENDS@,keydb_$(be).o) *.so
Config:
-I've finally added config file support. onak.conf is an example config;
-the main thing to change is the db_dir to whereever you want to put your
-database files. The configure script allows you to specific where it
-should live; by default it'll be PREFIX/etc/onak.conf.
+I've finally added config file support. onak.ini is an example config;
+the main thing to change is the location in the backend section to
+whereever you want to put your database files. The configure script allows
+you to specific where it should live; by default it'll be PREFIX/etc/onak.ini.
Backends:
.nf
.\" set tabstop to longest possible filename, plus a wee bit
.ta \w'/usr/lib/perl/getopts.pl 'u
-\fI/etc/onak.conf\fR default configuration file
+\fI/etc/onak.ini\fR default configuration file
.SH NOTES
This man page could probably do with some more details.
.SH "SEE ALSO"
.nf
.\" set tabstop to longest possible filename, plus a wee bit
.ta \w'/usr/lib/perl/getopts.pl 'u
-\fI/etc/onak.conf\fR default configuration file
+\fI/etc/onak.ini\fR default configuration file
.SH NOTES
This man page could probably do with some more details.
.SH "SEE ALSO"
.mail_dir = NULL,
};
+struct onak_db_config *find_db_backend_config(struct ll *backends, char *name)
+{
+ struct ll *cur;
+
+ cur = backends;
+ while (cur != NULL && strcmp(name,
+ ((struct onak_db_config *) cur->object)->name)) {
+ cur = cur->next;
+ }
+
+ return (cur != NULL) ? (struct onak_db_config *) cur->object : NULL;
+}
+
bool parsebool(char *str, bool fallback)
{
if (!strcasecmp(str, "false") || !strcasecmp(str, "no") ||
}
}
-static bool parseconfigline(char *line)
+/*
+ * Parse an old pksd style config line, as used in onak 0.4.6 and earlier.
+ */
+static bool parseoldconfigline(char *line)
{
if (line[0] == '#' || line[0] == 0) {
/*
return true;
}
+/*
+ * Parse a new style .ini config line, supporting [sections] and name=value
+ * format.
+ */
+static bool parseconfigline(char *line)
+{
+ /* Yes, this means we're not re-entrant. */
+ static char section[32] = "";
+ struct onak_db_config *backend;
+ size_t len;
+ char *name, *value;
+
+ if (line[0] == '#' || line[0] == ';' ||
+ line[0] == 0) {
+ /*
+ * Comment line, ignore.
+ */
+ } else if (line[0] == '[') {
+ /* Section name */
+ len = strlen(line);
+ if (line[len - 1] != ']') {
+ logthing(LOGTHING_CRITICAL,
+ "Malformed section header '%s' in "
+ "config file.", line);
+ return false;
+ }
+ if (len > sizeof(section)) {
+ logthing(LOGTHING_CRITICAL,
+ "Section header '%s' is too long in "
+ "config file.", line);
+ return false;
+ }
+ line[len - 1] = 0;
+ strncpy(section, &line[1], len);
+ } else if ((value = strchr(line, '=')) != NULL) {
+ name = line;
+ *value++ = 0;
+
+ /* We can have multiple backend: sections */
+ if (!strncmp(section, "backend:", 8)) {
+ backend = find_db_backend_config(
+ config.backends, §ion[8]);
+ if (backend == NULL) {
+ backend = calloc(1,
+ sizeof(struct onak_db_config));
+ backend->name = strdup(§ion[8]);
+ config.backends = lladd(config.backends,
+ backend);
+ }
+
+ if (!strcmp(name, "type")) {
+ backend->type = strdup(value);
+ } else if (!strcmp(name, "location")) {
+ backend->location = strdup(value);
+ } else if (!strcmp(name, "hostname")) {
+ backend->location = strdup(value);
+ } else if (!strcmp(name, "username")) {
+ backend->location = strdup(value);
+ } else if (!strcmp(name, "password")) {
+ backend->location = strdup(value);
+ }
+
+#define MATCH(s, n) !strcmp(section, s) && !strcmp(name, n)
+ /* [main] section */
+ } else if (MATCH("main", "backend")) {
+ config.db_backend = strdup(value);
+ } else if (MATCH("main", "backends_dir")) {
+ config.backends_dir = strdup(value);
+ } else if (MATCH("main", "logfile")) {
+ config.logfile = strdup(value);
+ } else if (MATCH("main", "loglevel")) {
+ setlogthreshold(atoi(value));
+ } else if (MATCH("main", "use_keyd")) {
+ config.use_keyd = parsebool(value,
+ config.use_keyd);
+ } else if (MATCH("main", "sock_dir")) {
+ config.sock_dir = strdup(value);
+ } else if (MATCH("main", "max_reply_keys")) {
+ config.maxkeys = atoi(value);
+ /* [mail] section */
+ } else if (MATCH("mail", "maintainer_email")) {
+ config.adminemail = strdup(value);
+ } else if (MATCH("mail", "mail_dir")) {
+ config.mail_dir = strdup(value);
+ } else if (MATCH("mail", "mta")) {
+ config.mta = strdup(value);
+ } else if (MATCH("mail", "bin_dir")) {
+ config.bin_dir = strdup(value);
+ } else if (MATCH("mail", "this_site")) {
+ config.thissite = strdup(value);
+ } else if (MATCH("mail", "syncsite")) {
+ config.syncsites = lladd(config.syncsites,
+ strdup(value));
+ /* [verification] section */
+ } else if (MATCH("verification", "check_sighash")) {
+ config.check_sighash = parsebool(value,
+ config.check_sighash);
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
void readconfig(const char *configfile) {
FILE *conffile;
char curline[1024];
char *dir, *conf;
size_t len;
struct onak_db_config *backend;
+ bool oldstyle = false;
+ bool res;
curline[1023] = 0;
+
+ /*
+ * Try to find a config file to use. If one is explicitly provided,
+ * use that. Otherwise look in $XDG_CONFIG_HOME, $HOME and finally
+ * the build in configuration directory. We try an old style onak.conf
+ * first and then the new style onak.ini if that wasn't found - this
+ * is to prevent breaking existing installs on upgrade.
+ */
if (configfile == NULL) {
conffile = NULL;
if ((dir = getenv("XDG_CONFIG_HOME")) != NULL) {
- len = strlen(dir) + 1 + 9 + 1; /* dir + / + onak.conf + NUL */
+ /* dir + / + onak.conf + NUL */
+ len = strlen(dir) + 1 + 9 + 1;
conf = malloc(len);
snprintf(conf, len, "%s/onak.conf", dir);
conffile = fopen(conf, "r");
+ if (conffile == NULL) {
+ /* Conveniently .ini is shorter than .conf */
+ snprintf(conf, len, "%s/onak.ini", dir);
+ conffile = fopen(conf, "r");
+ } else {
+ oldstyle = true;
+ }
free(conf);
} else if ((dir = getenv("HOME")) != NULL) {
- len = strlen(dir) + 18 + 1; /* dir + /.config/onak.conf + NUL */
+ /* dir + /.config/onak.conf + NUL */
+ len = strlen(dir) + 18 + 1;
conf = malloc(len);
snprintf(conf, len, "%s/.config/onak.conf", dir);
conffile = fopen(conf, "r");
+ if (conffile == NULL) {
+ /* Conveniently .ini is shorter than .conf */
+ snprintf(conf, len, "%s/onak.ini", dir);
+ conffile = fopen(conf, "r");
+ } else {
+ oldstyle = true;
+ }
free(conf);
}
if (conffile == NULL) {
- conffile = fopen(CONFIGFILE, "r");
+ conffile = fopen(CONFIGDIR "/onak.conf", "r");
+ if (conffile == NULL) {
+ conffile = fopen(CONFIGDIR "/onak.ini", "r");
+ } else {
+ oldstyle = true;
+ }
}
} else {
+ /*
+ * Explicitly provided config file; if the filename ends .conf
+ * assume it's old style.
+ */
+ len = strlen(configfile);
+ if (!strcmp(&configfile[len - 5], ".conf")) {
+ oldstyle = true;
+ }
conffile = fopen(configfile, "r");
}
+
if (conffile != NULL) {
if (!fgets(curline, 1023, conffile)) {
logthing(LOGTHING_CRITICAL,
return;
}
- /* Add a single DB configuration */
- backend = calloc(1, sizeof(*backend));
- config.backend = backend;
- config.backends = lladd(NULL, backend);
+ if (oldstyle) {
+ /* Add a single DB configuration */
+ backend = calloc(1, sizeof(*backend));
+ config.backend = backend;
+ config.backends = lladd(NULL, backend);
+ }
while (!feof(conffile)) {
/* Strip any trailing white space */
i++;
}
- if (!parseconfigline(&curline[i])) {
+ if (oldstyle) {
+ res = parseoldconfigline(&curline[i]);
+ } else {
+ res = parseconfigline(&curline[i]);
+ }
+ if (!res) {
logthing(LOGTHING_ERROR,
"Unknown config line: %s", curline);
}
}
}
fclose(conffile);
+
+ if (config.db_backend == NULL) {
+ logthing(LOGTHING_CRITICAL,
+ "No database backend configured.");
+ } else if (!oldstyle) {
+ config.backend = find_db_backend_config(
+ config.backends, config.db_backend);
+ if (config.backend == NULL) {
+ logthing(LOGTHING_NOTICE,
+ "Couldn't find configuration for %s "
+ "backend.", config.db_backend);
+ }
+ }
} else {
logthing(LOGTHING_NOTICE,
"Couldn't open config file; using defaults.");
.nf
.\" set tabstop to longest possible filename, plus a wee bit
.ta \w'/usr/lib/perl/getopts.pl 'u
-\fI/etc/onak.conf\fR default configuration file
+\fI/etc/onak.ini\fR default configuration file
.SH NOTES
This man page could probably do with some more details.
.SH "SEE ALSO"
my %config;
#
-# readconfig
+# readoldconfig
#
-# Reads in our config file. Ignores any command it doesn't understand rather
-# than having to list all the ones that are of no interest to us.
+# Read an old pksd-style config file. Currently if both old and new style
+# files are present the old style will be preferred in order to ensure smooth
+# upgrades.
#
-sub readconfig {
-
- open(CONFIG, "@CONFIG@") or
+sub readoldconfig {
+ open(CONFIG, "@CONFIGOLD@") or
die "Can't read config file: $!";
while (<CONFIG>) {
return;
}
+#
+# readconfig
+#
+# Reads in our config file. Ignores any command it doesn't understand rather
+# than having to list all the ones that are of no interest to us.
+#
+sub readconfig {
+ # Prefer the old style config if it exists.
+ if (-e "@CONFIGOLD@") {
+ &readoldconfig;
+ return;
+ }
+
+ open(CONFIG, "@CONFIG@") or
+ die "Can't read config file: $!";
+
+ $section = "";
+ while (<CONFIG>) {
+ if (/^#/ or /^$/) {
+ # Ignore; comment line.
+ } elsif (/^\[(\w+)\]/) {
+ section = $1;
+ } elsif ($section == "main") {
+ if (/^logfile\s*=\s*(.*)/) {
+ $config{'logfile'} = $1;
+ }
+ } elsif ($section == "mail") {
+ if (/^this_site\s*=\s*(.*)/) {
+ $config{'thissite'} = $1;
+ } elsif (/^maintainer_email\s*=\s*(.*)/) {
+ $config{'adminemail'} = $1;
+ } elsif (/^mta\s*=\s*(.*)/) {
+ $config{'mta'} = $1;
+ } elsif (/^bin_dir\s*=\s*(.*)/) {
+ $config{'pks_bin_dir'} = $1;
+ } elsif (/^mail_dir\s*=\s*(.*)/) {
+ $config{'mail_dir'} = $1;
+ } elsif (/^syncsite\s*=\s*(.*)/) {
+ push @{$config{'syncsites'}}, $1;
+ }
+ }
+ }
+
+ close(CONFIG);
+
+ return;
+}
+
#
# submitupdate
#
.nf
.\" set tabstop to longest possible filename, plus a wee bit
.ta \w'/usr/lib/perl/getopts.pl 'u
-\fI/etc/onak.conf\fR default configuration file
+\fI/etc/onak.ini\fR default configuration file
.SH NOTES
This man page could probably do with some more details.
.SH AUTHOR
+++ /dev/null
-#
-# onak configuration file. Taken from pksd.conf as a starting point.
-#
-
-pks_bin_dir @BINDIR@
-db_backend db4
-backends_dir @LIBDIR@/onak/backends
-db_dir @STATEDIR@/lib/onak
-logfile @STATEDIR@/log/onak.log
-# Loglevel : 0 is highest debug, default is 3, nothing is 7+
-loglevel 3
-
-# Should we use the keyd backend?
-use_keyd false
-
-### Set www_port to the port on which HTTP requests should be accepted.
-### If you do not want to process HTTP requests, set this to 0.
-
-www_port 11371
-socket_name /community/pgp-keyserver/pksd_socket
-
-### Specify the envelope sender address as the -f argument to
-### sendmail. This is the address which will receive any bounces.
-### If you don't use sendmail, then change this to an equivalent command.
-### If you do not want to process mail requests, leave this unset.
-
-mail_delivery_client /usr/sbin/sendmail -t -oi -fmailer-daemon
-
-### Set this to the address which should be displayed as the From:
-### address in all outgoing email, and as the maintainer in the body
-### of each message.
-
-maintainer_email PGP Key Server Administrator <pgp-keyserver-admin@the.earth.li>
-mail_intro_file /community/pgp-keyserver/share/mail_intro
-help_dir /community/pgp-keyserver/share
-mail_dir @STATEDIR@/spool/onak
-sock_dir @RUNDIR@
-
-### If you change this, make sure to put a corresponding help file in
-### the help_dir named above
-
-default_language EN
-
-### This is the email address of this site. It will be inserted in all
-### outgoing incremental messages, so it should match whatever the
-### downstream sites use as syncsite in their pksd.conf files.
-
-this_site pgp-public-keys@the.earth.li
-
-### Include a syncsite line for each site with which you are exchanging
-### incremental requests.
-
-#syncsite pgp-public-keys@keys.nl.pgp.net
-#syncsite pgp-public-keys@blackhole.pca.dfn.de
-#syncsite pgp-public-keys@pgp.es.net
-#syncsite pgp-public-keys@keyserver.linux.it
-#syncsite pgp-public-keys@pgp.dtype.org
-#syncsite pgp-public-keys@kjsl.com
-
-### Set this to 0 to disable mailserver LAST requests completely, to a
-### positive integer to limit LAST requests to that many days, or -1
-### to allow any argument to LAST.
-
-max_last 1
-
-### Set this to the maximum number of keys to return in the reply to
-### an index, verbose index, get, or since reply. Setting it to -1
-### will allow any size reply.
-
-max_reply_keys 128
-
-##
-## Verify signature hashes.
-##
-#check_sighash true
--- /dev/null
+;
+; Configuration for onak, an OpenPGP compatible keyserver
+;
+[main]
+backend=defaultdb4
+backends_dir=@LIBDIR@/onak/backends
+logfile=@STATEDIR@/log/onak.log
+; Loglevel : 0 is highest debug, default is 3, nothing is 7+
+loglevel=3
+; Should we use the keyd backend?
+use_keyd=false
+sock_dir=@RUNDIR@
+; Maximum number of keys to return in a reply to an index, verbose index or
+; get. Setting it to -1 will allow any size of reply.
+max_reply_keys=128
+
+; Settings related to key verification options available.
+[verification]
+; Verify signature hashes - verify that the hash a signature claims to be
+; over matches the hash of the data. Does not actually verify the signature.
+check_sighash=true
+
+; Settings related to the email interface to onak.
+[mail]
+maintainer_email=PGP Key Server Administrator <pgp-keyserver-admin@the.earth.li>
+mail_dir=@STATEDIR@/spool/onak
+; Specify the envelope sender address as the -f argument to
+; sendmail. This is the address which will receive any bounces.
+; If you don't use sendmail, then change this to an equivalent command.
+; If you do not want to process mail requests, leave this unset.
+mta=/usr/sbin/sendmail -t -oi -fmailer-daemon
+; Where the main onak binary lives, so the script that handles incoming
+; email knows where to find it.
+bin_dir=@BINDIR@
+; Email address outgoing incremental messages will come from.
+; Needs to match the syncsite entries others sites have for this site.
+this_site=pgp-public-keys@the.earth.li
+; Include a syncsite line for each site with which you are exchanging
+; incremental requests.
+;syncsite=pgp-public-keys@keys.nl.pgp.net
+;syncsite=pgp-public-keys@blackhole.pca.dfn.de
+;syncsite=pgp-public-keys@pgp.es.net
+;syncsite=pgp-public-keys@keyserver.linux.it
+;syncsite=pgp-public-keys@pgp.dtype.org
+;syncsite=pgp-public-keys@kjsl.com
+
+; Database backend configurations below here
+
+[backend:defaultdb4]
+type=db4
+location=@STATEDIR@/lib/onak
backend=${t##libkeydb_}
backend=${backend%%.so}
if [ "`echo t/$backend-*`" != "t/$backend-*" ]; then
- echo "* testing $backend backend"
+ echo "* testing $backend backend [conf]"
(sed -e "s;DIR;`pwd`;" t/test-in.conf ; \
echo db_backend $backend) > t/test.conf
for t in t/$backend-*.t t/all-*.t; do
done
rm t/test.conf
fi
+
+ if [ "`echo t/$backend-*`" != "t/$backend-*" ]; then
+ echo "* testing $backend backend [ini]"
+ sed -e "s;DIR;`pwd`;" -e "s;DB;${backend};" t/test-in.ini \
+ > t/test.ini
+ for t in t/$backend-*.t t/all-*.t; do
+ total=`expr $total + 1`
+ mkdir t/db/
+ if ! $t test.ini $backend; then
+ echo "test $t failed" >&2
+ fail=`expr $fail + 1`
+ fi
+ rm -rf t/db/
+ done
+ rm t/test.ini
+ fi
done
if [ "$fail" -gt 0 ]; then
--- /dev/null
+[main]
+backend=test-DB
+backends_dir=DIR
+logfile=onak.log
+loglevel=7
+use_keyd=false
+max_reply_keys=128
+
+[backend:test-DB]
+type=DB
+location=DIR/t/db/
+
+[mail]
+bin_dir=DIR
+this_site=pgp-public-keys@localhost