mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 21:39:25 +01:00
commit
8ec9053448
@ -16,6 +16,7 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/ergochat/irc-go/ircutils"
|
"github.com/ergochat/irc-go/ircutils"
|
||||||
|
"github.com/tidwall/buntdb"
|
||||||
"github.com/xdg-go/scram"
|
"github.com/xdg-go/scram"
|
||||||
|
|
||||||
"github.com/ergochat/ergo/irc/connection_limits"
|
"github.com/ergochat/ergo/irc/connection_limits"
|
||||||
@ -24,7 +25,6 @@ import (
|
|||||||
"github.com/ergochat/ergo/irc/modes"
|
"github.com/ergochat/ergo/irc/modes"
|
||||||
"github.com/ergochat/ergo/irc/passwd"
|
"github.com/ergochat/ergo/irc/passwd"
|
||||||
"github.com/ergochat/ergo/irc/utils"
|
"github.com/ergochat/ergo/irc/utils"
|
||||||
"github.com/tidwall/buntdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -474,6 +474,8 @@ func (am *AccountManager) Register(client *Client, account string, callbackNames
|
|||||||
am.Unregister(casefoldedAccount, true)
|
am.Unregister(casefoldedAccount, true)
|
||||||
return ®istrationCallbackError{underlying: err}
|
return ®istrationCallbackError{underlying: err}
|
||||||
} else {
|
} else {
|
||||||
|
am.server.logger.Info("accounts",
|
||||||
|
fmt.Sprintf("nickname %s registered account %s, pending verification", client.Nick(), account))
|
||||||
return am.server.store.Update(func(tx *buntdb.Tx) error {
|
return am.server.store.Update(func(tx *buntdb.Tx) error {
|
||||||
_, _, err = tx.Set(verificationCodeKey, code, setOptions)
|
_, _, err = tx.Set(verificationCodeKey, code, setOptions)
|
||||||
return err
|
return err
|
||||||
|
@ -681,6 +681,7 @@ func csPurgeAddHandler(service *ircService, client *Client, params []string, ope
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully purged channel %s from the server"), chname))
|
service.Notice(rb, fmt.Sprintf(client.t("Successfully purged channel %s from the server"), chname))
|
||||||
|
client.server.snomasks.Send(sno.LocalChannels, fmt.Sprintf("Operator %s purged channel %s [reason: %s]", operName, chname, reason))
|
||||||
case errInvalidChannelName:
|
case errInvalidChannelName:
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Can't purge invalid channel %s"), chname))
|
service.Notice(rb, fmt.Sprintf(client.t("Can't purge invalid channel %s"), chname))
|
||||||
default:
|
default:
|
||||||
@ -698,6 +699,7 @@ func csPurgeDelHandler(service *ircService, client *Client, params []string, ope
|
|||||||
switch client.server.channels.Unpurge(chname) {
|
switch client.server.channels.Unpurge(chname) {
|
||||||
case nil:
|
case nil:
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Successfully unpurged channel %s from the server"), chname))
|
service.Notice(rb, fmt.Sprintf(client.t("Successfully unpurged channel %s from the server"), chname))
|
||||||
|
client.server.snomasks.Send(sno.LocalChannels, fmt.Sprintf("Operator %s removed purge of channel %s", operName, chname))
|
||||||
case errNoSuchChannel:
|
case errNoSuchChannel:
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s wasn't previously purged from the server"), chname))
|
service.Notice(rb, fmt.Sprintf(client.t("Channel %s wasn't previously purged from the server"), chname))
|
||||||
default:
|
default:
|
||||||
|
@ -155,6 +155,14 @@ func (cidr IPNet) Contains(ip IP) bool {
|
|||||||
return cidr.IP == maskedIP
|
return cidr.IP == maskedIP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cidr IPNet) Size() (ones, bits int) {
|
||||||
|
if cidr.IP.IsIPv4() {
|
||||||
|
return int(cidr.PrefixLen) - 96, 32
|
||||||
|
} else {
|
||||||
|
return int(cidr.PrefixLen), 128
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FromNetIPnet converts a net.IPNet into an IPNet.
|
// FromNetIPnet converts a net.IPNet into an IPNet.
|
||||||
func FromNetIPNet(network net.IPNet) (result IPNet) {
|
func FromNetIPNet(network net.IPNet) (result IPNet) {
|
||||||
ones, _ := network.Mask.Size()
|
ones, _ := network.Mask.Size()
|
||||||
|
@ -2,8 +2,10 @@ package flatip
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -86,6 +88,38 @@ func doMaskingTest(ip net.IP, t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertEqual(found, expected interface{}) {
|
||||||
|
if !reflect.DeepEqual(found, expected) {
|
||||||
|
panic(fmt.Sprintf("expected %#v, found %#v", expected, found))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSize(t *testing.T) {
|
||||||
|
_, net, err := ParseCIDR("8.8.8.8/24")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ones, bits := net.Size()
|
||||||
|
assertEqual(ones, 24)
|
||||||
|
assertEqual(bits, 32)
|
||||||
|
|
||||||
|
_, net, err = ParseCIDR("2001::0db8/64")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ones, bits = net.Size()
|
||||||
|
assertEqual(ones, 64)
|
||||||
|
assertEqual(bits, 128)
|
||||||
|
|
||||||
|
_, net, err = ParseCIDR("2001::0db8/96")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ones, bits = net.Size()
|
||||||
|
assertEqual(ones, 96)
|
||||||
|
assertEqual(bits, 128)
|
||||||
|
}
|
||||||
|
|
||||||
func TestMasking(t *testing.T) {
|
func TestMasking(t *testing.T) {
|
||||||
for _, ipstr := range testIPStrs {
|
for _, ipstr := range testIPStrs {
|
||||||
doMaskingTest(easyParseIP(ipstr), t)
|
doMaskingTest(easyParseIP(ipstr), t)
|
||||||
|
@ -81,6 +81,10 @@ func registrationErrorToMessage(config *Config, client *Client, err error) (mess
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func announcePendingReg(client *Client, rb *ResponseBuffer, accountName string) {
|
||||||
|
client.server.snomasks.Send(sno.LocalAccounts, fmt.Sprintf(ircfmt.Unescape("Client $c[grey][$r%s$c[grey]] attempted to register account $c[grey][$r%s$c[grey]] from IP %s, pending verification"), client.Nick(), accountName, rb.session.IP().String()))
|
||||||
|
}
|
||||||
|
|
||||||
// helper function to dispatch messages when a client successfully registers
|
// helper function to dispatch messages when a client successfully registers
|
||||||
func sendSuccessfulRegResponse(service *ircService, client *Client, rb *ResponseBuffer) {
|
func sendSuccessfulRegResponse(service *ircService, client *Client, rb *ResponseBuffer) {
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
@ -2632,6 +2636,7 @@ func registerHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
|
|||||||
} else {
|
} else {
|
||||||
rb.Add(nil, server.name, "REGISTER", "VERIFICATION_REQUIRED", accountName, fmt.Sprintf(client.t("Account created, pending verification; verification code has been sent to %s"), callbackValue))
|
rb.Add(nil, server.name, "REGISTER", "VERIFICATION_REQUIRED", accountName, fmt.Sprintf(client.t("Account created, pending verification; verification code has been sent to %s"), callbackValue))
|
||||||
client.registerCmdSent = true
|
client.registerCmdSent = true
|
||||||
|
announcePendingReg(client, rb, accountName)
|
||||||
}
|
}
|
||||||
case errAccountAlreadyRegistered, errAccountAlreadyUnregistered, errAccountMustHoldNick:
|
case errAccountAlreadyRegistered, errAccountAlreadyUnregistered, errAccountMustHoldNick:
|
||||||
rb.Add(nil, server.name, "FAIL", "REGISTER", "USERNAME_EXISTS", accountName, client.t("Username is already registered or otherwise unavailable"))
|
rb.Add(nil, server.name, "FAIL", "REGISTER", "USERNAME_EXISTS", accountName, client.t("Username is already registered or otherwise unavailable"))
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ergochat/irc-go/ircfmt"
|
"github.com/ergochat/irc-go/ircfmt"
|
||||||
|
|
||||||
|
"github.com/ergochat/ergo/irc/sno"
|
||||||
"github.com/ergochat/ergo/irc/utils"
|
"github.com/ergochat/ergo/irc/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -159,6 +160,7 @@ func validateVhost(server *Server, vhost string, oper bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func hsSetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
func hsSetHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||||
|
oper := client.Oper()
|
||||||
user := params[0]
|
user := params[0]
|
||||||
var vhost string
|
var vhost string
|
||||||
|
|
||||||
@ -176,8 +178,10 @@ func hsSetHandler(service *ircService, server *Server, client *Client, command s
|
|||||||
service.Notice(rb, client.t("An error occurred"))
|
service.Notice(rb, client.t("An error occurred"))
|
||||||
} else if vhost != "" {
|
} else if vhost != "" {
|
||||||
service.Notice(rb, client.t("Successfully set vhost"))
|
service.Notice(rb, client.t("Successfully set vhost"))
|
||||||
|
server.snomasks.Send(sno.LocalVhosts, fmt.Sprintf("Operator %s set vhost %s on account %s", oper.Name, user, vhost))
|
||||||
} else {
|
} else {
|
||||||
service.Notice(rb, client.t("Successfully cleared vhost"))
|
service.Notice(rb, client.t("Successfully cleared vhost"))
|
||||||
|
server.snomasks.Send(sno.LocalVhosts, fmt.Sprintf("Operator %s cleared vhost on account %s", oper.Name, user))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,6 +1004,7 @@ func nsRegisterHandler(service *ircService, server *Server, client *Client, comm
|
|||||||
messageTemplate := client.t("Account created, pending verification; verification code has been sent to %s")
|
messageTemplate := client.t("Account created, pending verification; verification code has been sent to %s")
|
||||||
message := fmt.Sprintf(messageTemplate, callbackValue)
|
message := fmt.Sprintf(messageTemplate, callbackValue)
|
||||||
service.Notice(rb, message)
|
service.Notice(rb, message)
|
||||||
|
announcePendingReg(client, rb, account)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// details could not be stored and relevant numerics have been dispatched, abort
|
// details could not be stored and relevant numerics have been dispatched, abort
|
||||||
|
15
irc/uban.go
15
irc/uban.go
@ -366,7 +366,14 @@ func ubanInfoHandler(client *Client, target ubanTarget, params []string, rb *Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ubanInfoCIDR(client *Client, target ubanTarget, rb *ResponseBuffer) {
|
func ubanInfoCIDR(client *Client, target ubanTarget, rb *ResponseBuffer) {
|
||||||
if target.cidr.PrefixLen == 128 {
|
config := client.server.Config()
|
||||||
|
// show connection limiter/throttler state if this CIDR is entirely
|
||||||
|
// contained in a single limiter/throttler bucket:
|
||||||
|
ones, bits := target.cidr.Size()
|
||||||
|
showLimiter := (bits == 32 && ones >= config.Server.IPLimits.CidrLenIPv4) ||
|
||||||
|
(bits == 128 && ones >= config.Server.IPLimits.CidrLenIPv6)
|
||||||
|
sendMaskWarning := (bits == 128 && ones > config.Server.IPLimits.CidrLenIPv6)
|
||||||
|
if showLimiter {
|
||||||
netName, status := client.server.connectionLimiter.Status(target.cidr.IP)
|
netName, status := client.server.connectionLimiter.Status(target.cidr.IP)
|
||||||
if status.Exempt {
|
if status.Exempt {
|
||||||
rb.Notice(fmt.Sprintf(client.t("IP %s is exempt from connection limits"), target.cidr.IP.String()))
|
rb.Notice(fmt.Sprintf(client.t("IP %s is exempt from connection limits"), target.cidr.IP.String()))
|
||||||
@ -391,6 +398,10 @@ func ubanInfoCIDR(client *Client, target ubanTarget, rb *ResponseBuffer) {
|
|||||||
rb.Notice(line)
|
rb.Notice(line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if sendMaskWarning {
|
||||||
|
rb.Notice(fmt.Sprintf(client.t("Note: try evaluating a wider IPv6 CIDR like %s/%d"),
|
||||||
|
target.cidr.IP.String(), config.Server.IPLimits.CidrLenIPv6))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ubanInfoNickmask(client *Client, target ubanTarget, rb *ResponseBuffer) {
|
func ubanInfoNickmask(client *Client, target ubanTarget, rb *ResponseBuffer) {
|
||||||
@ -434,7 +445,7 @@ func ubanInfoNick(client *Client, target ubanTarget, rb *ResponseBuffer) {
|
|||||||
rb.Notice(fmt.Sprintf(client.t("Client %[1]s is unauthenticated and connected from %[2]s"), details.nick, ip.String()))
|
rb.Notice(fmt.Sprintf(client.t("Client %[1]s is unauthenticated and connected from %[2]s"), details.nick, ip.String()))
|
||||||
sendIPBanWarning = true
|
sendIPBanWarning = true
|
||||||
} else {
|
} else {
|
||||||
rb.Notice(fmt.Sprintf(client.t("Client %[1]s is logged into account %[2]s and has %[3]d active clients (see /NICKSERV CLIENTS LIST %[4]s for more info"), details.nick, details.accountName, len(mcl.Sessions()), details.nick))
|
rb.Notice(fmt.Sprintf(client.t("Client %[1]s is logged into account %[2]s and has %[3]d active clients (see /NICKSERV CLIENTS LIST %[4]s for more info)"), details.nick, details.accountName, len(mcl.Sessions()), details.nick))
|
||||||
if !ip.IsLoopback() && len(sessions) == 1 {
|
if !ip.IsLoopback() && len(sessions) == 1 {
|
||||||
rb.Notice(fmt.Sprintf(client.t("Client %[1]s is associated with IP %[2]s"), details.nick, ip.String()))
|
rb.Notice(fmt.Sprintf(client.t("Client %[1]s is associated with IP %[2]s"), details.nick, ip.String()))
|
||||||
sendIPBanWarning = true
|
sendIPBanWarning = true
|
||||||
|
Loading…
Reference in New Issue
Block a user