From: Martin Mares Date: Wed, 19 Jul 2017 10:35:53 +0000 (+0200) Subject: Split to directories X-Git-Tag: v0.9~48 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=3cb4e8e54034952c13f434187455caef39e60fd9;p=subauth.git Split to directories --- diff --git a/Makefile b/Makefile index 7ce559d..d538520 100644 --- a/Makefile +++ b/Makefile @@ -20,15 +20,8 @@ EXTRA_RUNDIRS=run CFLAGS+=$(LIBUCW_CFLAGS) $(LIBUCW_JSON_CFLAGS) LIBS+=$(LIBUCW_LIBS) $(LIBUCW_JSON_LIBS) -# Programs we want to compile -PROGS+=$(o)/subauthd $(o)/subauth - -# And how they are created -$(o)/subauthd: $(o)/subauthd.o -$(o)/subauth: $(o)/subauth.o - -# Configuration files -CONFIGS+=subauthd +include $(s)/server/Makefile +include $(s)/client/Makefile # And finally the default rules of the build system include $(BUILDSYS)/Makebottom diff --git a/client/Makefile b/client/Makefile new file mode 100644 index 0000000..608c26c --- /dev/null +++ b/client/Makefile @@ -0,0 +1,5 @@ +DIRS+=client + +PROGS+=$(o)/client/subauth + +$(o)/client/subauth: $(o)/client/subauth.o diff --git a/client/subauth.c b/client/subauth.c new file mode 100644 index 0000000..e597b76 --- /dev/null +++ b/client/subauth.c @@ -0,0 +1,80 @@ +/* + * Sub-authentication Client + * + * (c) 2017 Martin Mares + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "autoconf.h" + +static char *socket_path = INSTALL_RUN_DIR "/subauthd.socket"; + +static const struct opt_section options = { + OPT_ITEMS { + OPT_HELP("A client to the sub-authentication daemon."), + OPT_HELP("Usage: subauth [options]"), + OPT_HELP(""), + OPT_HELP("Options:"), + OPT_HELP_OPTION, + OPT_END + } +}; + +int main(int argc UNUSED, char **argv) +{ + opt_parse(&options, argv+1); + + int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0); + if (sk < 0) + die("socket(PF_UNIX, SOCK_SEQPACKET): %m"); + + struct sockaddr_un sun; + sun.sun_family = AF_UNIX; + if (strlen(socket_path) >= sizeof(sun.sun_path)) + die("Socket path too long"); + strcpy(sun.sun_path, socket_path); + + if (connect(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0) + die("Cannot connect to %s: %m", socket_path); + + struct fastbuf *out = bfdopen(1, 4096); + + struct json_context *js = json_new(); + struct json_node *rq = json_new_object(js); + + bprintf(out, ">>> Request:\n"); + json_write(js, out, rq); + bflush(out); + + struct fastbuf *rq_fb = fbgrow_create(4096); + json_write(js, rq_fb, rq); + byte *rq_buf; + uint rq_len = fbgrow_get_buf(rq_fb, &rq_buf); + if (send(sk, rq_buf, rq_len, 0) < 0) + die("Cannot send request: %m"); + bclose(rq_fb); + + byte rp_buf[4096]; // FIXME + int rp_len = recv(sk, rp_buf, sizeof(rp_buf), 0); + if (rp_len < 0) + die("Cannot receive reply: %m"); + + puts("Parsing reply"); + struct fastbuf rp_fb; + fbbuf_init_read(&rp_fb, rp_buf, rp_len, 0); + struct json_node *rp = json_parse(js, &rp_fb); + bprintf(out, "<<< Reply:\n"); + json_write(js, out, rp); + bflush(out); + + return 0; +} diff --git a/configure b/configure index a964476..1b22783 100755 --- a/configure +++ b/configure @@ -8,7 +8,7 @@ use strict; our($srcdir, $libdir); BEGIN { # Find the sources - my $pkgfile = "subauthd.c"; + my $pkgfile = "server/subauthd.c"; if (!defined ($srcdir = $ENV{"SRCDIR"})) { if (-f $pkgfile) { $srcdir="."; diff --git a/server/Makefile b/server/Makefile new file mode 100644 index 0000000..54b613f --- /dev/null +++ b/server/Makefile @@ -0,0 +1,6 @@ +DIRS+=server + +PROGS+=$(o)/server/subauthd +CONFIGS+=subauthd + +$(o)/server/subauthd: $(addprefix $(o)/server/, subauthd.o cmd.o) diff --git a/server/cmd.c b/server/cmd.c new file mode 100644 index 0000000..5e8b898 --- /dev/null +++ b/server/cmd.c @@ -0,0 +1,16 @@ +/* + * Sub-authentication Daemon: Commands + * + * (c) 2017 Martin Mares + */ + +#include + +#include "subauthd.h" + +void cmd_error(struct client *c, const char *err) +{ + json_object_set(c->reply, "error", json_new_string(c->json, err)); +} + + diff --git a/server/subauthd.c b/server/subauthd.c new file mode 100644 index 0000000..56d142f --- /dev/null +++ b/server/subauthd.c @@ -0,0 +1,305 @@ +/* + * Sub-authentication Daemon + * + * (c) 2017 Martin Mares + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "subauthd.h" + +static char *socket_path = "subauthd.socket"; +static uint max_connections = ~0U; + +static struct main_file listen_socket; +static uint num_connections; + +static byte packet_buffer[MAX_PACKET_SIZE]; +static byte oob_data_buffer[MAX_OOB_DATA_SIZE]; + +static int socket_read_handler(struct main_file *fi); +static int socket_write_handler(struct main_file *fi); + +static void client_close(struct client *c) +{ + msg(L_INFO, "Closing connection"); + file_del(&c->socket); + timer_del(&c->timer); + close(c->socket.fd); + json_delete(c->json); + xfree(c); + num_connections--; +} + +static void socket_timeout_handler(struct main_timer *tm) +{ + struct client *c = tm->data; + msg(L_INFO, "Client timeout"); + client_close(c); +} + +static void try_send_reply(struct client *c) +{ + struct fastbuf fb; + fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE); + + TRANS_TRY + { + json_write(c->json, &fb, c->reply); + } + TRANS_CATCH(x) + { + msg(L_ERROR, "Unable to construct reply, it is probably too long"); + fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE); + bputs(&fb, "{ \"error\": \"Reply too long\" }\n"); + } + TRANS_END; + + int len = fbbuf_count_written(&fb); + msg(L_INFO, "Sending reply of %d bytes", len); + if (send(c->socket.fd, packet_buffer, len, 0) < 0) + { + if (errno == EAGAIN || errno == EINTR) + { + msg(L_INFO, "Postponed send"); + c->socket.write_handler = socket_write_handler; + file_chg(&c->socket); + } + msg(L_ERROR, "Client write error: %m"); + client_close(c); + } + else + { + msg(L_INFO, "Reply sent"); + c->socket.read_handler = socket_read_handler; + c->socket.write_handler = NULL; + file_chg(&c->socket); + timer_add_rel(&c->timer, SOCKET_TIMEOUT); + } +} + +static void send_reply(struct client *c) +{ + timer_add_rel(&c->timer, SOCKET_TIMEOUT); + try_send_reply(c); +} + +static void received_packet(struct client *c, byte *pkt, int len) +{ + json_reset(c->json); + + struct fastbuf fb; + fbbuf_init_read(&fb, pkt, len, 0); + + c->reply = json_new_object(c->json); + + TRANS_TRY + { + c->request = json_parse(c->json, &fb); + } + TRANS_CATCH(x) + { + cmd_error(c, "Parse error"); + send_reply(c); + return; + } + TRANS_END; + + cmd_error(c, "OK"); + send_reply(c); +} + +static int socket_write_handler(struct main_file *fi) +{ + struct client *c = fi->data; + try_send_reply(c); + return HOOK_IDLE; +} + +static int socket_read_handler(struct main_file *fi) +{ + struct client *c = fi->data; + + struct iovec iov = { + .iov_base = packet_buffer, + .iov_len = MAX_PACKET_SIZE, + }; + + struct msghdr mh = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = oob_data_buffer, + .msg_controllen = MAX_OOB_DATA_SIZE, + }; + + ssize_t len = recvmsg(fi->fd, &mh, 0); + if (len < 0) + { + if (errno != EAGAIN && errno != EINTR) + msg(L_ERROR, "Socket read: %m"); + return HOOK_IDLE; + } + + if (!len) + { + client_close(c); + return HOOK_IDLE; + } + + struct ucred *cred = NULL; + for (struct cmsghdr *cm = CMSG_FIRSTHDR(&mh); cm; cm = CMSG_NXTHDR(&mh, cm)) + { + if (cm->cmsg_level == SOL_SOCKET) + { + if (cm->cmsg_type == SCM_RIGHTS) + { + // We are not interested in receiving file descriptor, but despite + // that they could be attached to the message. If it happens, simply + // close them. + int *fdptr = (int *) CMSG_DATA(cm); + int nfd = cm->cmsg_len / sizeof(int); + for (int i=0; icmsg_type == SCM_CREDENTIALS) + { + ASSERT(cm->cmsg_len >= sizeof(cred)); + cred = (struct ucred *) CMSG_DATA(cm); + } + } + } + + if (!cred) + { + msg(L_ERROR, "Dropping message with no credentials"); + return HOOK_RETRY; + } + + msg(L_INFO, "Got message from UID %d", (int) cred->uid); + c->uid = cred->uid; + + fi->read_handler = NULL; + file_chg(fi); + + received_packet(c, packet_buffer, len); + return HOOK_RETRY; +} + +static int listen_read_handler(struct main_file *fi) +{ + struct sockaddr_un client; + socklen_t addr_len = sizeof(client); + + int new_sk = accept(fi->fd, &client, &addr_len); + if (new_sk < 0) + { + if (errno != EAGAIN && errno != EINTR) + msg(L_ERROR, "Socket accept: %m"); + return HOOK_IDLE; + } + + if (num_connections >= max_connections) + { + msg(L_WARN, "Too many connections (you might need to increase MaxConnections)"); + close(new_sk); + return HOOK_IDLE; + } + num_connections++; + + msg(L_INFO, "Accepted connection"); + + if (fcntl(new_sk, F_SETFL, fcntl(new_sk, F_GETFL) | O_NONBLOCK) < 0) + die("Cannot set O_NONBLOCK: %m"); + + struct client *c = xmalloc_zero(sizeof(*c)); + c->json = json_new(); + + c->socket.fd = new_sk; + c->socket.read_handler = socket_read_handler; + c->socket.data = c; + file_add(&c->socket); + + c->timer.handler = socket_timeout_handler; + c->timer.data = c; + timer_add_rel(&c->timer, SOCKET_TIMEOUT); + + return HOOK_RETRY; +} + +static void init_socket(void) +{ + int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0); + if (sk < 0) + die("socket(PF_UNIX, SOCK_SEQPACKET): %m"); + + if (fcntl(sk, F_SETFL, fcntl(sk, F_GETFL) | O_NONBLOCK) < 0) + die("Cannot set O_NONBLOCK: %m"); + + struct sockaddr_un sun; + sun.sun_family = AF_UNIX; + if (strlen(socket_path) >= sizeof(sun.sun_path)) + die("SocketPath too long"); + strcpy(sun.sun_path, socket_path); + + if (unlink(socket_path) < 0 && errno != ENOENT) + die("Cannot unlink old socket %s: %m", socket_path); + + if (bind(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0) + die("Cannot bind to %s: %m", socket_path); + + if (listen(sk, 64) < 0) + die("listen(): %m"); + + int one; + if (setsockopt(sk, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) + die("setsockopt(SO_PASSCRED): %m"); + + listen_socket.fd = sk; + listen_socket.read_handler = listen_read_handler; + file_add(&listen_socket); + + msg(L_INFO, "Listening on %s", socket_path); +} + +static struct cf_section daemon_config = { + CF_ITEMS { + CF_STRING("SocketPath", &socket_path), + CF_UINT("MaxConnections", &max_connections), + CF_END + } +}; + +static const struct opt_section options = { + OPT_ITEMS { + OPT_HELP("A sub-authentication daemon."), + OPT_HELP("Usage: subauthd [options]"), + OPT_HELP(""), + OPT_HELP("Options:"), + OPT_HELP_OPTION, + OPT_CONF_OPTIONS, + OPT_END + } +}; + +int main(int argc UNUSED, char **argv) +{ + cf_def_file = CONFIG_DIR "/subauthd"; + cf_declare_section("SubauthD", &daemon_config, 0); + opt_parse(&options, argv+1); + + main_init(); + init_socket(); + + main_loop(); + return 0; +} diff --git a/server/subauthd.h b/server/subauthd.h new file mode 100644 index 0000000..4a104ec --- /dev/null +++ b/server/subauthd.h @@ -0,0 +1,27 @@ +/* + * Sub-authentication Daemon + * + * (c) 2017 Martin Mares + */ + +#include "autoconf.h" + +#include +#include + +#define SOCKET_TIMEOUT 60000 // in ms +#define MAX_PACKET_SIZE 16384 +#define MAX_OOB_DATA_SIZE 4096 + +struct client { + struct main_file socket; + struct main_timer timer; + int uid; + struct json_context *json; + struct json_node *request; + struct json_node *reply; +}; + +/* cmd.c */ + +void cmd_error(struct client *c, const char *err); diff --git a/subauth.c b/subauth.c deleted file mode 100644 index e597b76..0000000 --- a/subauth.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Sub-authentication Client - * - * (c) 2017 Martin Mares - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "autoconf.h" - -static char *socket_path = INSTALL_RUN_DIR "/subauthd.socket"; - -static const struct opt_section options = { - OPT_ITEMS { - OPT_HELP("A client to the sub-authentication daemon."), - OPT_HELP("Usage: subauth [options]"), - OPT_HELP(""), - OPT_HELP("Options:"), - OPT_HELP_OPTION, - OPT_END - } -}; - -int main(int argc UNUSED, char **argv) -{ - opt_parse(&options, argv+1); - - int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0); - if (sk < 0) - die("socket(PF_UNIX, SOCK_SEQPACKET): %m"); - - struct sockaddr_un sun; - sun.sun_family = AF_UNIX; - if (strlen(socket_path) >= sizeof(sun.sun_path)) - die("Socket path too long"); - strcpy(sun.sun_path, socket_path); - - if (connect(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0) - die("Cannot connect to %s: %m", socket_path); - - struct fastbuf *out = bfdopen(1, 4096); - - struct json_context *js = json_new(); - struct json_node *rq = json_new_object(js); - - bprintf(out, ">>> Request:\n"); - json_write(js, out, rq); - bflush(out); - - struct fastbuf *rq_fb = fbgrow_create(4096); - json_write(js, rq_fb, rq); - byte *rq_buf; - uint rq_len = fbgrow_get_buf(rq_fb, &rq_buf); - if (send(sk, rq_buf, rq_len, 0) < 0) - die("Cannot send request: %m"); - bclose(rq_fb); - - byte rp_buf[4096]; // FIXME - int rp_len = recv(sk, rp_buf, sizeof(rp_buf), 0); - if (rp_len < 0) - die("Cannot receive reply: %m"); - - puts("Parsing reply"); - struct fastbuf rp_fb; - fbbuf_init_read(&rp_fb, rp_buf, rp_len, 0); - struct json_node *rp = json_parse(js, &rp_fb); - bprintf(out, "<<< Reply:\n"); - json_write(js, out, rp); - bflush(out); - - return 0; -} diff --git a/subauthd.c b/subauthd.c deleted file mode 100644 index bc76ef5..0000000 --- a/subauthd.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Sub-authentication Daemon - * - * (c) 2017 Martin Mares - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "autoconf.h" - -static char *socket_path = "subauthd.socket"; -static uint max_connections = ~0U; - -static struct main_file listen_socket; -static uint num_connections; - -#define SOCKET_TIMEOUT 60000 // in ms -#define MAX_PACKET_SIZE 16384 -#define MAX_OOB_DATA_SIZE 4096 - -struct client { - struct main_file socket; - struct main_timer timer; - int uid; - struct json_context *json; - struct json_node *request; - struct json_node *reply; -}; - -static byte packet_buffer[MAX_PACKET_SIZE]; -static byte oob_data_buffer[MAX_OOB_DATA_SIZE]; - -static int socket_read_handler(struct main_file *fi); -static int socket_write_handler(struct main_file *fi); - -static void client_close(struct client *c) -{ - msg(L_INFO, "Closing connection"); - file_del(&c->socket); - timer_del(&c->timer); - close(c->socket.fd); - json_delete(c->json); - xfree(c); - num_connections--; -} - -static void cmd_error(struct client *c, const char *err) -{ - json_object_set(c->reply, "error", json_new_string(c->json, err)); -} - -static void socket_timeout_handler(struct main_timer *tm) -{ - struct client *c = tm->data; - - msg(L_INFO, "Client timeout"); - - client_close(c); -} - -static void try_send_reply(struct client *c) -{ - struct fastbuf fb; - fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE); - - TRANS_TRY - { - json_write(c->json, &fb, c->reply); - } - TRANS_CATCH(x) - { - msg(L_ERROR, "Unable to construct reply, it is probably too long"); - fbbuf_init_write(&fb, packet_buffer, MAX_PACKET_SIZE); - bputs(&fb, "{ \"error\": \"Reply too long\" }\n"); - } - TRANS_END; - - int len = fbbuf_count_written(&fb); - msg(L_INFO, "Sending reply of %d bytes", len); - if (send(c->socket.fd, packet_buffer, len, 0) < 0) - { - if (errno == EAGAIN || errno == EINTR) - { - msg(L_INFO, "Postponed send"); - c->socket.write_handler = socket_write_handler; - file_chg(&c->socket); - } - msg(L_ERROR, "Client write error: %m"); - client_close(c); - } - else - { - msg(L_INFO, "Reply sent"); - c->socket.read_handler = socket_read_handler; - c->socket.write_handler = NULL; - file_chg(&c->socket); - timer_add_rel(&c->timer, SOCKET_TIMEOUT); - } -} - -static void send_reply(struct client *c) -{ - timer_add_rel(&c->timer, SOCKET_TIMEOUT); - try_send_reply(c); -} - -static void received_packet(struct client *c, byte *pkt, int len) -{ - json_reset(c->json); - - struct fastbuf fb; - fbbuf_init_read(&fb, pkt, len, 0); - - c->reply = json_new_object(c->json); - - TRANS_TRY - { - c->request = json_parse(c->json, &fb); - } - TRANS_CATCH(x) - { - cmd_error(c, "Parse error"); - send_reply(c); - return; - } - TRANS_END; - - cmd_error(c, "OK"); - send_reply(c); -} - -static int socket_write_handler(struct main_file *fi) -{ - struct client *c = fi->data; - try_send_reply(c); - return HOOK_IDLE; -} - -static int socket_read_handler(struct main_file *fi) -{ - struct client *c = fi->data; - - struct iovec iov = { - .iov_base = packet_buffer, - .iov_len = MAX_PACKET_SIZE, - }; - - struct msghdr mh = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = oob_data_buffer, - .msg_controllen = MAX_OOB_DATA_SIZE, - }; - - ssize_t len = recvmsg(fi->fd, &mh, 0); - if (len < 0) - { - if (errno != EAGAIN && errno != EINTR) - msg(L_ERROR, "Socket read: %m"); - return HOOK_IDLE; - } - - if (!len) - { - client_close(c); - return HOOK_IDLE; - } - - struct ucred *cred = NULL; - for (struct cmsghdr *cm = CMSG_FIRSTHDR(&mh); cm; cm = CMSG_NXTHDR(&mh, cm)) - { - if (cm->cmsg_level == SOL_SOCKET) - { - if (cm->cmsg_type == SCM_RIGHTS) - { - // We are not interested in receiving file descriptor, but despite - // that they could be attached to the message. If it happens, simply - // close them. - int *fdptr = (int *) CMSG_DATA(cm); - int nfd = cm->cmsg_len / sizeof(int); - for (int i=0; icmsg_type == SCM_CREDENTIALS) - { - ASSERT(cm->cmsg_len >= sizeof(cred)); - cred = (struct ucred *) CMSG_DATA(cm); - } - } - } - - if (!cred) - { - msg(L_ERROR, "Dropping message with no credentials"); - return HOOK_RETRY; - } - - msg(L_INFO, "Got message from UID %d", (int) cred->uid); - c->uid = cred->uid; - - fi->read_handler = NULL; - file_chg(fi); - - received_packet(c, packet_buffer, len); - return HOOK_RETRY; -} - -static int listen_read_handler(struct main_file *fi) -{ - struct sockaddr_un client; - socklen_t addr_len = sizeof(client); - - int new_sk = accept(fi->fd, &client, &addr_len); - if (new_sk < 0) - { - if (errno != EAGAIN && errno != EINTR) - msg(L_ERROR, "Socket accept: %m"); - return HOOK_IDLE; - } - - if (num_connections >= max_connections) - { - msg(L_WARN, "Too many connections (you might need to increase MaxConnections)"); - close(new_sk); - return HOOK_IDLE; - } - num_connections++; - - msg(L_INFO, "Accepted connection"); - - if (fcntl(new_sk, F_SETFL, fcntl(new_sk, F_GETFL) | O_NONBLOCK) < 0) - die("Cannot set O_NONBLOCK: %m"); - - struct client *c = xmalloc_zero(sizeof(*c)); - c->json = json_new(); - - c->socket.fd = new_sk; - c->socket.read_handler = socket_read_handler; - c->socket.data = c; - file_add(&c->socket); - - c->timer.handler = socket_timeout_handler; - c->timer.data = c; - timer_add_rel(&c->timer, SOCKET_TIMEOUT); - - return HOOK_RETRY; -} - -static void init_socket(void) -{ - int sk = socket(PF_UNIX, SOCK_SEQPACKET, 0); - if (sk < 0) - die("socket(PF_UNIX, SOCK_SEQPACKET): %m"); - - if (fcntl(sk, F_SETFL, fcntl(sk, F_GETFL) | O_NONBLOCK) < 0) - die("Cannot set O_NONBLOCK: %m"); - - struct sockaddr_un sun; - sun.sun_family = AF_UNIX; - if (strlen(socket_path) >= sizeof(sun.sun_path)) - die("SocketPath too long"); - strcpy(sun.sun_path, socket_path); - - if (unlink(socket_path) < 0 && errno != ENOENT) - die("Cannot unlink old socket %s: %m", socket_path); - - if (bind(sk, (struct sockaddr *) &sun, sizeof(sun)) < 0) - die("Cannot bind to %s: %m", socket_path); - - if (listen(sk, 64) < 0) - die("listen(): %m"); - - int one; - if (setsockopt(sk, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) - die("setsockopt(SO_PASSCRED): %m"); - - listen_socket.fd = sk; - listen_socket.read_handler = listen_read_handler; - file_add(&listen_socket); - - msg(L_INFO, "Listening on %s", socket_path); -} - -static struct cf_section daemon_config = { - CF_ITEMS { - CF_STRING("SocketPath", &socket_path), - CF_UINT("MaxConnections", &max_connections), - CF_END - } -}; - -static const struct opt_section options = { - OPT_ITEMS { - OPT_HELP("A sub-authentication daemon."), - OPT_HELP("Usage: subauthd [options]"), - OPT_HELP(""), - OPT_HELP("Options:"), - OPT_HELP_OPTION, - OPT_CONF_OPTIONS, - OPT_END - } -}; - -int main(int argc UNUSED, char **argv) -{ - cf_def_file = CONFIG_DIR "/subauthd"; - cf_declare_section("SubauthD", &daemon_config, 0); - opt_parse(&options, argv+1); - - main_init(); - init_socket(); - - main_loop(); - return 0; -}