diff options
author | Omar Polo <op@omarpolo.com> | 2023-06-08 13:59:31 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2023-06-08 13:59:31 +0000 |
commit | c26f2460e42aa0822c283c805958989f339e7d8b (patch) | |
tree | 423410fae4de90b2b753ccad621d364c4641bed2 /proc.h | |
parent | 99f1fbb0c73b6f62b966760181b3d97f54bbe73b (diff) |
rework the daemon to do fork+exec
It uses the 'common' proc.c from various OpenBSD-daemons.
gmid grew organically bit by bit and it was also the first place where I
tried to implement privsep. It wasn't done very well, in fact the
parent process (that retains root privileges) just fork()s a generation
of servers, all sharing *exactly* the same address space. No good!
Now, we fork() and re-exec() ourselves, so that each process has a fresh
address space.
Some features (require client ca for example) are temporarly disabled,
will be fixed in subsequent commits. The "ge" program is also
temporarly disabled as it needs tweaks to do privsep too.
Diffstat (limited to 'proc.h')
-rw-r--r-- | proc.h | 123 |
1 files changed, 123 insertions, 0 deletions
@@ -0,0 +1,123 @@ +/* + * Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* imsg */ +struct imsgev { + struct imsgbuf ibuf; + void (*handler)(int, short, void *); + struct event ev; + struct privsep_proc *proc; + void *data; + short events; +}; + +#define IMSG_SIZE_CHECK(imsg, p) do { \ + if (IMSG_DATA_SIZE(imsg) < sizeof(*p)) \ + fatalx("bad length imsg received (%s)", #p); \ +} while (0) +#define IMSG_DATA_SIZE(imsg) ((imsg)->hdr.len - IMSG_HEADER_SIZE) + +#define PROC_PARENT_SOCK_FILENO 3 + +/* privsep */ +enum privsep_procid { + PROC_PARENT, + PROC_SERVER, + PROC_LOGGER, + PROC_MAX, +}; + +#define CONFIG_RELOAD 0x00 +#define CONFIG_SOCKS 0x01 +#define CONFIG_ALL 0xff + +struct privsep_pipes { + int *pp_pipes[PROC_MAX]; +}; + +struct privsep { + struct privsep_pipes *ps_pipes[PROC_MAX]; + struct privsep_pipes *ps_pp; + + struct imsgev *ps_ievs[PROC_MAX]; + const char *ps_title[PROC_MAX]; + uint8_t ps_what[PROC_MAX]; + + struct passwd *ps_pw; + int ps_noaction; + + unsigned int ps_instances[PROC_MAX]; + unsigned int ps_instance; + + /* Event and signal handlers */ + struct event ps_evsigint; + struct event ps_evsigterm; + struct event ps_evsigchld; + struct event ps_evsighup; + + void *ps_env; +}; + +struct privsep_proc { + const char *p_title; + enum privsep_procid p_id; + int (*p_cb)(int, struct privsep_proc *, + struct imsg *); + void (*p_init)(struct privsep *, + struct privsep_proc *); + void (*p_shutdown)(void); + const char *p_chroot; + struct passwd *p_pw; + struct privsep *p_ps; +}; + +struct privsep_fd { + enum privsep_procid pf_procid; + unsigned int pf_instance; +}; + +/* proc.c */ +void proc_init(struct privsep *, struct privsep_proc *, unsigned int, + int, int, char **, enum privsep_procid); +void proc_kill(struct privsep *); +void proc_connect(struct privsep *ps); +void proc_dispatch(int, short event, void *); +void proc_range(struct privsep *, enum privsep_procid, int *, int *); +void proc_run(struct privsep *, struct privsep_proc *, + struct privsep_proc *, unsigned int, + void (*)(struct privsep *, struct privsep_proc *, void *), void *); +void imsg_event_add(struct imsgev *); +int imsg_compose_event(struct imsgev *, uint16_t, uint32_t, + pid_t, int, void *, uint16_t); +int imsg_composev_event(struct imsgev *, uint16_t, uint32_t, + pid_t, int, const struct iovec *, int); +int proc_compose_imsg(struct privsep *, enum privsep_procid, int, + uint16_t, uint32_t, int, void *, uint16_t); +int proc_compose(struct privsep *, enum privsep_procid, + uint16_t, void *data, uint16_t); +int proc_composev_imsg(struct privsep *, enum privsep_procid, int, + uint16_t, uint32_t, int, const struct iovec *, int); +int proc_composev(struct privsep *, enum privsep_procid, + uint16_t, const struct iovec *, int); +int proc_forward_imsg(struct privsep *, struct imsg *, + enum privsep_procid, int); +struct imsgbuf * + proc_ibuf(struct privsep *, enum privsep_procid, int); +struct imsgev * + proc_iev(struct privsep *, enum privsep_procid, int); +enum privsep_procid + proc_getid(struct privsep_proc *, unsigned int, const char *); +int proc_flush_imsg(struct privsep *, enum privsep_procid, int); |