Example #1
0
func (ib *IrcBot) parsePacket(conn *irc.Conn, line *irc.Line) *models.Packet {
	result := ib.regex.FindStringSubmatch(line.Text())
	if result == nil {
		return nil
	}

	fileName := cleanFileName(result[3])
	packet := models.NewPacket(result[1], result[2], fileName, line.Nick, line.Target(), ib.server.Name, line.Time)

	//save packet
	if packet != nil {
		ib.dataService.SavePacket(packet)
	}

	return packet
}
Example #2
0
// Handles triggers if module is enabled and user/chan is allowed. This is mainly
// exported for use by library and should not have to be called by the user
func (self *Module) Handle(eventMode Event, trigger string, line *irc.Line) {
	// Filtered by: denyUser, allowUser, denyChan, allowChan
	if !self.Enabled() ||
		self.InDenyed(line.Nick) ||
		// Empty allowUser list => allow all
		(self.LenAllowed(UC_User) != 0 && !self.InAllowed(line.Nick)) ||
		self.InDenyed(line.Target()) ||
		// Empty denyChan list => allow all
		(self.LenAllowed(UC_Chan) != 0 && !self.InAllowed(line.Target())) {

		return
	}

	eventMode = Event(strings.ToUpper(string(eventMode)))

	go self.handleString(eventMode, trigger, line)
	go self.handleRegexp(eventMode, trigger, line)
}
Example #3
0
func (ei *EndpointIRC) message(c *irc.Conn, l *irc.Line) {
	var messageTarget MessageTarget
	if l.Public() {
		messageTarget = ei.GetChannel(l.Target())
	} else {
		messageTarget = ei.GetUser(l.Target())
	}
	ei.handler(l.Text(), ei.GetUser(l.Nick), l.Target(), messageTarget)
}
Example #4
0
func (plugin *Plugin) OnJoin(conn *client.Conn, line *client.Line) {
	logging.Info("vpnbot.Plugin: %v joined %v", line.Src, line.Target())

	if lastCheck, ok := plugin.lastCheckNicks[line.Nick]; ok && time.Now().Sub(lastCheck) < 15*time.Minute {
		// There is a check in progress or another one has been done earlier
		logging.Debug("vpnbot.Plugin: Not checking %v, last check was %v",
			line.Nick, humanize.Time(plugin.lastCheckNicks[line.Nick]))
		return
	}
	logging.Debug("vpnbot.Plugin: Checking %v...", line.Nick)
	plugin.lastCheckNicks[line.Nick] = time.Now()

	// Is this me?
	if line.Nick == conn.Me().Nick {
		logging.Debug("vpnbot.Plugin: %v is actually me, skipping.", line.Nick)
		return
	}

	// Nickname == Ident? (9 chars cut)
	if !strings.HasPrefix(nonWordCharsRegex.ReplaceAllString(line.Nick, ""),
		strings.TrimLeft(line.Ident, "~")) {
		logging.Debug("vpnbot.Plugin: %v's nick doesn't match the ident, skipping.", line.Nick)
		return
	}

	// Hostname is masked RDNS vhost/IP?
	// TODO - Use regex to avoid banning due to similar vhosts
	if !maskedAddrRegex.MatchString(line.Host) {
		// Detected custom vHost
		logging.Debug("vpnbot.Plugin: %v has a custom vhost, skipping.", line.Nick)
		return
	}

	go func() {
		botNick := line.Nick

		nobotActivityChan := make(chan string)
		defer plugin.bot.HandleFunc("privmsg",
			func(conn *client.Conn, line *client.Line) {
				if line.Nick == botNick {
					nobotActivityChan <- "User sent a message"
				}
			}).Remove()
		defer plugin.bot.HandleFunc("noticed",
			func(conn *client.Conn, line *client.Line) {
				if line.Nick == botNick {
					nobotActivityChan <- "User sent a notice"
				}
			}).Remove()
		defer plugin.bot.HandleFunc("part",
			func(conn *client.Conn, line *client.Line) {
				if line.Nick == botNick {
					nobotActivityChan <- "User left"
				}
			}).Remove()
		defer plugin.bot.HandleFunc("part",
			func(conn *client.Conn, line *client.Line) {
				if line.Nick == botNick {
				}

				if len(line.Args) > 0 {
					switch line.Args[0] {
					case "Excess flood":
						// If this was an excess flood, consider it spam that should
						// be good to ban anyways
						nobotActivityChan <- "Excess flood, banning early"
						banmask := fmt.Sprintf("%v!%v@%v", "*", "*", line.Host)
						// TODO - Ramp up/down the duration with increasing/decreasing activity of the bots
						plugin.banGlobal(plugin.generateBan(line.Nick, banmask,
							"Instant excess flood", 2*24*time.Hour))
					default:
						nobotActivityChan <- "User quit normally"
					}
				}
			}).Remove()

		// Give nobotActivityChan some time to prove this is not a bot
		select {
		case reason := <-nobotActivityChan:
			logging.Info("vpnbot.Plugin: %v, skipping.", reason)
			return
		case <-time.After(1 * time.Second):
		}

		// Get WHOIS info
		info, err := plugin.whois.WhoIs(line.Nick)
		if err != nil && err != whois.ErrNoSuchNick {
			logging.Warn("vpnbot.Plugin: Can't get WHOIS info for %v, skipping: %v",
				line.Nick, err.Error())
			return
		}

		// Not an oper?
		if info.IsOperator {
			logging.Debug("vpnbot.Plugin: %v is operator, skipping.",
				line.Nick)
			return
		}

		// Not away
		if info.IsAway {
			logging.Debug("vpnbot.Plugin: %v is away, skipping.", line.Nick)
			return
		}

		// Realname == Nickname?
		if info.Realname != line.Nick {
			logging.Debug(
				"vpnbot.Plugin: %v's nick doesn't match the realname, skipping.",
				line.Nick)
			return
		}

		// Count of channels at least 48
		if len(info.Channels) < 48 {
			logging.Debug(
				"vpnbot.Plugin: %v is not in a high amount of channels, skipping.",
				line.Nick)
			return
		}

		// Not halfop, op, aop or owner in any channel
		for _, prefix := range info.Channels {
			if prefix == '%' || prefix == '@' ||
				prefix == '&' || prefix == '~' {
				logging.Debug(
					"vpnbot.Plugin: %v is opped in a channel, skipping.",
					line.Nick)
				return
			}
		}

		// Give nobotActivityChan some time to prove this is not a bot
		select {
		case reason := <-nobotActivityChan:
			logging.Info("vpnbot.Plugin: %v, skipping.", reason)
			return
		case <-time.After(250 * time.Millisecond):
		}

		// More expensive tests below...

		// Make sure we deal with an unregistered client

		status := plugin.nickserv.Status(line.Nick)[line.Nick]
		if status.Error != nil {
			logging.Warn("vpnbot.Plugin: Can't get auth status for %v, skipping: %v",
				line.Nick, status.Error)
			return
		}
		if status.Level >= nickserv.Status_IdentifiedViaPassword {
			logging.Debug("vpnbot.Plugin: %v is identified, skipping.",
				line.Nick)
			return
		}

		// Give nobotActivityChan some time to prove this is not a bot
		select {
		case reason := <-nobotActivityChan:
			logging.Info("vpnbot.Plugin: %v, skipping.", reason)
			return
		case <-time.After(250 * time.Millisecond):
		}

		// This is a bot we need to ban!
		banmask := fmt.Sprintf("%v!%v@%v", "*", "*", line.Host)
		// TODO - Ramp up/down the duration with increasing/decreasing activity of the bots
		plugin.banGlobal(plugin.generateBan(line.Nick, banmask,
			"Known pattern of ban-evading/logging bot", 2*24*time.Hour))
	}()
}