/** * finger_init_client_stream: * @self: FingerProxy instance * * Initialize our client stream. We allocate a readline instance so * that we can fetch input line by line. **/ static gboolean finger_init_client_stream(FingerProxy *self) { ZStream *tmpstream; z_proxy_enter(self); self->super.endpoints[EP_CLIENT]->timeout = self->timeout; tmpstream = self->super.endpoints[EP_CLIENT]; self->super.endpoints[EP_CLIENT] = z_stream_line_new(tmpstream, self->max_line_length, ZRL_EOL_CRLF); z_stream_unref(tmpstream); z_proxy_return(self, TRUE); }
/** * finger_init_server_stream: * @self: FingerProxy instance * * Initialize our server stream. Exit with an error if our server side * is not connected. (ie NULL) **/ static gboolean finger_init_server_stream(FingerProxy *self) { ZStream *tmpstream; z_proxy_enter(self); if (!self->super.endpoints[EP_SERVER]) z_proxy_return(self, FALSE); self->super.endpoints[EP_SERVER]->timeout = self->timeout; tmpstream = self->super.endpoints[EP_SERVER]; self->super.endpoints[EP_SERVER] = z_stream_line_new(tmpstream, self->max_line_length, ZRL_EOL_CRLF); z_stream_unref(tmpstream); z_proxy_return(self, TRUE); }
/** * z_proxy_stack_proxy: * @self: proxy instance * @proxy_class: a Python class to be instantiated as the child proxy * * This function is called to start a child proxy. **/ gboolean z_proxy_stack_proxy(ZProxy *self, ZPolicyObj *proxy_class, ZStackedProxy **stacked, ZPolicyDict *stack_info) { int downpair[2], uppair[2]; ZPolicyObj *res, *client_stream, *server_stream, *stack_info_obj; ZStream *tmpstream; ZStream *client_upstream, *server_upstream; z_proxy_enter(self); if (proxy_class == z_policy_none) { z_policy_var_unref(proxy_class); z_proxy_leave(self); return FALSE; } if (!z_proxy_stack_prepare_streams(self, downpair, uppair)) { z_policy_var_unref(proxy_class); z_proxy_leave(self); return FALSE; } /*LOG This message reports that Zorp is about to stack a proxy class with the given fds as communication channels. */ z_proxy_log(self, CORE_DEBUG, 6, "Stacking subproxy; client='%d:%d', server='%d:%d'", downpair[0], downpair[1], uppair[0], uppair[1]); tmpstream = z_stream_fd_new(downpair[1], ""); client_stream = z_policy_stream_new(tmpstream); z_stream_unref(tmpstream); tmpstream = z_stream_fd_new(uppair[1], ""); server_stream = z_policy_stream_new(tmpstream); z_stream_unref(tmpstream); if (stack_info) { stack_info_obj = z_policy_struct_new(stack_info, Z_PST_SHARED); } else { Py_XINCREF(Py_None); stack_info_obj = Py_None; } res = z_policy_call(self->handler, "stackProxy", z_policy_var_build("(OOOO)", client_stream, server_stream, proxy_class, stack_info_obj), NULL, self->session_id); z_policy_var_unref(client_stream); z_policy_var_unref(server_stream); z_policy_var_unref(stack_info_obj); if (!res || res == z_policy_none || !z_policy_proxy_check(res)) { z_proxy_log(self, CORE_ERROR, 3, "Error stacking subproxy;"); close(downpair[0]); close(downpair[1]); close(uppair[0]); close(uppair[1]); z_policy_var_unref(res); z_proxy_leave(self); return FALSE; } client_upstream = z_stream_fd_new(downpair[0], ""); server_upstream = z_stream_fd_new(uppair[0], ""); *stacked = z_stacked_proxy_new(client_upstream, server_upstream, NULL, self, z_policy_proxy_get_proxy(res), 0); z_policy_var_unref(res); z_proxy_leave(self); return TRUE; }
/** * z_dispatch_accept: * @fdstream Socket stream * @client Address of remote endpoint * @dest Address of original destination * @user_data this * * Internal callback, called when a new incoming connection is established. * Creates and initialises a new ZConnection, and dispatches it to the chain * either synchronously by z_dispatch_connection or asynchronously by pushing * it to the chain's accept queue. * * Note: this function runs in the main thread. * * Returns: TRUE */ static gboolean z_dispatch_accept(ZStream *fdstream, ZSockAddr *client, ZSockAddr *dest, gpointer user_data) { ZConnection *conn = NULL; ZDispatchChain *chain = (ZDispatchChain *) user_data; z_enter(); if (fdstream == NULL) { z_dispatch_connection(chain, NULL); z_return(TRUE); } if (chain->params.common.transparent) { ZSockAddr *listen_addr = NULL; gboolean non_transparent = FALSE; GList *p; switch (chain->registered_key->type) { case ZD_BIND_SOCKADDR: listen_addr = chain->registered_key->sa.addr; non_transparent = z_sockaddr_equal(listen_addr, dest); break; case ZD_BIND_IFACE: case ZD_BIND_IFACE_GROUP: /* NOTE: we are running in the main thread just like the * code that manipulates chain->listeners, thus we don't need to * lock here. This is even true for threaded listeners as * z_dispatch_accept runs in the main thread in that case too. */ for (p = chain->listeners; p; p = p->next) { ZListener *l = ((ZListenerEntry *) p->data)->listener; if (z_sockaddr_equal(l->local, dest)) { non_transparent = TRUE; listen_addr = l->local; break; } } break; } if (non_transparent) { gchar buf1[MAX_SOCKADDR_STRING], buf2[MAX_SOCKADDR_STRING]; /*LOG This message indicates that Listener/Receiver was configured to be accept transparent connections, but it was connected directly. Configure it either non-transparent or deny direct access to it and set up the appropriate TPROXY rule. @see: Listener @see: Receiver */ z_log(chain->session_id, CORE_ERROR, 1, "Transparent listener connected directly, dropping connection; local='%s', client_local='%s'", z_sockaddr_format(listen_addr, buf1, sizeof(buf1)), z_sockaddr_format(dest, buf2, sizeof(buf2))); z_stream_close(fdstream, NULL); z_stream_unref(fdstream); z_sockaddr_unref(client); z_sockaddr_unref(dest); z_return(TRUE); } } conn = z_connection_new(); conn->remote = client; conn->dest = dest; conn->local = z_sockaddr_ref(conn->dest); conn->dispatch_bind = z_dispatch_bind_ref(chain->registered_key); conn->protocol = chain->registered_key->protocol; conn->stream = fdstream; if (chain->threaded) g_async_queue_push(chain->accept_queue, conn); else z_dispatch_connection(chain, conn); z_return(TRUE); }