xref: /openbsd-src/usr.sbin/unbound/daemon/remote.h (revision 8b7325af55f9372784d083aa385d31c4cebf9890)
1933707f3Ssthen /*
2933707f3Ssthen  * daemon/remote.h - remote control for the unbound daemon.
3933707f3Ssthen  *
4933707f3Ssthen  * Copyright (c) 2008, NLnet Labs. All rights reserved.
5933707f3Ssthen  *
6933707f3Ssthen  * This software is open source.
7933707f3Ssthen  *
8933707f3Ssthen  * Redistribution and use in source and binary forms, with or without
9933707f3Ssthen  * modification, are permitted provided that the following conditions
10933707f3Ssthen  * are met:
11933707f3Ssthen  *
12933707f3Ssthen  * Redistributions of source code must retain the above copyright notice,
13933707f3Ssthen  * this list of conditions and the following disclaimer.
14933707f3Ssthen  *
15933707f3Ssthen  * Redistributions in binary form must reproduce the above copyright notice,
16933707f3Ssthen  * this list of conditions and the following disclaimer in the documentation
17933707f3Ssthen  * and/or other materials provided with the distribution.
18933707f3Ssthen  *
19933707f3Ssthen  * Neither the name of the NLNET LABS nor the names of its contributors may
20933707f3Ssthen  * be used to endorse or promote products derived from this software without
21933707f3Ssthen  * specific prior written permission.
22933707f3Ssthen  *
23933707f3Ssthen  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
240b68ff31Ssthen  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
250b68ff31Ssthen  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
260b68ff31Ssthen  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
270b68ff31Ssthen  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
280b68ff31Ssthen  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
290b68ff31Ssthen  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
300b68ff31Ssthen  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
310b68ff31Ssthen  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
320b68ff31Ssthen  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
330b68ff31Ssthen  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34933707f3Ssthen  */
35933707f3Ssthen 
36933707f3Ssthen /**
37933707f3Ssthen  * \file
38933707f3Ssthen  *
39933707f3Ssthen  * This file contains the remote control functionality for the daemon.
40933707f3Ssthen  * The remote control can be performed using either the commandline
41933707f3Ssthen  * unbound-control tool, or a SSLv3/TLS capable web browser.
42933707f3Ssthen  * The channel is secured using SSLv3 or TLSv1, and certificates.
43933707f3Ssthen  * Both the server and the client(control tool) have their own keys.
44933707f3Ssthen  */
45933707f3Ssthen 
46933707f3Ssthen #ifndef DAEMON_REMOTE_H
47933707f3Ssthen #define DAEMON_REMOTE_H
48933707f3Ssthen #ifdef HAVE_OPENSSL_SSL_H
49*8b7325afSsthen #include <openssl/ssl.h>
50933707f3Ssthen #endif
51933707f3Ssthen struct config_file;
52933707f3Ssthen struct listen_list;
53933707f3Ssthen struct listen_port;
54933707f3Ssthen struct worker;
55933707f3Ssthen struct comm_reply;
56933707f3Ssthen struct comm_point;
57933707f3Ssthen struct daemon_remote;
58933707f3Ssthen 
5977079be7Ssthen /** number of milliseconds timeout on incoming remote control handshake */
6077079be7Ssthen #define REMOTE_CONTROL_TCP_TIMEOUT 120000
61933707f3Ssthen 
62933707f3Ssthen /**
63933707f3Ssthen  * a busy control command connection, SSL state
64933707f3Ssthen  */
65933707f3Ssthen struct rc_state {
66933707f3Ssthen 	/** the next item in list */
67933707f3Ssthen 	struct rc_state* next;
68933707f3Ssthen 	/** the commpoint */
69933707f3Ssthen 	struct comm_point* c;
70933707f3Ssthen 	/** in the handshake part */
71933707f3Ssthen 	enum { rc_none, rc_hs_read, rc_hs_write } shake_state;
72cebdf579Ssthen #ifdef HAVE_SSL
73933707f3Ssthen 	/** the ssl state */
74933707f3Ssthen 	SSL* ssl;
75cebdf579Ssthen #endif
7620237c55Ssthen 	/** file descriptor */
7720237c55Ssthen         int fd;
78933707f3Ssthen 	/** the rc this is part of */
79933707f3Ssthen 	struct daemon_remote* rc;
80933707f3Ssthen };
81933707f3Ssthen 
82933707f3Ssthen /**
83933707f3Ssthen  * The remote control tool state.
84933707f3Ssthen  * The state is only created for the first thread, other threads
85933707f3Ssthen  * are called from this thread.  Only the first threads listens to
86933707f3Ssthen  * the control port.  The other threads do not, but are called on the
87933707f3Ssthen  * command channel(pipe) from the first thread.
88933707f3Ssthen  */
89933707f3Ssthen struct daemon_remote {
90933707f3Ssthen 	/** the worker for this remote control */
91933707f3Ssthen 	struct worker* worker;
92933707f3Ssthen 	/** commpoints for accepting remote control connections */
93933707f3Ssthen 	struct listen_list* accept_list;
9431f127bbSsthen 	/* if certificates are used */
9531f127bbSsthen 	int use_cert;
96933707f3Ssthen 	/** number of active commpoints that are handling remote control */
97933707f3Ssthen 	int active;
98933707f3Ssthen 	/** max active commpoints */
99933707f3Ssthen 	int max_active;
100933707f3Ssthen 	/** current commpoints busy; should be a short list, malloced */
101933707f3Ssthen 	struct rc_state* busy_list;
102cebdf579Ssthen #ifdef HAVE_SSL
103933707f3Ssthen 	/** the SSL context for creating new SSL streams */
104933707f3Ssthen 	SSL_CTX* ctx;
105cebdf579Ssthen #endif
106933707f3Ssthen };
107933707f3Ssthen 
108933707f3Ssthen /**
10920237c55Ssthen  * Connection to print to, either SSL or plain over fd
11020237c55Ssthen  */
11120237c55Ssthen struct remote_stream {
11220237c55Ssthen #ifdef HAVE_SSL
11320237c55Ssthen 	/** SSL structure, nonNULL if using SSL */
11420237c55Ssthen 	SSL* ssl;
11520237c55Ssthen #endif
11620237c55Ssthen 	/** file descriptor for plain transfer */
11720237c55Ssthen 	int fd;
11820237c55Ssthen };
11920237c55Ssthen typedef struct remote_stream RES;
12020237c55Ssthen 
12120237c55Ssthen /**
122933707f3Ssthen  * Create new remote control state for the daemon.
123933707f3Ssthen  * @param cfg: config file with key file settings.
124933707f3Ssthen  * @return new state, or NULL on failure.
125933707f3Ssthen  */
126933707f3Ssthen struct daemon_remote* daemon_remote_create(struct config_file* cfg);
127933707f3Ssthen 
128933707f3Ssthen /**
129933707f3Ssthen  * remote control state to delete.
130933707f3Ssthen  * @param rc: state to delete.
131933707f3Ssthen  */
132933707f3Ssthen void daemon_remote_delete(struct daemon_remote* rc);
133933707f3Ssthen 
134933707f3Ssthen /**
135933707f3Ssthen  * remote control state to clear up. Busy and accept points are closed.
136933707f3Ssthen  * Does not delete the rc itself, or the ssl context (with its keys).
137933707f3Ssthen  * @param rc: state to clear.
138933707f3Ssthen  */
139933707f3Ssthen void daemon_remote_clear(struct daemon_remote* rc);
140933707f3Ssthen 
141933707f3Ssthen /**
142933707f3Ssthen  * Open and create listening ports for remote control.
143933707f3Ssthen  * @param cfg: config options.
144933707f3Ssthen  * @return list of ports or NULL on failure.
145933707f3Ssthen  *	can be freed with listening_ports_free().
146933707f3Ssthen  */
147933707f3Ssthen struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
148933707f3Ssthen 
149933707f3Ssthen /**
150933707f3Ssthen  * Setup comm points for accepting remote control connections.
151933707f3Ssthen  * @param rc: state
152933707f3Ssthen  * @param ports: already opened ports.
153933707f3Ssthen  * @param worker: worker with communication base. and links to command channels.
154933707f3Ssthen  * @return false on error.
155933707f3Ssthen  */
156933707f3Ssthen int daemon_remote_open_accept(struct daemon_remote* rc,
157933707f3Ssthen 	struct listen_port* ports, struct worker* worker);
158933707f3Ssthen 
159933707f3Ssthen /**
160af4988b1Ssthen  * Stop accept handlers for TCP (until enabled again)
161af4988b1Ssthen  * @param rc: state
162af4988b1Ssthen  */
163af4988b1Ssthen void daemon_remote_stop_accept(struct daemon_remote* rc);
164af4988b1Ssthen 
165af4988b1Ssthen /**
166af4988b1Ssthen  * Stop accept handlers for TCP (until enabled again)
167af4988b1Ssthen  * @param rc: state
168af4988b1Ssthen  */
169af4988b1Ssthen void daemon_remote_start_accept(struct daemon_remote* rc);
170af4988b1Ssthen 
171af4988b1Ssthen /**
172933707f3Ssthen  * Handle nonthreaded remote cmd execution.
173933707f3Ssthen  * @param worker: this worker (the remote worker).
174933707f3Ssthen  */
175933707f3Ssthen void daemon_remote_exec(struct worker* worker);
176933707f3Ssthen 
177cebdf579Ssthen #ifdef HAVE_SSL
178933707f3Ssthen /**
179933707f3Ssthen  * Print fixed line of text over ssl connection in blocking mode
180933707f3Ssthen  * @param ssl: print to
181933707f3Ssthen  * @param text: the text.
182933707f3Ssthen  * @return false on connection failure.
183933707f3Ssthen  */
18420237c55Ssthen int ssl_print_text(RES* ssl, const char* text);
185933707f3Ssthen 
186933707f3Ssthen /**
187933707f3Ssthen  * printf style printing to the ssl connection
18820237c55Ssthen  * @param ssl: the RES connection to print to. Blocking.
189933707f3Ssthen  * @param format: printf style format string.
190933707f3Ssthen  * @return success or false on a network failure.
191933707f3Ssthen  */
19220237c55Ssthen int ssl_printf(RES* ssl, const char* format, ...)
193933707f3Ssthen         ATTR_FORMAT(printf, 2, 3);
194933707f3Ssthen 
195933707f3Ssthen /**
196933707f3Ssthen  * Read until \n is encountered
19720237c55Ssthen  * If stream signals EOF, the string up to then is returned (without \n).
19820237c55Ssthen  * @param ssl: the RES connection to read from. blocking.
199933707f3Ssthen  * @param buf: buffer to read to.
200933707f3Ssthen  * @param max: size of buffer.
201933707f3Ssthen  * @return false on connection failure.
202933707f3Ssthen  */
20320237c55Ssthen int ssl_read_line(RES* ssl, char* buf, size_t max);
204cebdf579Ssthen #endif /* HAVE_SSL */
205933707f3Ssthen 
206933707f3Ssthen #endif /* DAEMON_REMOTE_H */
207