1 /* authd/authd.c - main code for authd
2 * Copyright (c) 2016 William Pitcock <nenolod@dereferenced.org>
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice is present in all copies.
8 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
12 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
17 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18 * POSSIBILITY OF SUCH DAMAGE.
28 static void error_cb(rb_helper
*helper
) __attribute__((noreturn
));
29 static void handle_reload(int parc
, char *parv
[]);
30 static void handle_stat(int parc
, char *parv
[]);
31 static void handle_options(int parc
, char *parv
[]);
33 rb_helper
*authd_helper
= NULL
;
34 authd_cmd_handler authd_cmd_handlers
[256] = {
35 ['C'] = handle_new_connection
,
36 ['D'] = handle_resolve_dns
,
37 ['E'] = handle_cancel_connection
,
38 ['O'] = handle_options
,
39 ['R'] = handle_reload
,
43 authd_stat_handler authd_stat_handlers
[256] = {
44 ['D'] = enumerate_nameservers
,
47 authd_reload_handler authd_reload_handlers
[256] = {
48 ['D'] = reload_nameservers
,
51 rb_dictionary
*authd_option_handlers
;
54 handle_stat(int parc
, char *parv
[])
56 authd_stat_handler handler
;
57 unsigned long long rid
;
61 warn_opers(L_CRIT
, "BUG: handle_stat received too few parameters (at least 3 expected, got %d)", parc
);
65 if((rid
= strtoull(parv
[1], NULL
, 16)) > UINT32_MAX
)
67 warn_opers(L_CRIT
, "BUG: handle_stat got a rid that was too large: %s", parv
[1]);
71 if (!(handler
= authd_stat_handlers
[(unsigned char)parv
[2][0]]))
74 handler((uint32_t)rid
, parv
[2][0]);
78 handle_options(int parc
, char *parv
[])
80 struct auth_opts_handler
*handler
;
84 warn_opers(L_CRIT
, "BUG: handle_options received too few parameters (at least 2 expected, got %d)", parc
);
88 if((handler
= rb_dictionary_retrieve(authd_option_handlers
, parv
[1])) == NULL
)
90 warn_opers(L_CRIT
, "BUG: handle_options got a bad option type %s", parv
[1]);
94 if((parc
- 2) < handler
->min_parc
)
96 warn_opers(L_CRIT
, "BUG: handle_options received too few parameters (at least %d expected, got %d)", handler
->min_parc
, parc
);
100 handler
->handler(parv
[1], parc
- 2, (const char **)&parv
[2]);
104 handle_reload(int parc
, char *parv
[])
106 authd_reload_handler handler
;
110 /* Reload all handlers */
111 for(size_t i
= 0; i
< 256; i
++)
113 if ((handler
= authd_reload_handlers
[(unsigned char) i
]) != NULL
)
120 if (!(handler
= authd_reload_handlers
[(unsigned char)parv
[1][0]]))
127 parse_request(rb_helper
*helper
)
129 static char *parv
[MAXPARA
+ 1];
130 static char readbuf
[READBUF_SIZE
];
133 authd_cmd_handler handler
;
135 while((len
= rb_helper_read(helper
, readbuf
, sizeof(readbuf
))) > 0)
137 parc
= rb_string_to_array(readbuf
, parv
, MAXPARA
);
142 handler
= authd_cmd_handlers
[(unsigned char)parv
[0][0]];
149 error_cb(rb_helper
*helper
)
156 dummy_handler(int sig
)
166 struct sigaction act
;
169 act
.sa_handler
= SIG_IGN
;
170 sigemptyset(&act
.sa_mask
);
171 sigaddset(&act
.sa_mask
, SIGPIPE
);
172 sigaddset(&act
.sa_mask
, SIGALRM
);
174 sigaddset(&act
.sa_mask
, SIGTRAP
);
178 sigaddset(&act
.sa_mask
, SIGWINCH
);
179 sigaction(SIGWINCH
, &act
, 0);
181 sigaction(SIGPIPE
, &act
, 0);
183 sigaction(SIGTRAP
, &act
, 0);
186 act
.sa_handler
= dummy_handler
;
187 sigaction(SIGALRM
, &act
, 0);
192 main(int argc
, char *argv
[])
196 authd_helper
= rb_helper_child(parse_request
, error_cb
, NULL
, NULL
, NULL
, 256, 256, 256); /* XXX fix me */
197 if(authd_helper
== NULL
)
199 fprintf(stderr
, "authd is not meant to be invoked by end users\n");
206 authd_option_handlers
= rb_dictionary_create("authd options handlers", rb_strcasecmp
);
210 rb_init_prng(NULL
, RB_PRNG_DEFAULT
);
212 rb_helper_loop(authd_helper
, 0);
215 * XXX this function will never be called from here -- is it necessary?