Esempio n. 1
0
/*
 * mo_connect - CONNECT command handler
 *
 * Added by Jto 11 Feb 1989
 *
 * m_connect
 *      parv[1] = servername
 *      parv[2] = port number
 *      parv[3] = remote server
 */
static int
mo_connect(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	int port;
	int tmpport;
	struct server_conf *server_p;
	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, "remote");
		return 0;
	}

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

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

	/*
	 * try to find the name, then host, if both fail notify ops and bail
	 */
	if((server_p = find_server_conf(parv[1])) == NULL)
	{
		sendto_one_notice(source_p, ":Connect: Host %s not listed in ircd.conf", parv[1]);
		return 0;
	}

	if(ServerConfSSL(server_p) && (!ssl_ok || !get_ssld_count()))
	{
		sendto_one_notice(source_p,
				  ":Connect: Server %s is set to use SSL/TLS but SSL/TLS is not configured.",
				  parv[1]);
		return 0;
	}

	/*
	 * 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 = 0;
	if(parc > 2 && !EmptyString(parv[2]))
		port = atoi(parv[2]);
	if(port == 0 && server_p->port)
		port = server_p->port;
	else if(port <= 0)
	{
		sendto_one_notice(source_p, ":Connect: illegal port number");
		return 0;
	}
	
	/*
	 * Notify all operators about remote connect requests
	 */

	ilog(L_SERVER, "CONNECT From %s : %s %s", source_p->name, parv[1], parc > 2 ? parv[2] : "");

	server_p->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(server_p, source_p))
	{
			sendto_one_notice(source_p, ":*** Connecting to %s.%d",
				server_p->name, server_p->port);
	}
	else
	{
		sendto_one_notice(source_p, ":*** Couldn't connect to %s.%d",
			server_p->name, server_p->port);
	}

	/*
	 * client is either connecting with all the data it needs or has been
	 * destroyed
	 */
	server_p->port = tmpport;
	return 0;
}
Esempio n. 2
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;
}
Esempio n. 3
0
/*
 * m_squit - SQUIT message handler
 *      parv[0] = sender prefix
 *      parv[1] = server name
 *      parv[2] = comment
 */
int m_squit(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct ConfItem* aconf;
  char*            server;
  struct Client*   acptr;
  char  *comment = (parc > 2 && parv[2]) ? parv[2] : cptr->name;

  if (!IsPrivileged(sptr))
    {
      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
      return 0;
    }

  if (parc > 1)
    {
      server = parv[1];
      /*
      ** To accomodate host masking, a squit for a masked server
      ** name is expanded if the incoming mask is the same as
      ** the server name for that link to the name of link.
      */
      while ((*server == '*') && IsServer(cptr))
        {
          aconf = cptr->serv->nline;
          if (!aconf)
            break;
          if (!irccmp(server, my_name_for_link(me.name, aconf)))
            server = cptr->name;
          break; /* WARNING is normal here */
          /* NOTREACHED */
        }
      /*
      ** The following allows wild cards in SQUIT. Only useful
      ** when the command is issued by an oper.
      */
      for (acptr = GlobalClientList; (acptr = next_client(acptr, server));
           acptr = acptr->next)
        if (IsServer(acptr) || IsMe(acptr))
          break;
      if (acptr && IsMe(acptr))
        {
          acptr = cptr;
          server = cptr->name;
        }
    }
  else
    {
      /*
      ** This is actually protocol error. But, well, closing
      ** the link is very proper answer to that...
      **
      ** Closing the client's connection probably wouldn't do much
      ** good.. any oper out there should know that the proper way
      ** to disconnect is /QUIT :)
      **
      ** its still valid if its not a local client, its then
      ** a protocol error for sure -Dianora
      */
      if(MyClient(sptr))
        {
          sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
               me.name, parv[0], "SQUIT");
          return 0;
        }
      else
        {
          server = cptr->host;
          acptr = cptr;
        }
    }

  /*
  ** SQUIT semantics is tricky, be careful...
  **
  ** The old (irc2.2PL1 and earlier) code just cleans away the
  ** server client from the links (because it is never true
  ** "cptr == acptr".
  **
  ** This logic here works the same way until "SQUIT host" hits
  ** the server having the target "host" as local link. Then it
  ** will do a real cleanup spewing SQUIT's and QUIT's to all
  ** directions, also to the link from which the orinal SQUIT
  ** came, generating one unnecessary "SQUIT host" back to that
  ** link.
  **
  ** One may think that this could be implemented like
  ** "hunt_server" (e.g. just pass on "SQUIT" without doing
  ** nothing until the server having the link as local is
  ** reached). Unfortunately this wouldn't work in the real life,
  ** because either target may be unreachable or may not comply
  ** with the request. In either case it would leave target in
  ** links--no command to clear it away. So, it's better just
  ** clean out while going forward, just to be sure.
  **
  ** ...of course, even better cleanout would be to QUIT/SQUIT
  ** dependant users/servers already on the way out, but
  ** currently there is not enough information about remote
  ** clients to do this...   --msa
  */
  if (!acptr)
    {
      sendto_one(sptr, form_str(ERR_NOSUCHSERVER),
                 me.name, parv[0], server);
      return 0;
    }
  if (IsLocOp(sptr) && !MyConnect(acptr))
    {
      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
      return 0;
    }

  if (MyClient(sptr) && !IsOperRemote(sptr) && !MyConnect(acptr))
    {
      sendto_one(sptr,":%s NOTICE %s :You have no R flag",me.name,parv[0]);
      return 0;
    }

  /*
  **  Notify all opers, if my local link is remotely squitted
  */
  if (MyConnect(acptr) && !IsAnOper(cptr))
    {
      sendto_ops_butone(NULL, &me,
                        ":%s WALLOPS :Received SQUIT %s from %s (%s)",
                        me.name, server, get_client_name(sptr,FALSE), comment);
      log(L_TRACE, "SQUIT From %s : %s (%s)", parv[0], server, comment);
    }
  else if (MyConnect(acptr))
    sendto_ops("Received SQUIT %s from %s (%s)",
               acptr->name, get_client_name(sptr,FALSE), comment);
  
  return exit_client(cptr, acptr, sptr, comment);
}
Esempio n. 4
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 *aconf;
	struct Client *target_p;

	/* always privileged with handlers */

	if(MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3)
	{
		sendto_one(source_p, ":%s NOTICE %s :You need remote = yes;", me.name, parv[0]);
		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, parv[0], "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, parv[0], parv[1], target_p->from->name);
		return;
	}

	/*
	 * try to find the name, then host, if both fail notify ops and bail
	 */
	if(!(aconf = find_conf_by_name(parv[1], CONF_SERVER)))
	{
		if(!(aconf = find_conf_by_host(parv[1], CONF_SERVER)))
		{
			sendto_one(source_p,
				   "NOTICE %s :Connect: Host %s not listed in ircd.conf",
				   parv[0], parv[1]);
			return;
		}
	}
	s_assert(0 != aconf);
	/*
	 * 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, "NOTICE %s :Connect: Illegal port number", parv[0]);
			return;
		}
	}
	else if(port <= 0 && (port = PORTNUM) <= 0)
	{
		sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number",
			   me.name, parv[0]);
		return;
	}
	/*
	 * Notify all operators about remote connect requests
	 */

	ilog(L_TRACE, "CONNECT From %s : %s %s", parv[0], 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))
	{
#ifndef HIDE_SERVERS_IPS
		if(IsOperAdmin(source_p))
			sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
				   me.name, parv[0], aconf->host, aconf->name, aconf->port);
		else
#endif
			sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
				   me.name, parv[0], aconf->name, aconf->port);

	}
	else
	{
		sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
			   me.name, parv[0], aconf->name, aconf->port);

	}
	/*
	 * client is either connecting with all the data it needs or has been
	 * destroyed
	 */
	aconf->port = tmpport;
}
Esempio n. 5
0
/*
 * m_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
 */
int m_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  int              port;
  int              tmpport;
  struct ConfItem* aconf;
  struct Client*   acptr;

  if (!IsPrivileged(sptr))
    {
      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
      return -1;
    }

  if (IsLocOp(sptr) && parc > 3) {
    /* 
     * Only allow LocOps to make local CONNECTS --SRB
     */
    return 0;
  }

  if (MyConnect(sptr) && !IsOperRemote(sptr) && parc > 3)
    {
      sendto_one(sptr,":%s NOTICE %s :You have no R flag", me.name, parv[0]);
      return 0;
    }

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

  if (parc < 2 || *parv[1] == '\0')
    {
      sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
                 me.name, parv[0], "CONNECT");
      return -1;
    }

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

  /*
   * try to find the name, then host, if both fail notify ops and bail
   */
  if (!(aconf = find_conf_by_name(parv[1], CONF_CONNECT_SERVER))) {
#ifndef HIDE_SERVERS_IPS
    if (!(aconf = find_conf_by_host(parv[1], CONF_CONNECT_SERVER))) {
#endif
      sendto_one(sptr,
                 "NOTICE %s :Connect: Host %s not listed in ircd.conf",
                 parv[0], parv[1]);
      return 0;
#ifndef HIDE_SERVERS_IPS
    }
#endif
  }
  assert(0 != aconf);
  /*
   * 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]))
    {
#ifdef NEG_PORT
      if ((port = atoi(parv[2])) < 0)
#else    
      if ((port = atoi(parv[2])) <= 0)
#endif      
        {
          sendto_one(sptr, "NOTICE %s :Connect: Illegal port number",
                     parv[0]);
          return 0;
        }
    }
#ifdef NEG_PORT
  else if (port < 0 && (port = PORTNUM) <= 0)
#else    
  else if (port <= 0 && (port = PORTNUM) <= 0)
#endif  
    {
      sendto_one(sptr, ":%s NOTICE %s :Connect: missing port number",
                 me.name, parv[0]);
      return 0;
    }
#ifdef NEG_PORT
  if (port == 0)
    port = tmpport; /* From conf */
  if (port == 0)
    port = PORTNUM; /* Default if there wasn't one set in conf */
#endif
    
  /*
   * Notify all operators about remote connect requests
   */
  if (!IsAnOper(cptr))
    {
      sendto_ops_butone(NULL, &me,
                        ":%s WALLOPS :Remote CONNECT %s %s from %s",
                        me.name, parv[1], parv[2] ? parv[2] : "",
                        get_client_name(sptr, FALSE));

      irclog(L_TRACE, "CONNECT From %s : %s %s", 
          parv[0], 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 (connect_server(aconf, sptr, 0))
#if (defined SERVERHIDE) || (defined HIDE_SERVERS_IPS)
    sendto_one(sptr, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
               me.name, parv[0], "255.255.255.255", aconf->name, aconf->port);
  else
    sendto_one(sptr, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
               me.name, parv[0], "255.255.255.255",aconf->port);
#else
    sendto_one(sptr, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
               me.name, parv[0], aconf->host, aconf->name, aconf->port);
  else