/** * telnet_stream_write: * @self: * @buf: * @ep: * * * * Returns: * */ static GIOStatus telnet_stream_write(TelnetProxy *self, ZIOBufferDyn *buf, guint ep) { GIOStatus res; gsize bytes_written; z_proxy_enter(self); if (buf->ofs != buf->end) { res = z_stream_write(self->super.endpoints[ep], &buf->buf[buf->ofs], buf->end - buf->ofs, &bytes_written, NULL); switch (res) { case G_IO_STATUS_NORMAL: buf->ofs += bytes_written; break; case G_IO_STATUS_AGAIN: break; default: z_proxy_return(self, G_IO_STATUS_ERROR); } if (buf->ofs != buf->end) { self->super.endpoints[ep]->want_write = TRUE; z_proxy_return(self, G_IO_STATUS_AGAIN); } } z_proxy_return(self, G_IO_STATUS_NORMAL); }
/** * z_transfer2_write_dest: * @self: ZTransfer2 instance * @endpoint: endpoint to send data to * @buf: send data from this buffer * @error: error details are stored here * * This function is called to send data to the specified endpoint. When * it is a proxy-connected stream then the proxy provided callbacks are * used to send information, otherwise z_stream_write is called directly. **/ static GIOStatus z_transfer2_write_dest(ZTransfer2 *self, gint endpoint, ZTransfer2Buffer *buf, GError **error) { ZStream *to = z_transfer2_get_stream(self, endpoint); GError *local_error = NULL; GIOStatus res = G_IO_STATUS_NORMAL; gsize bytes_written; z_proxy_enter(self->owner); if (!z_transfer2_buffer_empty(buf)) { if (endpoint & ZT2E_STACKED) res = z_stream_write(to, &buf->buf[buf->ofs], buf->end - buf->ofs, &bytes_written, &local_error); else res = z_transfer2_dst_write(self, to, &buf->buf[buf->ofs], buf->end - buf->ofs, &bytes_written, &local_error); switch (res) { case G_IO_STATUS_NORMAL: buf->ofs += bytes_written; if (!z_transfer2_buffer_empty(buf)) { res = G_IO_STATUS_AGAIN; } default: break; } } if (local_error) g_propagate_error(error, local_error); z_proxy_leave(self->owner); return res; }
/** * http_ftp_send_command: * @self: HttpProxy instance * @cmd: FTP command to send * @param: parameter to @cmd * * Send a command to the FTP server. **/ static gboolean http_ftp_send_command(HttpProxy *self, const gchar *cmd, const gchar *param) { gchar request_msg[1024]; gsize bw; if (param) g_snprintf(request_msg, sizeof(request_msg), "%s %s\r\n", cmd, param); else g_snprintf(request_msg, sizeof(request_msg), "%s\r\n", cmd); if (z_stream_write(self->super.endpoints[EP_SERVER], request_msg, strlen(request_msg), &bw, NULL) != G_IO_STATUS_NORMAL) return FALSE; return TRUE; }
/** * finger_query_policy: * @self: FingerProxy instance * * Check the policy about the current request. **/ static gboolean finger_query_policy(FingerProxy *self) { char *errmsg = "Policy violation, request denied.\r\n"; gsize bytes_written; gint res; z_proxy_enter(self); z_policy_lock(self->super.thread); res = z_policy_event(self->super.handler, "fingerRequest", z_policy_var_build("(ss)", self->username->str, self->hostnames->str), self->super.session_id); switch (res) { case FINGER_REQ_UNSPEC: case FINGER_REQ_REJECT: case FINGER_REQ_ABORT: /*LOG This message is about administrator decision to reject the finger session. */ z_proxy_log(self, FINGER_POLICY, 2, "Policy violation, abort session;"); z_stream_write(self->super.endpoints[EP_CLIENT], errmsg, strlen(errmsg), &bytes_written, NULL); /* fallthrough */ case FINGER_REQ_DROP: if (res == ZV_DROP) { /*LOG This message is about administrator decision to drop finger session. */ z_proxy_log(self, FINGER_POLICY, 2, "Policy violation, drop session;"); } z_policy_unlock(self->super.thread); z_proxy_return(self, FALSE); case FINGER_REQ_ACCEPT: default: break; } z_policy_unlock(self->super.thread); z_proxy_return(self, TRUE); }
/** * finger_main: * @s: FingerProxy instance * * main proxy routine. **/ static void finger_main(ZProxy *s) { FingerProxy *self = Z_CAST(s, FingerProxy); z_proxy_enter(self); if (!finger_init_client_stream(self)) z_proxy_return(self); /*LOG This debug message is about proxy state when start to fetching request */ z_proxy_log(self, FINGER_DEBUG, 6, "fetching request;"); if (!finger_fetch_request(self)) { char *errmsg = "Finger protocol or disallowed protocol element, request denied.\r\n"; gsize bytes_written; z_stream_write(self->super.endpoints[EP_CLIENT], errmsg, strlen(errmsg), &bytes_written, NULL); z_proxy_return(self); } /*LOG This debug message is about proxy state when finger fetched request and asking policy about it */ z_proxy_log(self, FINGER_DEBUG, 6, "asking policy;"); if (!finger_query_policy(self)) z_proxy_return(self); /*LOG This debug message is about proxy state when finger start connect to server. */ z_proxy_log(self, FINGER_DEBUG, 6, "connecting server;"); /* this sets the server side endpoint if successful */ if (!z_proxy_connect_server(&self->super, NULL, 0)) z_proxy_return(self); if (!finger_init_server_stream(self)) z_proxy_return(self); /*LOG This debug message is about proxy state when finger start send the request to server. */ z_proxy_log(self, FINGER_DEBUG, 6, "sending request;"); if (!finger_send_request(self)) z_proxy_return(self); /*LOG This debug message is about proxy state when finger start to copy server answer to client. */ z_proxy_log(self, FINGER_DEBUG, 6, "copying response;"); if (!finger_copy_response(self)) z_proxy_return(self); /*LOG This debug message is about proxy state when finger stop it's work. */ z_proxy_log(self, FINGER_DEBUG, 6, "everything is done;"); z_proxy_return(self); }
/** * finger_copy_response: * @self: FingerProxy instance * * Copy server's response to the client. * **/ static gboolean finger_copy_response(FingerProxy *self) { gsize bytes_written; gint res = G_IO_STATUS_ERROR; z_proxy_enter(self); if (self->response_header->len && z_stream_write(self->super.endpoints[EP_CLIENT], self->response_header->str, self->response_header->len, &bytes_written, NULL) != G_IO_STATUS_NORMAL) { /*LOG This message appear when some error found in client side when writting the header. */ z_proxy_log(self, FINGER_ERROR, 1, "Error write request;"); z_proxy_return(self, FALSE); } while (1) { gchar *line; gsize line_len; gchar *response; if (!z_proxy_loop_iteration(&self->super)) break; res = z_stream_line_get(self->super.endpoints[EP_SERVER], &line, &line_len, NULL); if (res != G_IO_STATUS_NORMAL) /* EOF or read error */ break; response = alloca(line_len + 3); memcpy(response, line, line_len); strcpy(response + line_len, "\r\n"); if (z_stream_write(self->super.endpoints[EP_CLIENT], response, line_len + 2, &bytes_written, NULL) != G_IO_STATUS_NORMAL) { /*LOG This message appear when some error found in client side when writting the response. */ z_proxy_log(self, FINGER_ERROR, 1, "Error write request;"); z_proxy_return(self, FALSE); } } if (res != G_IO_STATUS_ERROR && self->response_footer->len && z_stream_write(self->super.endpoints[EP_CLIENT], self->response_footer->str, self->response_footer->len, &bytes_written, NULL) != G_IO_STATUS_NORMAL) { /*LOG This message appear when some error found in client side when writting the footer. */ z_proxy_log(self, FINGER_ERROR, 1, "Error write request;"); z_proxy_return(self, FALSE); } z_proxy_return(self, TRUE); }
/** * finger_send_request: * @self: FingerProxy instance * * Construct and send a request to the server based on the state * stored by finger_fetch_request(). **/ static gboolean finger_send_request(FingerProxy *self) { gchar request[self->username->len + self->hostnames->len + 6]; gsize bytes_written; z_proxy_enter(self); if (self->long_req) { if (self->username->len > 0) { if (self->hostnames->len > 0) g_snprintf(request, sizeof(request), "/W %s%s\r\n", self->username->str, self->hostnames->str); else g_snprintf(request, sizeof(request), "/W %s\r\n", self->username->str); } else { if (self->hostnames->len > 0) g_snprintf(request, sizeof(request), "/W %s\r\n", self->hostnames->str); else g_snprintf(request, sizeof(request), "/W\r\n"); } } else { if (self->username->len > 0) { if (self->hostnames->len > 0) g_snprintf(request, sizeof(request), "%s%s\r\n", self->username->str, self->hostnames->str); else g_snprintf(request, sizeof(request), "%s\r\n", self->username->str); } else { if (self->hostnames->len > 0) g_snprintf(request, sizeof(request), "%s\r\n", self->hostnames->str); else g_snprintf(request, sizeof(request), "\r\n"); } } if (z_stream_write(self->super.endpoints[EP_SERVER], request, strlen(request), &bytes_written, NULL) != G_IO_STATUS_NORMAL) { /*LOG This message appear when some error found in server side. */ z_proxy_log(self, FINGER_ERROR, 1, "Error write request;"); z_proxy_return(self, FALSE); } z_proxy_return(self, TRUE); }