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_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); }
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)); }
/** * 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); }
/** * 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); }
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); }
/** * 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()); }
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); }
guint Pop3AnswerParseQUIT(Pop3Proxy *self) { z_proxy_enter(self); self->pop3_state = POP3_STATE_QUIT; z_proxy_return(self, POP3_RSP_ACCEPT); }
/** * 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_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); }
/** * 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()); }
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); }
/** * 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); }
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 Pop3ParseAPOP(Pop3Proxy *self) { gchar username[self->max_username_length + 1]; guint i; gchar *buf = self->command_param->str; z_proxy_enter(self); for (i = 0; i < self->max_username_length && buf[i] != 0 && buf[i] != ' '; i++) username[i] = buf[i]; username[i] = 0; if (buf[i] != ' ') { /*LOG This message indicates that the username parameter is too long or the digest missing after the username and Zorp rejects the request. */ z_proxy_log(self, POP3_REQUEST, 3, "The username parameter is too long or the digest parameter is missing; req='APOP', req_prm='%s'", self->command_param->str); z_proxy_return(self, POP3_REQ_REJECT); } g_string_assign(self->username, username); while (buf[i] == 32) i++; buf = &buf[i]; for (i = 0; i < 32 && buf[i] != 0 && ((buf[i] >= '0' && buf[i] <= '9') || (buf[i] >= 'a' && buf[i] <= 'f') || (buf[i] >= 'A' && buf[i] <= 'F')); i++) ; if (i < 32) { /*LOG This message indicates that the MD5 digest parameter of the request is invalid and Zorp rejects the request. */ z_proxy_log(self, POP3_REQUEST, 3, "Error parsing the MD5 digest; req='APOP', req_prm='%s'", self->command_param->str); z_proxy_return(self, POP3_REQ_REJECT); } z_proxy_return(self, POP3_REQ_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); }
/** * 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 Pop3ParseUSER(Pop3Proxy *self) { gchar username[self->max_username_length + 1]; z_proxy_enter(self); if (self->command_param->len <= self->max_username_length) { g_strlcpy(username, self->command_param->str, self->max_username_length + 1); g_string_assign(self->username, username); z_proxy_return(self, POP3_REQ_ACCEPT); } /*LOG This message indicates that the username parameter of the request is too long and Zorp rejects the request. Check the 'max_username_length' attribute. */ z_proxy_log(self, POP3_POLICY, 2, "Username is too long; max_username_length='%d', username_length='%" G_GSIZE_FORMAT "', username='******'", self->max_username_length, self->command_param->len, self->command_param->str); z_proxy_return(self, POP3_REQ_REJECT); }
guint Pop3ParsePASS(Pop3Proxy *self) { gchar password[self->max_password_length + 1]; z_proxy_enter(self); if (self->command_param->len <= self->max_password_length) { g_strlcpy(password, self->command_param->str, self->max_password_length + 1); g_string_assign(self->password, password); z_proxy_return(self, POP3_REQ_ACCEPT); } /*LOG This message indicates that the password parameter of the request is too long and Zorp rejects the request. Check the 'max_password_length' attribute. */ z_proxy_log(self, POP3_POLICY, 2, "Password is too long; max_password_length='%d', password_length='%d'", self->max_password_length, (gint) self->command_param->len); z_proxy_return(self, POP3_REQ_REJECT); }
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); }
/** * This function sends a packet to one of the endpoints. * * @param[in] self Telnet proxy instance * @param[in] ep Endpoint index * @param[in] pkt Packet to send (consumed) * * The function consumes the packet, so the caller must not unref it itself! * * @returns GIOStatus instance **/ GIOStatus telnet_write_packet(TelnetProxy *self, ZEndpoint ep, ZPktBuf *pkt) { GIOStatus res = G_IO_STATUS_ERROR; z_proxy_enter(self); if (self->super.ssl_opts.handshake_pending[ep]) /* do not send any data while SSL handshake is in progress. */ { z_proxy_return(self, G_IO_STATUS_NORMAL); } /* need to keep pkt around to be able to write the audit record */ z_pktbuf_ref(pkt); res = z_stream_write_packet(self->super.endpoints[ep], pkt, NULL); z_pktbuf_unref(pkt); z_proxy_return(self, res); }
guint ftp_policy_feature_hash_search(struct _FtpProxy *self, const gchar *feature) { ZPolicyObj *res; guint verdict; gboolean valid; z_proxy_enter(self); res = g_hash_table_lookup(self->policy_features, feature); if (!res) res = g_hash_table_lookup(self->policy_features, "*"); if (!res) { /*LOG This message indicates that the policy does not contain any setting for the given feature and Zorp drops the feature. Check the 'features' attribute. */ z_proxy_log(self, FTP_POLICY, 5, "Policy does not contain this feature, dropping; feature='%s'", feature); z_proxy_return(self, FTP_FEATURE_DROP); } z_policy_lock(self->super.thread); valid = ftp_hash_get_type(res, &verdict); z_policy_unlock(self->super.thread); if (!valid) { /*LOG This message indicates that the policy type is invalid for the given feature and thus Zorp drops the feature. */ z_proxy_log(self, FTP_POLICY, 1, "Policy value invalid; feature='%s'", feature); z_proxy_return(self, FTP_FEATURE_DROP); } z_proxy_return(self, verdict); }
/** * telnet_check_suboption: * @self: * @ep: * * * * Returns: * */ static guint telnet_check_suboption(TelnetProxy *self, guint ep) { guint res; TelnetOptionFunction check_func; ZIOBuffer *sbuf = &self->suboptions[ep]; gchar buf[TELNET_BUFFER_SIZE + 1]; guint i, j; z_proxy_enter(self); /* check if allowed in this session */ if (!(self->options[self->opneg_option[ep]][OTHER_EP(ep)] & (SENT_WILL | GOT_DO)) && !(self->options[self->opneg_option[ep]][ep] & (SENT_WILL | GOT_DO))) { z_proxy_log(self, TELNET_VIOLATION, 3, "Option not allowed in the session; option='%d'", self->opneg_option[ep]); z_proxy_return(self, TELNET_CHECK_ABORT); } /* check if valid */ if ((check_func = self->telnet_options[self->opneg_option[ep]]) == NULL) { /* option has no suboption check function */ /* copy suboption negotiation buffer into policy_value */ for (j = 0, i = sbuf->ofs; i < sbuf->end; j++, i++) buf[j] = sbuf->buf[i]; g_string_assign(self->policy_name, ""); g_string_assign(self->policy_value, buf); /* call policy check */ res = telnet_policy_suboption(self, (guchar) buf[0], "", buf); } else { /* call check function, and check function calls policy */ res = check_func(self, ep); } z_proxy_return(self, res); }
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); }
/** * telnet_set_defaults: * @self: * * */ static void telnet_set_defaults(TelnetProxy *self) { int i; z_proxy_enter(self); self->telnet_policy = z_dim_hash_table_new(1, 2, DIMHASH_WILDCARD, DIMHASH_WILDCARD); for (i = 0; i < 256; i++) self->telnet_options[i] = NULL; self->policy_name = g_string_new(""); self->policy_value = g_string_new(""); self->timeout = 600000; self->negotiation = g_hash_table_new(g_str_hash, g_str_equal); z_proxy_return(self); }
void plug_register_vars(PlugProxy *self) { z_proxy_enter(self); z_proxy_var_new(&self->super, "timeout", Z_VAR_GET | Z_VAR_SET_CONFIG | Z_VAR_TYPE_INT, &self->session_data.timeout); z_proxy_var_new(&self->super, "copy_to_client", Z_VAR_GET | Z_VAR_SET_CONFIG | Z_VAR_TYPE_INT, &self->session_data.copy_to_client); z_proxy_var_new(&self->super, "copy_to_server", Z_VAR_GET | Z_VAR_SET_CONFIG | Z_VAR_TYPE_INT, &self->session_data.copy_to_server); z_proxy_var_new(&self->super, "shutdown_soft", Z_VAR_GET | Z_VAR_SET_CONFIG | Z_VAR_TYPE_INT, &self->session_data.shutdown_soft); z_proxy_var_new(&self->super, "packet_stats_interval_packet", Z_VAR_GET | Z_VAR_SET_CONFIG | Z_VAR_TYPE_INT, &self->session_data.packet_stats_interval_packet); z_proxy_var_new(&self->super, "packet_stats_interval_time", Z_VAR_GET | Z_VAR_SET_CONFIG | Z_VAR_TYPE_INT, &self->session_data.packet_stats_interval_time); z_proxy_var_new(&self->super, "buffer_size", Z_VAR_GET | Z_VAR_SET_CONFIG | Z_VAR_TYPE_INT, &self->session_data.buffer_size); /* Zorp 1.4 compatibility */ z_proxy_var_new(&self->super, "packet_stats_interval", Z_VAR_TYPE_ALIAS | Z_VAR_GET | Z_VAR_SET | Z_VAR_GET_CONFIG | Z_VAR_SET_CONFIG, "packet_stats_interval_packet"); z_proxy_return(self); }