gboolean ftp_policy_parse_authinfo(FtpProxy *self, const gchar *cmd, GString *param) { gboolean called = FALSE; PyObject *result = NULL; PyObject *args = NULL; gboolean ret; z_proxy_enter(self); z_policy_lock(self->super.thread); args = z_policy_var_build("ss", cmd, param->str); result = z_policy_call(self->super.handler, "parseInbandAuth", args, &called, self->super.session_id); if (!called) { z_policy_unlock(self->super.thread); z_proxy_return(self, FALSE); } if (result == NULL || !z_policy_var_parse(result, "i", &ret)) ret = FALSE; if (result) z_policy_var_unref(result); z_policy_unlock(self->super.thread); z_proxy_return(self, ret); }
gboolean smtp_policy_is_extension_permitted(SmtpProxy *self, gchar *extension) { ZPolicyObj *e; SmtpExtensionDesc *ed; SmtpActionTypes verdict = SMTP_EXT_DROP; gboolean found; z_proxy_enter(self); /* compatibility, check permit_extensions first */ ed = g_hash_table_lookup(known_extensions, extension); if (ed && (self->permit_extensions & ed->extension_mask)) z_proxy_return(self, TRUE); e = g_hash_table_lookup(self->extensions, extension); if (!e) e = g_hash_table_lookup(self->extensions, "*"); if (!e) z_proxy_return(self, FALSE); z_policy_lock(self->super.thread); found = smtp_hash_get_type(e, &verdict); z_policy_unlock(self->super.thread); z_proxy_return(self, found && (verdict == SMTP_EXT_ACCEPT)); }
gboolean ftp_policy_bounce_check(FtpProxy *self, guint side, ZSockAddr *remote, gboolean connect) { PyObject *zsock; gboolean called; ZPolicyObj *res; gboolean ret; z_proxy_enter(self); z_policy_lock(self->super.thread); zsock = z_policy_sockaddr_new(remote); res = z_policy_call(self->super.handler, "bounceCheck", z_policy_var_build("(Oii)", zsock, side, connect), &called, self->super.session_id); if (!called) { z_policy_unlock(self->super.thread); z_proxy_return(self, TRUE); } if ((res == NULL) || !z_policy_var_parse(res, "i", &ret)) ret = FALSE; z_policy_var_unref(res); z_policy_var_unref(zsock); z_policy_unlock(self->super.thread); z_proxy_return(self, ret); }
/** * 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); }
/** * telnet_set_defaults: * @self: * * */ static void telnet_set_defaults(TelnetProxy *self) { z_proxy_enter(self); self->telnet_policy = z_dim_hash_table_new(1, 2, DIMHASH_WILDCARD, DIMHASH_WILDCARD); for (int i = 0; i < 256; i++) self->telnet_suboptions[i] = NULL; for (int i = 0; i < 256; i++) self->telnet_option_negotiation_handlers[i] = NULL; self->policy_name = g_string_new(""); self->policy_value = g_string_new(""); self->timeout = 600000; self->transparent = TRUE; self->gw_auth_required = FALSE; self->server_stream_initialized = FALSE; self->server_hostname = g_string_new(""); self->server_username = g_string_new(""); self->gw_username = g_string_new(""); self->gw_password = g_string_new(""); self->server_port = 23; self->greeting = g_string_new("Welcome to Zorp!\r\n\r\n"); self->server_name_prompt = g_string_new("Server: "); self->gw_username_prompt = g_string_new("Gateway user name: "); self->gw_password_prompt = g_string_new("Gateway password: "); self->negotiation = g_hash_table_new(g_str_hash, g_str_equal); z_proxy_return(self); }
/** * telnet_stream_read: * @self: * @buf: * @ep: * * * * Returns: * */ static GIOStatus telnet_stream_read(TelnetProxy *self, ZIOBuffer *buf, guint ep) { GIOStatus res; gsize len; z_proxy_enter(self); len = 0; res = z_stream_read(self->super.endpoints[ep], buf->buf + buf->end, sizeof(buf->buf) - buf->end, &len, NULL); buf->end += len; switch (res) { case G_IO_STATUS_NORMAL: z_proxy_return(self, res); case G_IO_STATUS_EOF: z_proxy_return(self, res); case G_IO_STATUS_AGAIN: z_proxy_return(self, res); default: break; } z_proxy_return(self, G_IO_STATUS_ERROR); }
/** * telnet_register_vars: * @self: * * */ static void telnet_register_vars(TelnetProxy *self) { z_proxy_enter(self); z_proxy_var_new(&self->super, "option", Z_VAR_TYPE_DIMHASH | Z_VAR_GET | Z_VAR_GET_CONFIG, self->telnet_policy); z_proxy_var_new(&self->super, "negotiation", Z_VAR_TYPE_HASH | Z_VAR_GET | Z_VAR_GET_CONFIG, self->negotiation); z_proxy_var_new(&self->super, "current_var_name", Z_VAR_TYPE_STRING | Z_VAR_GET | Z_VAR_SET, self->policy_name); z_proxy_var_new(&self->super, "current_var_value", Z_VAR_TYPE_STRING | Z_VAR_GET | Z_VAR_SET, self->policy_value); z_proxy_var_new(&self->super, "timeout", Z_VAR_TYPE_INT | Z_VAR_GET | Z_VAR_SET_CONFIG, &self->timeout); z_proxy_return(self); }
/** * 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; }
/** * anypy_set_verdict: * @self: AnyPyProxy instance * @args: Python args argument * * sets verdict for the parent proxy * args is (verdict,description) **/ static ZPolicyObj * anypy_set_verdict(AnyPyProxy * self, ZPolicyObj *args) { gint verdict; gchar *description; z_proxy_enter(self); if (!z_policy_var_parse_tuple(args, "is", &verdict, &description)) { z_policy_raise_exception_obj(z_policy_exc_value_error, "Invalid arguments."); z_proxy_return(self, NULL); } if (self->super.parent_proxy) { ZProxyStackIface *iface; iface = z_proxy_find_iface(self->super.parent_proxy, Z_CLASS(ZProxyStackIface)); if (iface) { z_proxy_stack_iface_set_verdict(iface, verdict, description); z_object_unref(&iface->super); } } z_proxy_return(self, z_policy_none_ref()); }
/** * z_proxy_stack_prepare_streams: * @self: ZProxy instance * @downpair: * @uppair: * **/ static gboolean z_proxy_stack_prepare_streams(ZProxy *self, gint *downpair, gint *uppair) { z_proxy_enter(self); if (socketpair(AF_UNIX, SOCK_STREAM, 0, downpair) == -1) { /*LOG This message indicates that stacking a child proxy failed, because creating an AF_UNIX domain socketpair failed on the client side. */ z_proxy_log(self, CORE_ERROR, 1, "Error creating client socketpair for stacked proxy; error='%s'", g_strerror(errno)); z_proxy_leave(self); return FALSE; } else if (socketpair(AF_UNIX, SOCK_STREAM, 0, uppair) == -1) { close(downpair[0]); close(downpair[1]); /*LOG This message indicates that stacking a child proxy failed, because creating an AF_UNIX domain socketpair failed on the server side. */ z_proxy_log(self, CORE_ERROR, 1, "Error creating server socketpair for stacked proxy; error='%s'", g_strerror(errno)); z_proxy_leave(self); return FALSE; } z_proxy_leave(self); return TRUE; }
/** * z_transfer2_read_source: * @self: ZTransfer2 instance * @endpoint: endpoint to fetch data from * @buf: store fetched information into this buffer * @error: error details are stored here * * This function is called to fetch data from the specified endpoint. When * it is a proxy-connected stream then the proxy provided callbacks are * used to fetch information, otherwise z_stream_read is called directly. **/ static GIOStatus z_transfer2_read_source(ZTransfer2 *self, gint endpoint, ZTransfer2Buffer *buf, GError **error) { ZStream *from = z_transfer2_get_stream(self, endpoint); GIOStatus res = G_IO_STATUS_NORMAL; GError *local_error = NULL; gsize read_len; z_proxy_enter(self->owner); if (endpoint & ZT2E_STACKED) { res = z_stream_read(from, &buf->buf[buf->end], buf->size - buf->end, &read_len, &local_error); } else if (endpoint == ZT2E_SOURCE) { res = z_transfer2_src_read(self, self->endpoints[endpoint], &buf->buf[buf->end], buf->size - buf->end, &read_len, &local_error); } if (res == G_IO_STATUS_NORMAL) { buf->end += read_len; } if (local_error) g_propagate_error(error, local_error); z_proxy_leave(self->owner); return res; }
guint Pop3AnswerParseQUIT(Pop3Proxy *self) { z_proxy_enter(self); self->pop3_state = POP3_STATE_QUIT; z_proxy_return(self, POP3_RSP_ACCEPT); }
/** * anypy_set_content_hint: * @self: AnyPyProxy instance * @args: Python args argument * * sets verdict for the parent proxy * args is (verdict,description) **/ static ZPolicyObj * anypy_set_content_hint(AnyPyProxy * self, ZPolicyObj *args) { gint64 length; z_proxy_enter(self); if (!z_policy_var_parse_tuple(args, "L", &length)) { z_policy_raise_exception_obj(z_policy_exc_value_error, "Invalid arguments."); z_proxy_leave(self); return NULL; } if (self->super.parent_proxy) { ZProxyStackIface *iface; iface = z_proxy_find_iface(self->super.parent_proxy, Z_CLASS(ZProxyStackIface)); if (iface) { z_proxy_stack_iface_set_content_hint(iface, length); z_object_unref(&iface->super); } } z_proxy_return(self, z_policy_none_ref()); }
/** * telnet_process_command: * @self: * @ep: * * * * Returns: * */ static guint telnet_process_command(TelnetProxy *self, guint ep) { ZPolicyObj *res = NULL; guint option_needed; gchar cmd_str[5]; guint ret_status; z_proxy_enter(self); /* * allow commands defined in RFC 854 * these are important, and must be implemented */ /* NOTE: this triggers a warning in gcc as the second part of the * condition is always TRUE as guchar is always less-or-equal than 255, * this is true, but I leave the condition intact as in the possible case * command is changed to int the condition might be perfectly valid */ if (self->command[ep] >= 240) z_proxy_return(self, TELNET_CHECK_OK); /* * allow negotiated commands * these were allowed during a negotiation */ g_snprintf(cmd_str, sizeof(cmd_str), "%hhu", self->command[ep]); z_policy_lock(self->super.thread); res = g_hash_table_lookup(self->negotiation, cmd_str); if (res != NULL) { if (!z_policy_var_parse(res, "i", &option_needed)) { z_proxy_log(self, TELNET_POLICY, 2, "Value in negotiation table bad; command='%d'", self->command[ep]); z_policy_unlock(self->super.thread); z_proxy_return(self, TELNET_CHECK_REJECT); } z_proxy_trace(self, "Changed needed negotiated option; command='%s', option='%d'", cmd_str, option_needed); } else { option_needed = self->command[ep]; } z_policy_unlock(self->super.thread); ret_status = TELNET_CHECK_REJECT; if (option_needed == 255) { ret_status = TELNET_CHECK_OK; } else if (option_needed > 255) { z_proxy_log(self, TELNET_POLICY, 2, "Value in negotation table out of range; command='%d', value='%d'", self->command[ep], option_needed); } else { z_proxy_trace(self, "Option state check; option='%d', state='%d:%d'", option_needed, self->options[option_needed][ep], self->options[option_needed][OTHER_EP(ep)]); if (self->options[option_needed][ep] & (SENT_WILL | GOT_DO)) ret_status = TELNET_CHECK_OK; } /* reject everything else */ z_proxy_return(self, ret_status); }
ZPolicyObj * smtp_policy_sanitize_address(SmtpProxy *self, ZPolicyObj *args) { gchar *address; gchar *final_end; GString *sanitized_address; ZPolicyObj *res = NULL; z_proxy_enter(self); if (!z_policy_var_parse_tuple(args, "s", &address)) { z_policy_raise_exception_obj(z_policy_exc_value_error, "Invalid arguments"); z_proxy_leave(self); return NULL; } sanitized_address = g_string_new(""); if (!smtp_sanitize_address(self, sanitized_address, address, TRUE, &final_end)) { z_policy_raise_exception_obj(z_policy_exc_value_error, "Invalid address"); goto exit; } res = z_policy_var_build("s", sanitized_address->str); exit: g_string_free(sanitized_address, TRUE); z_proxy_leave(self); return res; }
guint Pop3ParseAUTH(Pop3Proxy *self) { z_proxy_enter(self); self->pop3_state = POP3_STATE_AUTH_A; self->auth_lines = 0; z_proxy_return(self, POP3_RSP_ACCEPT); }
guint Pop3AnswerParseUSER(Pop3Proxy *self) { z_proxy_enter(self); if (strcmp(self->response->str, "+OK") == 0) self->pop3_state = POP3_STATE_AUTH_U; z_proxy_return(self, POP3_RSP_ACCEPT); }
guint Pop3ParseRETR(Pop3Proxy *self) { guint ret; z_proxy_enter(self); ret = Pop3ParseNum_One(self); z_proxy_return(self, ret); }
static GIOStatus ftp_transfer_src_read(ZTransfer2 *s, ZStream *stream, gchar *buf, gsize count, gsize *bytes_read, GError **err) { FtpProxy *owner = (FtpProxy *) s->owner; GIOStatus res; z_proxy_enter(owner); res = z_stream_read(stream, buf, count, bytes_read, err); z_proxy_return(owner, res); }
/** * anypy_config_set_defaults: * @self: AnyPyProxy instance * * This function initializes various attributes exported to the Python layer * for possible modification. **/ static void anypy_config_set_defaults(AnyPyProxy *self) { z_proxy_enter(self); self->max_line_length[EP_CLIENT] = 4096; self->max_line_length[EP_SERVER] = 4096; z_proxy_leave(self); }
void ftp_policy_feature_hash_handle_insert(struct _FtpProxy *self, GHashTable *features) { z_proxy_enter(self); z_policy_lock(self->super.thread); g_hash_table_foreach(self->policy_features, ftp_policy_feature_hash_foreach_cb, features); z_policy_unlock(self->super.thread); z_proxy_leave(self); }
static gboolean telnet_client_read(ZStream *stream, GIOCondition cond G_GNUC_UNUSED, gpointer user_data) { TelnetProxy *self = Z_CAST(user_data, TelnetProxy); gboolean res; z_proxy_enter(self); res = telnet_read(self, stream, EP_CLIENT); z_proxy_return(self, res); }
/** * 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); }
guint Pop3ParseNum_OneOptional(Pop3Proxy *self) { guint ret; z_proxy_enter(self); if (strlen(self->command_param->str) == 0) z_proxy_return(self, POP3_REQ_ACCEPT); self->response_multiline = FALSE; ret = Pop3ParseNum_One(self); z_proxy_return(self, ret); }
/** * 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_transfer2_timeout: * @user_data: ZTransfer2 instance passed as a generic pointer * * This function is a timeout-callback registered to terminate the * transfer loop when a specified time elapses. **/ static gboolean z_transfer2_timeout(gpointer user_data) { ZTransfer2 *self = Z_CAST(user_data, ZTransfer2); z_proxy_enter(self->owner); /*LOG This message indicates the data transfer timed out. */ z_proxy_log(self->owner, CORE_ERROR, 3, "Data transfer timed out; timeout='%ld'", self->timeout); z_transfer2_update_status(self, ZT2S_TIMEDOUT+ZT2S_FAILED+ZT2S_FINISHED, TRUE); z_proxy_leave(self->owner); return FALSE; }
guint Pop3ParseNoarg(Pop3Proxy *self) { z_proxy_enter(self); if (self->command_param->len > 0) /*LOG This message indicates that the request must not have any parameter and Zorp is going to drop the parameter. */ z_proxy_log(self, POP3_REQUEST, 4, "Dropping request parameter, no parameter allowed; req='%s', req_prm='%s'", self->command->str, self->command_param->str); g_string_assign(self->command_param, ""); z_proxy_return(self, POP3_REQ_ACCEPT); }
/** * finger_config_set_defaults: * @self: FingerProxy instance * * Fills in our state with default values. **/ static void finger_config_set_defaults(FingerProxy *self) { z_proxy_enter(self); self->max_line_length = 132; self->max_username_length = 8; self->max_hostname_length = 30; self->max_hop_count = 0; self->strict_username_check = TRUE; self->username = g_string_sized_new(32); self->hostnames = g_string_sized_new(0); self->response_header = g_string_sized_new(0); self->response_footer = g_string_sized_new(0); self->timeout = 30000; z_proxy_return(self); }
static gboolean z_proxy_stack_fds(ZProxy *self, gint client_fd, gint server_fd, gint control_fd, ZStackedProxy **stacked, guint32 flags) { ZStream *client_upstream, *server_upstream, *control_stream = NULL; z_proxy_enter(self); client_upstream = z_stream_fd_new(client_fd, ""); server_upstream = z_stream_fd_new(server_fd, ""); if (control_fd != -1) control_stream = z_stream_fd_new(control_fd, ""); *stacked = z_stacked_proxy_new(client_upstream, server_upstream, control_stream, self, NULL, flags); z_proxy_leave(self); return TRUE; }
static gboolean anypy_stream_init(AnyPyProxy *self) { z_proxy_enter(self); if (!self->super.endpoints[EP_CLIENT] || !self->super.endpoints[EP_SERVER]) { z_proxy_log(self, ANYPY_ERROR, 2, "Server side not yet connected, unable to init streams;"); z_proxy_leave(self); return FALSE; } self->super.endpoints[EP_CLIENT] = z_stream_push(self->super.endpoints[EP_CLIENT], z_stream_line_new(NULL, self->max_line_length[EP_CLIENT], ZRL_EOL_CRLF)); self->super.endpoints[EP_SERVER] = z_stream_push(self->super.endpoints[EP_SERVER], z_stream_line_new(NULL, self->max_line_length[EP_SERVER], ZRL_EOL_CRLF)); z_proxy_leave(self); return TRUE; }