2 #include <event2/event.h>
14 /* hold a trps instance and a config manager */
15 struct tr_trps_event_cookie {
21 /********** Ersatz TRPS implementation **********/
22 TRPS_INSTANCE *trps_create (TALLOC_CTX *mem_ctx)
24 return talloc_zero(mem_ctx, TRPS_INSTANCE);
27 void trps_destroy (TRPS_INSTANCE *trps)
33 static int trps_listen (TRPS_INSTANCE *trps, int port)
40 struct sockaddr_storage storage;
41 struct sockaddr_in in4;
44 struct sockaddr_in *saddr = (struct sockaddr_in *) &addr.in4;
46 saddr->sin_port = htons (port);
47 saddr->sin_family = AF_INET;
48 saddr->sin_addr.s_addr = INADDR_ANY;
50 if (0 > (conn = socket (AF_INET, SOCK_STREAM, 0)))
53 setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
55 if (0 > (rc = bind (conn, (struct sockaddr *) saddr, sizeof(struct sockaddr_in))))
58 if (0 > (rc = listen(conn, 512)))
61 tr_debug("trps_listen: TRP Server listening on port %d", port);
67 /* returns EACCES if authorization is denied */
68 static int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName,
71 TRPS_INSTANCE *inst = (TRPS_INSTANCE *)data;
72 TR_NAME name ={(char *) displayName->value,
76 if (0!=inst->auth_handler(clientName, &name, inst->cookie)) {
77 tr_debug("trps_auth_cb: client '%.*s' denied authorization.", name.len, name.buf);
78 result=EACCES; /* denied */
84 /* returns 0 on authorization success, 1 on failure, or -1 in case of error */
85 static int trps_auth_connection (TRPS_INSTANCE *inst,
90 int auth, autherr = 0;
91 gss_buffer_desc nameBuffer = {0, NULL};
95 nameLen = asprintf(&name, "trustrouter@%s", inst->hostname);
96 nameBuffer.length = nameLen;
97 nameBuffer.value = name;
99 if (rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, trps_auth_cb, inst)) {
100 tr_debug("trps_auth_connection: Error from gsscon_passive_authenticate(), rc = %d.", rc);
104 if (rc = gsscon_authorize(*gssctx, &auth, &autherr)) {
105 tr_debug("trps_auth_connection: Error from gsscon_authorize, rc = %d, autherr = %d.",
111 tr_debug("trps_auth_connection: Connection authenticated, conn = %d.", conn);
113 tr_debug("trps_auth_connection: Authentication failed, conn %d.", conn);
119 static int tr_trps_req_handler (TRPS_INSTANCE *trps,
124 if (orig_req != NULL)
126 return -1; /* not handling anything right now */
129 static void trps_handle_connection (TRPS_INSTANCE *trps, int conn)
134 static int tr_trps_gss_handler(gss_name_t client_name, TR_NAME *gss_name,
138 struct tr_trps_event_cookie *cookie=(struct tr_trps_event_cookie *)cookie_in;
139 TRPS_INSTANCE *trps = cookie->trps;
140 TR_CFG_MGR *cfg_mgr = cookie->cfg_mgr;
142 tr_debug("tr_trps_gss_handler()");
144 if ((!client_name) || (!gss_name) || (!trps) || (!cfg_mgr)) {
145 tr_debug("tr_trps_gss_handler: Bad parameters.");
149 /* look up the RP client matching the GSS name */
150 if ((NULL == (rp = tr_rp_client_lookup(cfg_mgr->active->rp_clients, gss_name)))) {
151 tr_debug("tr_trps_gss_handler: Unknown GSS name %s", gss_name->buf);
156 tr_debug("Client's GSS Name: %s", gss_name->buf);
162 static int trps_get_listener(TRPS_INSTANCE *trps,
163 TRPS_REQ_FUNC *req_handler,
164 trps_auth_func *auth_handler,
165 const char *hostname,
171 if (0 > (listen = trps_listen(trps, port))) {
173 if (0 == strerror_r(errno, errbuf, 256)) {
174 tr_debug("trps_get_listener: Error opening port %d: %s.", port, errbuf);
176 tr_debug("trps_get_listener: Unknown error openining port %d.", port);
181 /* opening port succeeded */
182 tr_debug("trps_get_listener: Opened port %d.", port);
184 /* make this socket non-blocking */
185 if (0 != fcntl(listen, F_SETFL, O_NONBLOCK)) {
186 tr_debug("trps_get_listener: Error setting O_NONBLOCK.");
193 /* store the caller's request handler & cookie */
194 trps->req_handler = req_handler;
195 trps->auth_handler = auth_handler;
196 trps->hostname = talloc_strdup(trps, hostname);
198 trps->cookie = cookie;
205 /* Accept and process a connection on a port opened with trps_get_listener() */
206 int trps_accept(TRPS_INSTANCE *trps, int listen)
210 conn = accept(listen, NULL, NULL);
213 perror("Error from TRP Server accept()");
217 /* does not fork, handles request in main process */
218 trps_handle_connection(trps, conn);
219 write(conn, "TRP Online\n", strlen("TRP Online\n"));
225 /********** Event Handling **********/
227 /* called when a connection to the TRPS port is received */
228 static void tr_trps_event_cb(int listener, short event, void *arg)
230 TRPS_INSTANCE *trps = (TRPS_INSTANCE *)arg;
232 if (0==(event & EV_READ))
233 tr_debug("tr_trps_event_cb: unexpected event on TRPS socket (event=0x%X)", event);
235 trps_accept(trps, listener);
239 /* Configure the trps instance and set up its event handler.
240 * Returns 0 on success, nonzero on failure. Fills in
241 * *trps_event (which should be allocated by caller). */
242 int tr_trps_event_init(struct event_base *base,
245 struct tr_socket_event *trps_ev)
247 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
248 struct tr_trps_event_cookie *cookie;
251 if (trps_ev == NULL) {
252 tr_debug("tr_trps_event_init: Null trps_ev.");
257 /* Create the cookie for callbacks. It is part of the trps context, so it will
258 * be cleaned up when trps is freed by talloc_free. */
259 cookie=talloc(tmp_ctx, struct tr_trps_event_cookie);
260 if (cookie == NULL) {
261 tr_debug("tr_trps_event_init: Unable to allocate cookie.");
266 cookie->cfg_mgr=cfg_mgr;
267 talloc_steal(trps, cookie);
269 /* get a trps listener */
270 trps_ev->sock_fd=trps_get_listener(trps,
273 cfg_mgr->active->internal->hostname,
274 cfg_mgr->active->internal->trps_port,
276 if (trps_ev->sock_fd < 0) {
277 tr_crit("Error opening TRP server socket.");
283 trps_ev->ev=event_new(base,
288 event_add(trps_ev->ev, NULL);
291 talloc_free(tmp_ctx);