2 * Copyright (c) 2018, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include <tr_config.h>
39 #include <mon_internal.h>
43 * Cookie for the event handling callback
45 struct tr_mons_event_cookie {
52 * Callback to handle a triggered event
54 * @param listener file descriptor of the socket that triggered the event
55 * @param event libevent2 event
56 * @param arg pointer to our MONS_INSTANCE
58 static void tr_mons_event_cb(int listener, short event, void *arg)
60 MONS_INSTANCE *mons = talloc_get_type_abort(arg, MONS_INSTANCE);
62 // check that we were not accidentally triggered
63 if (0==(event & EV_READ))
64 tr_debug("tr_mons_event_cb: unexpected event on monitoring interface socket (event=0x%X)", event);
66 mons_accept(mons, listener);
71 * Callback to handle an incoming monitoring request
73 * @param mons monitoring interface instance
74 * @param orig_req incoming request
75 * @param resp destination for outgoing response
76 * @param cookie_in cookie from the event handling system
77 * @return 0 on success
79 static int tr_mons_req_handler(MONS_INSTANCE *mons,
88 * Callback to authorize a GSS client
90 * @param client_name ?
91 * @param gss_name GSS name of credential attempting to authorize
92 * @param cookie_in event cookie
93 * @return 0 if authorization is successful, -1 if not
95 static int tr_mons_auth_handler(gss_name_t client_name, TR_NAME *gss_name, void *cookie_in)
97 struct tr_mons_event_cookie *cookie=talloc_get_type_abort(cookie_in, struct tr_mons_event_cookie);
98 MONS_INSTANCE *mons = cookie->mons;
100 if ((!client_name) || (!gss_name) || (!mons)) {
101 tr_debug("tr_mons_gss_handler: Bad parameters.");
105 /* Ensure at least one client exists using this GSS name */
106 if (! tr_gss_names_matches(mons->authorized_gss_names, gss_name)) {
107 tr_info("tr_mons_gss_handler: Unauthorized request from %.*s", gss_name->len, gss_name->buf);
111 /* Credential was valid, authorize it */
112 tr_info("tr_mons_gss_handler: Authorized request from %.*s", gss_name->len, gss_name->buf);
119 * Get a listener for monitoring requests, returns its socket fd. Accept
120 * connections with tids_accept() */
123 * Configure the monitoring service instance and set up its event handler
125 * @param base libevent2 event base
126 * @param mons MONS_INSTANCE for this monitoring interface
127 * @param cfg_mgr configuration manager instance
128 * @param mons_ev monitoring interface event instance
129 * @return 0 on success, nonzero on failure.
131 int tr_mons_event_init(struct event_base *base,
134 struct tr_socket_event *mons_ev)
136 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
137 struct tr_mons_event_cookie *cookie=NULL;
141 if (mons_ev == NULL) {
142 tr_debug("tr_mon_event_init: Null mons_ev.");
147 if (cfg_mgr->active->internal->mons_port == 0) {
148 tr_notice("tr_mons_event_init: monitoring is disabled, not enabling events or opening sockets");
153 /* Create the cookie for callbacks. We'll put it in the mons context, so it will
154 * be cleaned up when mons is freed by talloc_free. */
155 cookie=talloc(tmp_ctx, struct tr_mons_event_cookie);
156 if (cookie == NULL) {
157 tr_debug("tr_mons_event_init: Unable to allocate cookie.");
162 cookie->cfg_mgr=cfg_mgr;
163 talloc_steal(mons, cookie);
165 /* get a monitoring interface listener */
166 mons_ev->n_sock_fd = mons_get_listener(mons, tr_mons_req_handler,
167 tr_mons_auth_handler,
168 cfg_mgr->active->internal->hostname,
169 cfg_mgr->active->internal->mons_port,
170 (void *) cookie, mons_ev->sock_fd,
172 if (mons_ev->n_sock_fd==0) {
173 tr_crit("Error opening monitoring interface socket.");
179 for (ii=0; ii<mons_ev->n_sock_fd; ii++) {
180 mons_ev->ev[ii]=event_new(base,
181 mons_ev->sock_fd[ii],
185 event_add(mons_ev->ev[ii], NULL);
189 talloc_free(tmp_ctx);