Пример #1
0
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);
}
Пример #2
0
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));
}
Пример #3
0
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);
}
Пример #4
0
/**
 * 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);
}
Пример #5
0
/**
 * 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);
}
Пример #6
0
/**
 * 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);
}
Пример #7
0
/**
 * 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);
}
Пример #8
0
/**
 * 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;
}
Пример #9
0
/**
 * 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());
}
Пример #10
0
/**
 * 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;
}
Пример #11
0
/**
 * 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;
}
Пример #12
0
guint
Pop3AnswerParseQUIT(Pop3Proxy *self)
{
  z_proxy_enter(self);
  self->pop3_state = POP3_STATE_QUIT;
  z_proxy_return(self, POP3_RSP_ACCEPT);
}
Пример #13
0
/**
 * 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());
}
Пример #14
0
/**
 * 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);
} 
Пример #15
0
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;
}
Пример #16
0
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);
}
Пример #17
0
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);
}
Пример #18
0
guint
Pop3ParseRETR(Pop3Proxy *self)
{
  guint ret;

  z_proxy_enter(self);
  ret = Pop3ParseNum_One(self);
  z_proxy_return(self, ret);
}
Пример #19
0
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);
}
Пример #20
0
/**
 * 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);
}
Пример #21
0
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);
}
Пример #22
0
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);
}
Пример #23
0
/**
 * 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);
}
Пример #24
0
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);
}
Пример #25
0
/**
 * 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);
}
Пример #26
0
/**
 * 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;
}
Пример #27
0
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);
}
Пример #28
0
/**
 * 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);
}
Пример #29
0
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;
}
Пример #30
0
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;
}