2 #include <event2/event.h>
14 /* hold a trps instance and a config manager */
15 struct tr_trps_event_cookie {
20 /********** Ersatz TRPC implementation **********/
21 TRPC_INSTANCE *trpc_create (TALLOC_CTX *mem_ctx)
23 return talloc_zero(mem_ctx, TRPC_INSTANCE);
26 void trpc_destroy (TRPC_INSTANCE *trpc)
32 /* Connect to a TRP server */
33 int trpc_open_connection (TRPC_INSTANCE *trpc,
40 unsigned int use_port = 0;
47 tr_debug("trpc_open_connection: opening GSS connection to %s:%d", server, use_port);
48 err = gsscon_connect(server, use_port, "trustrouter", &conn, gssctx);
57 /* simple function, based on tidc_send_req */
58 int trpc_send_msg (TRPC_INSTANCE *trpc,
61 const char *msg_content,
70 /* Send the request over the connection */
71 if (err = gsscon_write_encrypted_token (conn,
74 strlen(msg_content))) {
75 tr_err( "trpc_send_msg: Error sending message over connection.\n");
79 /* Read the response from the connection */
80 if (err = gsscon_read_encrypted_token(conn, gssctx, &resp_buf, &resp_buflen)) {
86 tr_debug( "trpc_send_msg: Response Received (%u bytes).\n", (unsigned) resp_buflen);
87 tr_debug( "%s\n", resp_buf);
90 /* Call the caller's response function */
91 (*resp_handler)(trpc, resp_buf, cookie);
103 /********** Ersatz TRPS implementation **********/
104 TRPS_INSTANCE *trps_create (TALLOC_CTX *mem_ctx)
106 return talloc_zero(mem_ctx, TRPS_INSTANCE);
109 void trps_destroy (TRPS_INSTANCE *trps)
115 static int trps_listen (TRPS_INSTANCE *trps, int port)
122 struct sockaddr_storage storage;
123 struct sockaddr_in in4;
126 struct sockaddr_in *saddr = (struct sockaddr_in *) &addr.in4;
128 saddr->sin_port = htons (port);
129 saddr->sin_family = AF_INET;
130 saddr->sin_addr.s_addr = INADDR_ANY;
132 if (0 > (conn = socket (AF_INET, SOCK_STREAM, 0)))
135 setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
137 if (0 > (rc = bind (conn, (struct sockaddr *) saddr, sizeof(struct sockaddr_in))))
140 if (0 > (rc = listen(conn, 512)))
143 tr_debug("trps_listen: TRP Server listening on port %d", port);
149 /* returns EACCES if authorization is denied */
150 static int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName,
153 TRPS_INSTANCE *inst = (TRPS_INSTANCE *)data;
154 TR_NAME name ={(char *) displayName->value,
155 displayName->length};
158 if (0!=inst->auth_handler(clientName, &name, inst->cookie)) {
159 tr_debug("trps_auth_cb: client '%.*s' denied authorization.", name.len, name.buf);
160 result=EACCES; /* denied */
166 /* returns 0 on authorization success, 1 on failure, or -1 in case of error */
167 static int trps_auth_connection (TRPS_INSTANCE *inst,
169 gss_ctx_id_t *gssctx)
172 int auth, autherr = 0;
173 gss_buffer_desc nameBuffer = {0, NULL};
177 nameLen = asprintf(&name, "trustrouter@%s", inst->hostname);
178 nameBuffer.length = nameLen;
179 nameBuffer.value = name;
181 if (rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, trps_auth_cb, inst)) {
182 tr_debug("trps_auth_connection: Error from gsscon_passive_authenticate(), rc = %d.", rc);
186 if (rc = gsscon_authorize(*gssctx, &auth, &autherr)) {
187 tr_debug("trps_auth_connection: Error from gsscon_authorize, rc = %d, autherr = %d.",
193 tr_debug("trps_auth_connection: Connection authenticated, conn = %d.", conn);
195 tr_debug("trps_auth_connection: Authentication failed, conn %d.", conn);
201 static int tr_trps_req_handler (TRPS_INSTANCE *trps,
206 if (orig_req != NULL)
208 return -1; /* not handling anything right now */
211 static void trps_handle_connection (TRPS_INSTANCE *trps, int conn)
216 static int tr_trps_gss_handler(gss_name_t client_name, TR_NAME *gss_name,
220 struct tr_trps_event_cookie *cookie=(struct tr_trps_event_cookie *)cookie_in;
221 TRPS_INSTANCE *trps = cookie->trps;
222 TR_CFG_MGR *cfg_mgr = cookie->cfg_mgr;
224 tr_debug("tr_trps_gss_handler()");
226 if ((!client_name) || (!gss_name) || (!trps) || (!cfg_mgr)) {
227 tr_debug("tr_trps_gss_handler: Bad parameters.");
231 /* look up the RP client matching the GSS name */
232 if ((NULL == (rp = tr_rp_client_lookup(cfg_mgr->active->rp_clients, gss_name)))) {
233 tr_debug("tr_trps_gss_handler: Unknown GSS name %s", gss_name->buf);
238 tr_debug("Client's GSS Name: %s", gss_name->buf);
244 static int trps_get_listener(TRPS_INSTANCE *trps,
245 TRPS_REQ_FUNC *req_handler,
246 trps_auth_func *auth_handler,
247 const char *hostname,
253 if (0 > (listen = trps_listen(trps, port))) {
255 if (0 == strerror_r(errno, errbuf, 256)) {
256 tr_debug("trps_get_listener: Error opening port %d: %s.", port, errbuf);
258 tr_debug("trps_get_listener: Unknown error openining port %d.", port);
263 /* opening port succeeded */
264 tr_debug("trps_get_listener: Opened port %d.", port);
266 /* make this socket non-blocking */
267 if (0 != fcntl(listen, F_SETFL, O_NONBLOCK)) {
268 tr_debug("trps_get_listener: Error setting O_NONBLOCK.");
275 /* store the caller's request handler & cookie */
276 trps->req_handler = req_handler;
277 trps->auth_handler = auth_handler;
278 trps->hostname = talloc_strdup(trps, hostname);
280 trps->cookie = cookie;
287 /* Accept and process a connection on a port opened with trps_get_listener() */
288 int trps_accept(TRPS_INSTANCE *trps, int listen)
292 conn = accept(listen, NULL, NULL);
295 perror("Error from TRP Server accept()");
299 /* does not fork, handles request in main process */
300 trps_handle_connection(trps, conn);
301 write(conn, "TRP Online\n", strlen("TRP Online\n"));
307 /********** Event Handling **********/
309 /* called when a connection to the TRPS port is received */
310 static void tr_trps_event_cb(int listener, short event, void *arg)
312 TRPS_INSTANCE *trps = (TRPS_INSTANCE *)arg;
314 if (0==(event & EV_READ))
315 tr_debug("tr_trps_event_cb: unexpected event on TRPS socket (event=0x%X)", event);
317 trps_accept(trps, listener);
321 /* Configure the trps instance and set up its event handler.
322 * Returns 0 on success, nonzero on failure. Fills in
323 * *trps_event (which should be allocated by caller). */
324 int tr_trps_event_init(struct event_base *base,
327 struct tr_socket_event *trps_ev)
329 TALLOC_CTX *tmp_ctx=talloc_new(NULL);
330 struct tr_trps_event_cookie *cookie;
333 if (trps_ev == NULL) {
334 tr_debug("tr_trps_event_init: Null trps_ev.");
339 /* Create the cookie for callbacks. It is part of the trps context, so it will
340 * be cleaned up when trps is freed by talloc_free. */
341 cookie=talloc(tmp_ctx, struct tr_trps_event_cookie);
342 if (cookie == NULL) {
343 tr_debug("tr_trps_event_init: Unable to allocate cookie.");
348 cookie->cfg_mgr=cfg_mgr;
349 talloc_steal(trps, cookie);
351 /* get a trps listener */
352 trps_ev->sock_fd=trps_get_listener(trps,
355 cfg_mgr->active->internal->hostname,
356 cfg_mgr->active->internal->trps_port,
358 if (trps_ev->sock_fd < 0) {
359 tr_crit("Error opening TRP server socket.");
365 trps_ev->ev=event_new(base,
370 event_add(trps_ev->ev, NULL);
373 talloc_free(tmp_ctx);