Exemplo n.º 1
0
/**
 * Handle NOTICE commands
 *
 * @param source is the nick of the person whom sent the notice
 * @param receiver is the nick whom it was sent to
 * @param msg is the message that was sent
 *
 * @return always returns MOD_CONT
 */
int m_notice(char *source, char *receiver, char *msg)
{
    char *temp = NULL;
    char *version;
    char *clean;

    if (BadPtr(source) || BadPtr(receiver) || BadPtr(msg)) {
        return MOD_CONT;
    }

    if (!stricmp(receiver, s_StatServ)
        || (s_StatServ_alias && !stricmp(receiver, s_StatServ_alias))) {
        clean = normalizeBuffer(msg);
        doCleanBuffer((char *) clean);
        temp = myStrGetToken(clean, ' ', 0);
        if (!temp) {
            free(clean);
            return MOD_CONT;
        }
        if (!stricmp(temp, "VERSION")) {
            version = myStrGetTokenRemainder(clean, ' ', 1);
            handle_ctcp_version(source, version);
            free(version);
        }
        free(clean);
        free(temp);
    }

    return MOD_CONT;
}
Exemplo n.º 2
0
void event_message_process(char *eventbuf)
{
    int retVal = 0;
    EvtMessage *current = NULL;
    char source[64];
    char cmd[64];
    char buf[512];              /* Longest legal IRC command line */
    char *s;
    int ac;                     /* Parameters for the command */
    char **av;
    EvtMessage *evm;

    /* zero out the buffers before we do much else */
    *buf = '\0';
    *source = '\0';
    *cmd = '\0';

    strscpy(buf, eventbuf, sizeof(buf));

    doCleanBuffer((char *) buf);

    /* Split the buffer into pieces. */
    if (*buf == ':') {
        s = strpbrk(buf, " ");
        if (!s)
            return;
        *s = 0;
        while (isspace(*++s));
        strscpy(source, buf + 1, sizeof(source));
        memmove(buf, s, strlen(s) + 1);
    } else {
        *source = 0;
    }
    if (!*buf)
        return;
    s = strpbrk(buf, " ");
    if (s) {
        *s = 0;
        while (isspace(*++s));
    } else
        s = buf + strlen(buf);
    strscpy(cmd, buf, sizeof(cmd));
    ac = split_buf(s, &av, 1);

    /* Do something with the message. */
    evm = find_event(cmd);
    if (evm) {
        char *mod_current_module_name_save = mod_current_module_name;
        Module *mod_current_module_save = mod_current_module;
        if (evm->func) {
            mod_current_module_name = evm->mod_name;
            mod_current_module = findModule(evm->mod_name);
            retVal = evm->func(source, ac, av);
            if (retVal == MOD_CONT) {
                current = evm->next;
                while (current && current->func && retVal == MOD_CONT) {
                    mod_current_module_name = current->mod_name;
                    mod_current_module = findModule(current->mod_name);
                    retVal = current->func(source, ac, av);
                    current = current->next;
                }
            }
            mod_current_module_name = mod_current_module_name_save;
            mod_current_module = mod_current_module_save;
        }
    }
    /* Free argument list we created */
    free(av);
}
Exemplo n.º 3
0
/*
 * m_notice - generic message handler
 */
int m_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char*           name;
  char*           server;
  int             ret = 0;
  int             i;
  int             j;
  int             fd = 0;
  int             count;
  char            *clean;
  char*           vector[MAXTARGETS];
  char*           temp; /* added by Vadtec 02/25/2008 */
  char*           parv_temp; /* added by Vadtec 02/26/2008 */
  int             found_g = 0; /* added by Vadtec 02/26/2008 */
  int             sent = 0; /* added by Vadtec 03/13/2008 */
  struct Client*  acptr; /* added by Vadtec 02/26/2008 */
  struct Channel* chptr; /* added by Vadtec 02/27/2008 */
  int             isdcc = 0;

  assert(0 != cptr);
  assert(cptr == sptr);

  ClrFlag(sptr, FLAG_TS8);

  if (parc < 2 || EmptyString(parv[1]))
    return send_reply(sptr, ERR_NORECIPIENT, MSG_NOTICE);

  if (parc < 3 || EmptyString(parv[parc - 1]))
    return send_reply(sptr, ERR_NOTEXTTOSEND);

  if (parv[1][0] == '@' && IsChannelPrefix(parv[1][1])) {
    parv[1]++;                        /* Get rid of '@' */
    return m_wallchops(cptr, sptr, parc, parv);
  }

  count = unique_name_vector(parv[1], ',', vector, MAXTARGETS);

  /* Check here to make sure that the client is ours so we dont respond to NOTICES from other server's users. - Vadtec 02/25/2008 */
  /* Also, check to make sure that the notice is actually destined for the *server* and not another user. That way we don't process
     some user saying "what version do you use" to another user via notice. - Vadtec 03/13/2008 */
  if (feature_bool(FEAT_CTCP_VERSIONING) && MyConnect(sptr) && !strcmp(parv[1], cli_name(&me))) {
    /*
     Added by Vadtec 02/25/2008.
     This is so that we can do version checking (and banning) of connecting clients.
     Rules: Only one really. CTCP VERSION is not part of the RFC and therefore clients are not required to respond to
     a request for their version.
     NOTE: If we are lucky enough to have _GNU_SOURCE, we will use it over the standard strstr because its case insensetive.
           This should help against clients that like to send lower case CTCPs from slipping through as easily with only one
           function call.
    */
    for (fd = HighestFd; fd >= 0 && !sent; --fd) { /* Added the "sent" check here so that if we have already sent the notice
                                                      we don't needlessly loop through *all* the users - Vadtec 03/13/2008 */
      if ((acptr = LocalClientArray[fd])) {
        if (!cli_user(acptr))
          continue;

        #ifdef _GNU_SOURCE
        if ((temp = strcasestr(parv[2], "\x01VERSION"))) { /* added \x01 to the string so that it will *only* respond to CTCP version
                                                              replies. Seems redundant, but we dont want the users doing
                                                              /notice <server> version (and getting away with it) - Vadtec 03/13/2008 */
          temp = strchrnul(parv[2], ' '); /* Moved this here to take advantage of strchrnul - added by Vadtec 03/13/2008 */
        #else
        if ((temp = strstr(parv[2], "\x01VERSION")) || (temp = strstr(parv[2], "\x01version"))) { /* See above comment about \x01 - Vadtec */
          temp = strchr(parv[2], ' '); /* Moved this here to take advantage of strchrnul - added by Vadtec 03/13/2008 */
          if (temp == 0)
            temp = parv[2] + strlen(parv[2]); /* This does the same thing as strchrnul - Vadtec */
        #endif
          parv_temp = parv[2];
          j = 0;
          while (j <= (temp - parv[2])) { parv_temp++; j++; }

          clean = normalizeBuffer(parv_temp);
          doCleanBuffer((char *) clean);

          ircd_strncpy(cli_version(sptr), normalizeBuffer(clean), VERSIONLEN);
          sendcmdto_serv_butone(&me, CMD_MARK, cptr, "%s %s :%s", cli_name(sptr), MARK_CVERSION, cli_version(sptr));

          /* Moved here to solve duplicate MARK's if any of the CTCP_* conditions were false 05/13/2009 */
          sent = 1;

          if (feature_bool(FEAT_CTCP_VERSIONING_CHAN)) {
            sprintf(temp, "%s has version \002%s\002", cli_name(sptr), cli_version(sptr));
            /* Announce to channel. */
            if ((chptr = FindChannel(feature_str(FEAT_CTCP_VERSIONING_CHANNAME)))) {
              if (feature_bool(FEAT_CTCP_VERSIONING_USEMSG))
                sendcmdto_channel_butone(&me, CMD_PRIVATE, chptr, cptr, SKIP_DEAF | SKIP_BURST, '\0', "%H :%s", chptr, temp);
              else
                sendcmdto_channel_butone(&me, CMD_NOTICE, chptr, cptr, SKIP_DEAF | SKIP_BURST, '\0', "%H :%s", chptr, temp);
              /* Removed sent=1 from here because it caused the MARK above to be sent
                 more then once if any of the conditions leading here are false 05/13/2009 */
            }
          }

          if (feature_bool(FEAT_CTCP_VERSIONING_KILL)) {
            if ((found_g = find_kill(acptr))) {
              sendto_opmask_butone(0, found_g == -2 ? SNO_GLINE : SNO_OPERKILL,
                                   found_g == -2 ? "G-line active for %s%s" :
                                   "K-line active for %s%s",
                                   IsUnknown(sptr) ? "Unregistered Client ":"",
                                   get_client_name(sptr, SHOW_IP));
              return exit_client_msg(cptr, acptr, &me, "Banned Client: %s", cli_version(acptr));
            }
          }
          else
            return 0;
        }
      }
    }
  }

  for (i = 0; i < count; ++i) {
    name = vector[i];
    if (IsChannelPrefix(*name)) {
      ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_CHANNOTICE, name);
      if (ret != 0) {
        if (ret == 2)
          return CPTR_KILLED;
        else
          return 0;
      }
    } else {
      #ifdef _GNU_SOURCE
      if ((temp = strcasestr(parv[2], "\001DCC"))) {
        temp = strchrnul(parv[2], ' ');
      #else
      if ((temp = strstr(parv[2], "\001DCC")) || (temp = strstr(parv[2], "\001dcc"))) {
        temp = strchr(parv[2], ' ');
      #endif
        isdcc = 1;
        ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_DCC, name);
        if (ret != 0) {
          if (ret == 2)
            return CPTR_KILLED;
          else
            return 0;
        }
      }

      if (!isdcc) {
        ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_NOTICE, name);
        if (ret != 0) {
          if (ret == 2)
            return CPTR_KILLED;
          else
            return 0;
        }
      }
    }
  }
  i = 0;

  for (i = 0; i < count; ++i) {
    name = vector[i];
    /*
     * channel msg?
     */
    if (IsChannelPrefix(*name)) {
      relay_channel_notice(sptr, name, parv[parc - 1], count);
    }
    /*
     * we have to check for the '@' at least once no matter what we do
     * handle it first so we don't have to do it twice
     */
    else if ((server = strchr(name, '@')))
      relay_directed_notice(sptr, name, server, parv[parc - 1]);
    else 
      relay_private_notice(sptr, name, parv[parc - 1]);
  }
  return 0;
}

/*
 * ms_notice - server message handler
 */
int ms_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char* name;
  char* server;

  ClrFlag(sptr, FLAG_TS8);

  if (parc < 3) {
    /*
     * we can't deliver it, sending an error back is pointless
     */
    return protocol_violation(sptr,"Not enough params for NOTICE");
  }
  name = parv[1];
  /*
   * channel msg?
   */
  if (IsChannelPrefix(*name)) {
    server_relay_channel_notice(sptr, name, parv[parc - 1]);
  }
  /*
   * coming from another server, we have to check this here
   */
  else if ('$' == *name && IsOper(sptr)) {
    server_relay_masked_notice(sptr, name, parv[parc - 1]);
  }
  else if ((server = strchr(name, '@'))) {
    /*
     * XXX - can't get away with not doing everything
     * relay_directed_notice has to do
     */
    relay_directed_notice(sptr, name, server, parv[parc - 1]);
  }
  else {
    server_relay_private_notice(sptr, name, parv[parc - 1]);
  }
  return 0;
}

/*
 * mo_notice - oper message handler
 */
int mo_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  char*           name;
  char*           server;
  int             i;
  int             count;
  char*           vector[MAXTARGETS];
  assert(0 != cptr);
  assert(cptr == sptr);

  ClrFlag(sptr, FLAG_TS8);

  if (parc < 2 || EmptyString(parv[1]))
    return send_reply(sptr, ERR_NORECIPIENT, MSG_NOTICE);

  if (parc < 3 || EmptyString(parv[parc - 1]))
    return send_reply(sptr, ERR_NOTEXTTOSEND);

  if (parv[1][0] == '@' && IsChannelPrefix(parv[1][1])) {
    parv[1]++;                        /* Get rid of '@' */
    return m_wallchops(cptr, sptr, parc, parv);
  }

  count = unique_name_vector(parv[1], ',', vector, MAXTARGETS);

  for (i = 0; i < count; ++i) {
    name = vector[i];
    /*
     * channel msg?
     */
    if (IsChannelPrefix(*name))
      relay_channel_notice(sptr, name, parv[parc - 1], count);

    else if (*name == '$')
      relay_masked_notice(sptr, name, parv[parc - 1]);

    else if ((server = strchr(name, '@')))
      relay_directed_notice(sptr, name, server, parv[parc - 1]);

    else 
      relay_private_notice(sptr, name, parv[parc - 1]);
  }
  return 0;
}
Exemplo n.º 4
0
void process()
{
    int retVal = 0;
    Message *current = NULL;
    char source[64];
    char cmd[64];
    char buf[512];              /* Longest legal IRC command line */
    char *s;
    int ac;                     /* Parameters for the command */
    char **av;
    Message *m;

    /* zero out the buffers before we do much else */
    *buf = '\0';
    *source = '\0';
    *cmd = '\0';

    /* If debugging, log the buffer */
    if (debug) {
        alog("debug: Received: %s", inbuf);
    }

    /* First make a copy of the buffer so we have the original in case we
     * crash - in that case, we want to know what we crashed on. */
    strscpy(buf, inbuf, sizeof(buf));

    doCleanBuffer((char *) buf);

    /* Split the buffer into pieces. */
    if (*buf == ':') {
        s = strpbrk(buf, " ");
        if (!s)
            return;
        *s = 0;
        while (isspace(*++s));
        strscpy(source, buf + 1, sizeof(source));
        memmove(buf, s, strlen(s) + 1);
    } else {
        *source = 0;
    }
    if (!*buf)
        return;
    s = strpbrk(buf, " ");
    if (s) {
        *s = 0;
        while (isspace(*++s));
    } else
        s = buf + strlen(buf);
    strscpy(cmd, buf, sizeof(cmd));
    ac = split_buf(s, &av, 1);
    if (protocoldebug) {
        protocol_debug(source, cmd, ac, av);
    }
    if (mod_current_buffer) {
        free(mod_current_buffer);
    }
    /* fix to moduleGetLastBuffer() bug 296 */
    /* old logic was that since its meant for PRIVMSG that we would get
       the NICK as AV[0] and the rest would be in av[1], however on Bahamut
       based systems when you do /cs it assumes we will translate the command
       to the NICK and thus AV[0] is the message. The new logic is to check
       av[0] to see if its a service nick if so assign mod_current_buffer the
       value from AV[1] else just assign av[0] - TSL */
    /* First check if the ircd proto module overrides this -GD */
    /* fix to moduleGetLastBuffer() bug 476:
       fixed in part by adding {} to nickIsServices()
       however if you have a pseudo they could not use moduleGetLastBuffer()
       cause they are not part of nickIsServices, even those the ac count is 2
       that was ignored and only the first param was passed on which is fine for
       Bahmut ircd aliases but not for pseudo clients on. So additional logic is
       that if the ac is greater then 1 copy av[1] else copy av[0] 
       I also changed from if statments, cause attempting to access a array member
       that is not set can lead to odd things - TSL (3/12/06) */
    if (!xanadu_set_mod_current_buffer(ac, av)) {
        if (ac >= 1) {
            if (nickIsServices(av[0], 1)) {
                mod_current_buffer =
                    (ac > 1 ? sstrdup(av[1]) : sstrdup(av[0]));
            } else {
                mod_current_buffer =
                    (ac > 1 ? sstrdup(av[1]) : sstrdup(av[0]));
            }
        } else {
            mod_current_buffer = NULL;
        }
    }
    /* Do something with the message. */
    m = find_message(cmd);
    if (m) {
        if (m->func) {
            mod_current_module_name = m->mod_name;
            retVal = m->func(source, ac, av);
            mod_current_module_name = NULL;
            if (retVal == MOD_CONT) {
                current = m->next;
                while (current && current->func && retVal == MOD_CONT) {
                    mod_current_module_name = current->mod_name;
                    retVal = current->func(source, ac, av);
                    mod_current_module_name = NULL;
                    current = current->next;
                }
            }
        }
    } else {
        if (debug)
            alog("debug: unknown message from server (%s)", inbuf);
    }

    /* Load/unload modules if needed */
    handleModuleOperationQueue();

    /* Free argument list we created */
    free(av);
}