Exemple #1
0
/*! \brief CONNECT command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = target server
 *      - parv[2] = port number
 *      - parv[3] = nickname/servername
 */
static int
mo_connect(struct Client *source_p, int parc, char *parv[])
{
  int port = 0, tmpport = 0;
  struct MaskItem *conf = NULL;
  const struct Client *target_p = NULL;

  if (EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "CONNECT");
    return 0;
  }

  if (parc > 3)
  {
    if (!HasOFlag(source_p, OPER_FLAG_CONNECT_REMOTE))
    {
      sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "connect:remote");
      return 0;
    }

    if (hunt_server(source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
      return 0;
  }
  else if (!HasOFlag(source_p, OPER_FLAG_CONNECT))
  {
    sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "connect");
    return 0;
  }

  /*
   * Try to find the name, then host, if both fail notify ops and bail
   */
  if (!(conf = find_matching_name_conf(CONF_SERVER, parv[1], NULL, NULL, 0)) &&
      !(conf = find_matching_name_conf(CONF_SERVER, NULL, NULL, parv[1], 0)))
  {
    sendto_one_notice(source_p, &me, ":Connect: Host %s not listed in configuration file", parv[1]);
    return 0;
  }

  if ((target_p = hash_find_server(conf->name)))
  {
    sendto_one_notice(source_p, &me, ":Connect: Server %s already exists from %s.",
                      target_p->name, target_p->from->name);
    return 0;
  }

  /*
   * Get port number from user, if given. If not specified,
   * use the default from configuration structure. If missing
   * from there, then use the precompiled default.
   */
  tmpport = port = conf->port;

  if (parc > 2 && !EmptyString(parv[2]))
  {
    if ((port = atoi(parv[2])) <= 0)
    {
      sendto_one_notice(source_p, &me, ":Connect: Illegal port number");
      return 0;
    }
  }
  else if (port <= 0 && (port = PORTNUM) <= 0)
  {
    sendto_one_notice(source_p, &me, ":Connect: missing port number");
    return 0;
  }

  if (find_servconn_in_progress(conf->name))
  {
    sendto_one_notice(source_p, &me, ":Connect: a connection to %s "
                      "is already in progress.", conf->name);
    return 0;
  }

  /*
   * Notify all operators about remote connect requests
   */
  ilog(LOG_TYPE_IRCD, "CONNECT From %s : %s %s",
       source_p->name, parv[1], parv[2] ? parv[2] : "");

  conf->port = port;

  /*
   * At this point we should be calling connect_server with a valid
   * connect{} block and a valid port in the connect{} block
   */
  if (serv_connect(conf, source_p))
  {
    if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN))
      sendto_one_notice(source_p, &me, ":*** Connecting to %s[%s].%d",
                        conf->host, conf->name, conf->port);
    else
      sendto_one_notice(source_p, &me, ":*** Connecting to %s.%d",
                        conf->name, conf->port);
  }
  else
    sendto_one_notice(source_p, &me, ":*** Couldn't connect to %s.%d",
                      conf->name, conf->port);

  /*
   * Client is either connecting with all the data it needs or has been
   * destroyed
   */
  conf->port = tmpport;
  return 0;
}
/*
 * mo_connect - CONNECT command handler
 * 
 * Added by Jto 11 Feb 1989
 *
 * m_connect
 *      parv[0] = sender prefix
 *      parv[1] = servername
 *      parv[2] = port number
 *      parv[3] = remote server
 */
static void
mo_connect(struct Client* client_p, struct Client* source_p,
           int parc, char* parv[])
{
  int port;
  int tmpport;
  struct ConfItem *conf = NULL;
  struct AccessItem *aconf = NULL;
  struct Client *target_p;

  /* always privileged with handlers */
  if (MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3)
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "connect");
    return;
  }

  if (hunt_server(client_p, source_p,
                  ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
    return;

  if (*parv[1] == '\0')
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "CONNECT");
    return;
  }

  if ((target_p = find_server(parv[1])))
  {
    sendto_one(source_p,
	       ":%s NOTICE %s :Connect: Server %s already exists from %s.",
               me.name, source_p->name, parv[1], target_p->from->name);
    return;
  }

  /*
   * try to find the name, then host, if both fail notify ops and bail
   */
  if ((conf = find_matching_name_conf(SERVER_TYPE,
				      parv[1], NULL, NULL, 0)) != NULL)
    aconf = (struct AccessItem *)map_to_conf(conf);
  else if ((conf = find_matching_name_conf(SERVER_TYPE,
					   NULL, NULL, parv[1], 0)) != NULL)
    aconf = (struct AccessItem *)map_to_conf(conf);
  
  if (conf == NULL)
  {
    sendto_one(source_p,
	       ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
	       me.name, source_p->name, parv[1]);
    return;
  }
    
  /* Get port number from user, if given. If not specified,
   * use the default form configuration structure. If missing
   * from there, then use the precompiled default.
   */
  tmpport = port = aconf->port;

  if (parc > 2 && !EmptyString(parv[2]))
  {
    if ((port = atoi(parv[2])) <= 0)
    {
      sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal port number",
                 me.name, source_p->name);
      return;
    }
  }
  else if (port <= 0 && (port = PORTNUM) <= 0)
  {
    sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number",
               me.name, source_p->name);
    return;
  }

  if (find_servconn_in_progress(conf->name))
  {
    sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
               "is already in progress.", me.name, source_p->name, conf->name);
    return;
  }

  /*
   * Notify all operators about remote connect requests
   */
  ilog(L_TRACE, "CONNECT From %s : %s %s", 
       source_p->name, parv[1], parv[2] ? parv[2] : "");

  aconf->port = port;

  /* at this point we should be calling connect_server with a valid
   * C:line and a valid port in the C:line
   */
  if (serv_connect(aconf, source_p))
  {
    if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
      sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
                 me.name, source_p->name, aconf->host,
                 conf->name, aconf->port);
    else
      sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
                 me.name, source_p->name, conf->name, aconf->port);
  }
  else
  {
    sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
               me.name, source_p->name, conf->name, aconf->port);
  }

  /* client is either connecting with all the data it needs or has been
   * destroyed
   */
  aconf->port = tmpport;
}
Exemple #3
0
/*! \brief CONNECT command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = target server
 *      - parv[2] = port number
 *      - parv[3] = nickname/servername
 */
static int
ms_connect(struct Client *source_p, int parc, char *parv[])
{
  int port = 0, tmpport = 0;
  struct MaskItem *conf = NULL;
  const struct Client *target_p = NULL;

  if (parc < 4 || EmptyString(parv[3]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "CONNECT");
    return 0;
  }

  if (hunt_server(source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
    return 0;

  /*
   * Try to find the name, then host, if both fail notify ops and bail
   */
  if (!(conf = find_matching_name_conf(CONF_SERVER, parv[1], NULL, NULL, 0)) &&
      !(conf = find_matching_name_conf(CONF_SERVER, NULL, NULL, parv[1], 0)))
  {
    sendto_one_notice(source_p, &me, ":Connect: Host %s not listed in configuration file", parv[1]);
    return 0;
  }

  if ((target_p = hash_find_server(conf->name)))
  {
    sendto_one_notice(source_p, &me, ":Connect: Server %s already exists from %s.",
                      target_p->name, target_p->from->name);
    return 0;
  }

  /*
   * Get port number from user, if given. If not specified,
   * use the default from configuration structure. If missing
   * from there, then use the precompiled default.
   */
  tmpport = port = conf->port;

  if (parc > 2 && !EmptyString(parv[2]))
  {
    port = atoi(parv[2]);

    /*
     * If someone sends port 0, and we have a config port.. use it
     */
    if (port == 0 && conf->port)
      port = conf->port;
    else if (port <= 0)
    {
      sendto_one_notice(source_p, &me, ":Connect: Illegal port number");
      return 0;
    }
  }
  else if (port <= 0 && (port = PORTNUM) <= 0)
  {
    sendto_one_notice(source_p, &me, ":Connect: missing port number");
    return 0;
  }

  if (find_servconn_in_progress(conf->name))
  {
    sendto_one_notice(source_p, &me, ":Connect: a connection to %s "
                      "is already in progress.", conf->name);
    return 0;
  }

  /*
   * Notify all operators about remote connect requests
   */
  sendto_realops_flags(UMODE_ALL, L_ALL, SEND_GLOBAL, "from %s: Remote CONNECT %s %d from %s",
                       me.name, parv[1], port, source_p->name);
  sendto_server(NULL, 0, 0,
                ":%s GLOBOPS :Remote CONNECT %s %d from %s",
                me.id, parv[1], port, source_p->name);

  ilog(LOG_TYPE_IRCD, "CONNECT From %s : %s %d",
       source_p->name, parv[1], port);

  conf->port = port;

  /*
   * At this point we should be calling connect_server with a valid
   * connect{} block and a valid port in the connect{} block
   */
  if (serv_connect(conf, source_p))
    sendto_one_notice(source_p, &me, ":*** Connecting to %s.%d",
                      conf->name, conf->port);
  else
    sendto_one_notice(source_p, &me, ":*** Couldn't connect to %s.%d",
                      conf->name, conf->port);
  /*
   * Client is either connecting with all the data it needs or has been
   * destroyed
   */
  conf->port = tmpport;
  return 0;
}
/*
 * ms_connect - CONNECT command handler
 * 
 * Added by Jto 11 Feb 1989
 *
 * m_connect
 *      parv[0] = sender prefix
 *      parv[1] = servername
 *      parv[2] = port number
 *      parv[3] = remote server
 */
static void
ms_connect(struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
  int port;
  int tmpport;
  struct ConfItem *conf = NULL;
  struct AccessItem *aconf = NULL;
  struct Client *target_p;

  if (hunt_server(client_p, source_p,
                  ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
    return;

  if (*parv[1] == '\0')
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "CONNECT");
    return;
  }

  if ((target_p = find_server(parv[1])))
  {
    sendto_one(source_p,
	       ":%s NOTICE %s :Connect: Server %s already exists from %s.",
               me.name, source_p->name, parv[1], target_p->from->name);
    return;
  }

  /*
   * try to find the name, then host, if both fail notify ops and bail
   */
  if ((conf = find_matching_name_conf(SERVER_TYPE,
				      parv[1], NULL, NULL, 0)) != NULL)
    aconf = (struct AccessItem *)map_to_conf(conf);
  else if ((conf = find_matching_name_conf(SERVER_TYPE,
					   NULL, NULL, parv[1], 0)) != NULL)
    aconf = (struct AccessItem *)map_to_conf(conf);

  if (aconf == NULL)
  {
    sendto_one(source_p,
	       ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
	       me.name, source_p->name, parv[1]);
    return;
  }

  assert(aconf != NULL);

  /* Get port number from user, if given. If not specified,
   * use the default form configuration structure. If missing
   * from there, then use the precompiled default.
   */
  tmpport = port = aconf->port;

  if (parc > 2 && !EmptyString(parv[2]))
  {
    port = atoi(parv[2]);

    /* if someone sends port 0, and we have a config port.. use it */
    if (port == 0 && aconf->port)
      port = aconf->port;
    else if (port <= 0)
    {
      sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal port number",
                 me.name, source_p->name);
      return;
    }
  }
  else if (port <= 0 && (port = PORTNUM) <= 0)
  {
    sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number",
               me.name, source_p->name);
    return;
  }

  if (find_servconn_in_progress(conf->name))
  {
    sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
               "is already in progress.", me.name, source_p->name, conf->name);
    return;
  }

  /*
   * Notify all operators about remote connect requests
   */
  sendto_wallops_flags(UMODE_WALLOP, &me, "Remote CONNECT %s %d from %s",
                       parv[1], port, source_p->name);
  sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS,
                ":%s WALLOPS :Remote CONNECT %s %d from %s",
                me.name, parv[1], port, source_p->name);

  ilog(L_TRACE, "CONNECT From %s : %s %d", 
       source_p->name, parv[1], port);

  aconf->port = port;

  /* at this point we should be calling connect_server with a valid
   * C:line and a valid port in the C:line
   */
  if (serv_connect(aconf, source_p))
    sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
               me.name, source_p->name, conf->name, aconf->port);
  else
    sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
               me.name, source_p->name, conf->name, aconf->port);
  /* client is either connecting with all the data it needs or has been
   * destroyed
   */
  aconf->port = tmpport;
}