[WIP] Fix ban by software version, some other under-hood changes
- Use updated version of upstream go-xmpp + fixes on client-side - Introduce golangci-lint v2 + fixes - Move especially noisy debugging stuff to separate config handles to be able to switch them off - Add a bit debug to ban by software path
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
)
|
||||
|
||||
// BunyPresense производит проверку по бело-чёрным спискам. Если presence пришёл от злодея (из чёрного списка), то
|
||||
@@ -28,7 +28,11 @@ func (j *Jabber) BunyPresense(v xmpp.Presence) error { //nolint:gocognit,gocyclo
|
||||
room := strings.SplitN(v.From, "/", 2)[0]
|
||||
|
||||
if room == "" {
|
||||
log.Infof("We got empty room field in presence event, which kinda strange: %s", spew.Sdump(v))
|
||||
msg := "We got empty room field in presence event, which kinda strange: " + spew.Sdump(v)
|
||||
|
||||
for str := range strings.SplitSeq(msg, "\n") {
|
||||
log.Info(str)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -419,32 +423,42 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
|
||||
_ = json.Unmarshal([]byte(presenceJSONString), &p)
|
||||
|
||||
if p.Affiliation == "admin" || p.Affiliation == "owner" {
|
||||
log.Infof("Skipping useragent blacklist check for %s because his affiliation is %s", v.From, p.Affiliation)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// На всякий случай.
|
||||
if p.Role == "moderator" {
|
||||
log.Infof("Skipping useragent blacklist check for %s because his role is %s", v.From, p.Role)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if v.From == p.From {
|
||||
log.Errorf("Found jid of %s in presence db: %s", v.From, p.JID)
|
||||
log.Infof("Found jid of %s in presence db: %s", v.From, p.JID)
|
||||
|
||||
if p.Affiliation == "admin" || p.Affiliation == "owner" {
|
||||
log.Infof("Skipping useragent blacklist check for %s because his affiliation is %s", v.From, p.Affiliation)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// На всякий случай.
|
||||
if p.Role == "moderator" {
|
||||
log.Infof("Skipping useragent blacklist check for %s because his role is %s", v.From, p.Role)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debug("Useragent is not owner or moderator, proceeding with check...")
|
||||
|
||||
// Lookup in global blacklist.
|
||||
log.Debug("Find our room in connected room list...")
|
||||
|
||||
for _, cRoom := range j.RoomsConnected {
|
||||
if cRoom == room {
|
||||
log.Debug("Found our room in list of connected rooms")
|
||||
|
||||
for _, bEntry := range j.BlackList.Blacklist {
|
||||
// Обработаем правила глобального чёрного списка.
|
||||
if bEntry.RoomName == "" {
|
||||
log.Debugf("Check in global blacklist")
|
||||
|
||||
for _, useragent := range bEntry.UserAgent {
|
||||
switch {
|
||||
case useragent.Name != "" && useragent.Version != "" && useragent.Os != "":
|
||||
if ver.Name == useragent.Name && ver.Version == useragent.Version && ver.Os == useragent.Os {
|
||||
log.Debug("Found all 3 components in black list, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
@@ -462,6 +476,8 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
|
||||
case useragent.Name != "" && useragent.Version != "":
|
||||
if ver.Name == useragent.Name && ver.Version == useragent.Version {
|
||||
log.Debug("Found sw name and version in blacklist, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
@@ -479,6 +495,8 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
|
||||
case useragent.Name != "":
|
||||
if ver.Name == useragent.Name {
|
||||
log.Debug("Found sw name in blacklist, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
@@ -496,6 +514,8 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
|
||||
case useragent.Version != "":
|
||||
if ver.Version == useragent.Version {
|
||||
log.Debug("Found sw version in blacklist, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
@@ -515,10 +535,14 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
}
|
||||
|
||||
if bEntry.RoomName == room {
|
||||
log.Debug("Found blacklist entries for room")
|
||||
|
||||
for _, useragent := range bEntry.UserAgent {
|
||||
switch {
|
||||
case useragent.Name != "" && useragent.Version != "" && useragent.Os != "":
|
||||
if ver.Name == useragent.Name && ver.Version == useragent.Version && ver.Os == useragent.Os {
|
||||
log.Debug("Found all 3 components in black list, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
@@ -536,6 +560,8 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
|
||||
case useragent.Name != "" && useragent.Version != "":
|
||||
if ver.Name == useragent.Name && ver.Version == useragent.Version {
|
||||
log.Debug("Found sw name and version in blacklist, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
@@ -553,6 +579,8 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
|
||||
case useragent.Name != "":
|
||||
if ver.Name == useragent.Name {
|
||||
log.Debug("Found sw name in blacklist, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
@@ -570,6 +598,8 @@ func (j *Jabber) BunySoftwareVersion(v xmpp.IQ, ver IqResultSoftwareVersion) err
|
||||
|
||||
case useragent.Version != "":
|
||||
if ver.Version == useragent.Version {
|
||||
log.Debug("Found sw version in blacklist, it is ban")
|
||||
|
||||
id, err := j.Squash(room, p.JID, bEntry.ReasonEnable, v.Type)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
)
|
||||
|
||||
// Cmd парсит команды из чятика.
|
||||
@@ -222,7 +222,11 @@ func (j *Jabber) Cmd(v xmpp.Chat) error {
|
||||
}
|
||||
|
||||
default:
|
||||
log.Infof("Rehash command from outer space: %s", spew.Sdump(v))
|
||||
msg := "Rehash command from outer space: " + spew.Sdump(v)
|
||||
|
||||
for str := range strings.SplitSeq(msg, "\n") {
|
||||
log.Info(str)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,13 @@ import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
)
|
||||
|
||||
// ParseEvent парсит ивенты, прилетающие из модуля xmpp (изменения presence, фразы участников, ошибки).
|
||||
@@ -83,7 +82,9 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
case "error":
|
||||
// Это ошибка со стороны сервера, видимо, в ответ на наши действия и поскольку такие вещи происходят
|
||||
// асинхронно, связать их с конкретными нашими действиями довольно сложно.
|
||||
log.Warn(spew.Sdump(e))
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Error(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,66 +114,6 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
|
||||
if err := xml.Unmarshal(v.Query, &iqStruct); err == nil {
|
||||
switch iqStruct.Xmlns { //nolint:wsl,whitespace
|
||||
// Запрос номера версии приложения.
|
||||
case "jabber:iq:version":
|
||||
log.Infof("Got IQ get request for version from %s", v.From)
|
||||
|
||||
if id, err := j.Talk.IqVersionResponse(
|
||||
v,
|
||||
j.C.ExeName,
|
||||
j.C.Version,
|
||||
(strings.SplitN(runtime.GOOS, "/", 2))[0],
|
||||
); err != nil {
|
||||
err := fmt.Errorf(
|
||||
"unable to send version info to jabber server: id=%s, err=%w",
|
||||
id,
|
||||
err,
|
||||
)
|
||||
|
||||
j.GTomb.Kill(err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
parseError = false
|
||||
|
||||
// Нам прислали попингуй.
|
||||
case "urn:xmpp:ping":
|
||||
log.Infof("Got IQ get request for pong from %s", v.From)
|
||||
|
||||
if id, err := j.Talk.PingResponse(v); err != nil {
|
||||
err := fmt.Errorf(
|
||||
"unable to send pong to jabber server: id=%s, err=%w",
|
||||
id,
|
||||
err,
|
||||
)
|
||||
|
||||
j.GTomb.Kill(err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
parseError = false
|
||||
|
||||
// У нас запросили время последней активности. В нашем случае это либо время запуска клиента, либо время
|
||||
// последней фразы в чяти. Xep-0012.
|
||||
case "jabber:iq:last":
|
||||
log.Infof("Got IQ get last activity time request from %s", v.From)
|
||||
|
||||
if id, err := j.Talk.JabberIqLastResponse(v, j.LastActivity); err != nil {
|
||||
err := fmt.Errorf(
|
||||
"unable to send last activity time to jabber server: id=%s, err=%w",
|
||||
id,
|
||||
err,
|
||||
)
|
||||
|
||||
j.GTomb.Kill(err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
parseError = false
|
||||
|
||||
// Запрос на список поддерживаемых фич - версия, локальное время, итд.
|
||||
case xmpp.XMPPNS_DISCO_INFO:
|
||||
log.Infof("Got IQ get disco#info request from %s", v.From)
|
||||
@@ -233,7 +174,10 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
// Запрашивают что-то, о чём мы не имеем представления.
|
||||
default:
|
||||
log.Info("Got an unknown IQ get request, discarding")
|
||||
log.Info(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -266,7 +210,10 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
|
||||
default:
|
||||
log.Info("Got bogus IQ get time request, discarding")
|
||||
log.Info(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -303,7 +250,10 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
|
||||
default:
|
||||
log.Info("Got unknown IQ get pubsub something request, discarding")
|
||||
log.Info(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
|
||||
parseError = true //nolint:wsl
|
||||
}
|
||||
@@ -312,35 +262,13 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
}
|
||||
}
|
||||
|
||||
// Попробуем распарсить входящий запрос как urn:xmpp:ping он приходит при MUC Self-Ping (Schrödinger's Chat).
|
||||
// Предполагается, что такие респонсы должны приходить только для пинга без серверной оптимизации.
|
||||
// Хотя идейно мы не поддерживаем работу без серверной оптимизации, но на пинг ответим, нам несложно.
|
||||
if parseError {
|
||||
var iqStruct IqPing
|
||||
|
||||
if err := xml.Unmarshal(v.Query, &iqStruct); err == nil {
|
||||
log.Debugf("Got IQ get request (actually, response) for MUC Self-Ping from %s", v.From)
|
||||
|
||||
if id, err := j.Talk.PingResponse(v); err != nil {
|
||||
err := fmt.Errorf(
|
||||
"unable to send pong to jabber server: id=%s, err=%w",
|
||||
id,
|
||||
err,
|
||||
)
|
||||
|
||||
j.GTomb.Kill(err)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
parseError = false
|
||||
}
|
||||
|
||||
// Не знаю, как парсить... залоггируем это дело и пойдём дальше.
|
||||
if parseError {
|
||||
log.Infof("Does not look like parsable via iqStruct")
|
||||
log.Info(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
|
||||
case xmpp.IQTypeResult:
|
||||
@@ -381,7 +309,10 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
} else {
|
||||
// Поскольку никакой логики у нас на этот счёт не предусмотрено, то просто пропускаем ответ.
|
||||
log.Infof("Got unknown pong from %s to %s", v.From, v.To)
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,15 +346,24 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
log.Infof("Got ban successful from %s to %s", v.From, v.To)
|
||||
} else {
|
||||
log.Infof("Got ban successful from %s to %s, from room we are not in", v.From, v.To)
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Infof("Got strange ban successful message from %s to %s", v.From, v.To)
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Infof("Got strange ban successful message from %s to %s", v.From, v.To)
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
|
||||
// Ответ с результатом адресован нам.
|
||||
@@ -459,11 +399,17 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
}
|
||||
|
||||
log.Info("Got an IQ result. Dunno how deal with it, discarding")
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
|
||||
default:
|
||||
log.Info("Got an IQ result. Dunno how deal with it, discarding")
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
|
||||
// Этот бот не управляется со стороны сервера, поэтому все попытки порулить игнорируем.
|
||||
@@ -492,8 +438,9 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
// Нам прилетело сообщение об ошибке.
|
||||
case xmpp.IQTypeError:
|
||||
// Если сервер не хочет пинговаться и отвечает ошибкой на пинг, то наверно он не умеет в пинги,
|
||||
@@ -517,7 +464,10 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
}
|
||||
} else {
|
||||
log.Error("Iq parsed as ping, but does not belong to xmlns urn:xmpp:ping")
|
||||
log.Error(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
parseError = false
|
||||
@@ -556,14 +506,68 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
"looks like message parsed as jabberIqErrorCancelNotAcceptable but we're not in given room",
|
||||
)
|
||||
|
||||
log.Error(spew.Sdump(e))
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Error(
|
||||
"Looks like message parsed as jabberIqErrorCancelNotAcceptable but addressed not to us",
|
||||
)
|
||||
|
||||
log.Error(spew.Sdump(e))
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
|
||||
parseError = false
|
||||
}
|
||||
}
|
||||
|
||||
if parseError {
|
||||
var IqErrorCancelServiceNotAvailable IqErrorCancelServiceNotAvailable
|
||||
|
||||
if err := xml.Unmarshal(v.Query, &IqErrorCancelServiceNotAvailable); err == nil {
|
||||
if v.To == j.Talk.JID() {
|
||||
log.Infof("Jid %s disabled response to iq.version(?) request", v.From)
|
||||
} else {
|
||||
log.Error(
|
||||
"Looks like message parsed as jabberIqErrorCancelServiceNotAvailable but addressed not to us",
|
||||
)
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
|
||||
parseError = false
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
<iq from='slackware-current@conference.jabber.ru/Batman46(new)' to='buny@jabber.ru/Лунная призма'
|
||||
type='error' id='94e55122-6c15-4e88-a0df-ae9f02e0b550'>
|
||||
<query xmlns='jabber:iq:version'/>
|
||||
<error code='404' type='cancel'>
|
||||
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Адресата нет в конференции</text>
|
||||
</error>
|
||||
</iq>
|
||||
*/
|
||||
if parseError {
|
||||
var IqErrorCancelItemNotFound IqErrorCancelItemNotFound
|
||||
|
||||
if err := xml.Unmarshal(v.Query, &IqErrorCancelItemNotFound); err == nil {
|
||||
if v.To == j.Talk.JID() {
|
||||
log.Infof("Jid %s disabled response to iq.version(?) request, hello batman46(new)", v.From)
|
||||
} else {
|
||||
log.Error(
|
||||
"Looks like message parsed as jabberIqErrorCancelServiceNotAvailable but addressed not to us",
|
||||
)
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
|
||||
parseError = false
|
||||
@@ -572,12 +576,19 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
|
||||
if parseError {
|
||||
log.Error("Unhandled IQ Error message")
|
||||
log.Error(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
// Нам прилетело что-то неизвестное из семейства IQ stanza.
|
||||
|
||||
// Нам прилетело что-то неизвестное из семейства IQ stanza.
|
||||
default:
|
||||
log.Info("Got an unknown IQ request. Dunno how deal with it, discarding")
|
||||
log.Info(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
|
||||
// Смена статуса участника.
|
||||
@@ -614,7 +625,10 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
} else {
|
||||
log.Errorf("Presence notification, Type: %s, From: %s, Show: %s, Status: %s",
|
||||
v.Type, v.From, v.Show, v.Status)
|
||||
log.Error(spew.Sdump(v))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Error(str)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Infof(
|
||||
@@ -746,13 +760,18 @@ func (j *Jabber) ParseEvent(e any) { //nolint:maintidx,gocognit,gocyclo
|
||||
|
||||
default:
|
||||
log.Debug("Got unknown reply to disco#info")
|
||||
log.Debug(spew.Sdump(e))
|
||||
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Debug(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Это что-то неизвестное, подампим событие в лог.
|
||||
default:
|
||||
log.Info(spew.Sdump(e))
|
||||
for str := range strings.SplitSeq(spew.Sdump(e), "\n") {
|
||||
log.Info(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"buny-jabber-bot/internal/log"
|
||||
"fmt"
|
||||
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/google/uuid"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
)
|
||||
|
||||
// QuerySoftwareVersion запрошивает версию и название клиента.
|
||||
// QuerySoftwareVersion запрашивает версию и название клиента.
|
||||
func (j *Jabber) QuerySoftwareVersion(jid string) (string, error) {
|
||||
var (
|
||||
id string
|
||||
|
||||
@@ -261,6 +261,7 @@ func (j *Jabber) ReadConfig() error { //nolint:gocognit,gocyclo
|
||||
log.Info("loglevel not defined in config, using info")
|
||||
}
|
||||
|
||||
// sampleConfig.DebugLib = false
|
||||
// sampleConfig.Log = "" if not set.
|
||||
|
||||
j.C = sampleConfig
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
)
|
||||
|
||||
// SigHandler срабатывает если происходит завершение программы, инициированное либо init-ом, либо пользователем.
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
)
|
||||
|
||||
// Squash банит указанный jid в указанной комнате.
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/xml"
|
||||
"os"
|
||||
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
"gopkg.in/tomb.v2"
|
||||
)
|
||||
|
||||
@@ -14,9 +14,13 @@ type (
|
||||
CSign string `json:"csign,omitempty"`
|
||||
Loglevel string `json:"loglevel,omitempty"`
|
||||
Log string `json:"log,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
ExeName string `json:"exe_name,omitempty"`
|
||||
Jabber struct {
|
||||
Debug struct {
|
||||
Lib bool `json:"lib,omitempty"`
|
||||
Ping bool `json:"ping,omitempty"`
|
||||
} `json:"debug"`
|
||||
Version string `json:"version,omitempty"`
|
||||
ExeName string `json:"exe_name,omitempty"`
|
||||
Jabber struct {
|
||||
Server string `json:"server,omitempty"`
|
||||
Nick string `json:"nick,omitempty"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
@@ -202,6 +206,46 @@ type (
|
||||
} `xml:"not-acceptable"`
|
||||
}
|
||||
|
||||
// IqErrorCancelServiceNotAvailable обычно возвращается сервером в ответ на iq-запрос к несуществующей сущности.
|
||||
// Если мы такое получаем от клиента, значит мы запросили что-то, что клиент явно не объявил как существущее в
|
||||
// списке своих capability. https://xmpp.org/extensions/xep-0030.html#errors
|
||||
IqErrorCancelServiceNotAvailable struct {
|
||||
XMLName xml.Name `xml:"error"`
|
||||
Text string `xml:",chardata"`
|
||||
Type string `xml:"type,attr"`
|
||||
ServiceUnavailable struct {
|
||||
Text string `xml:",chardata"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
}
|
||||
}
|
||||
|
||||
/* <iq from='slackware-current@conference.jabber.ru/Batman46(new)' to='buny@jabber.ru/Лунная призма' type='error' id='94e55122-6
|
||||
c15-4e88-a0df-ae9f02e0b550'>
|
||||
<query xmlns='jabber:iq:version'/>
|
||||
<error code='404' type='cancel'>
|
||||
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||||
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Адресата нет в конференции</text>
|
||||
</error>
|
||||
</iq>
|
||||
*/
|
||||
|
||||
// IqErrorCancelItemNotFound не знаю, насколько корректно так отвечать на запрос версии ПО, но такое иногда
|
||||
// встречаетсяю. Придётся поддержать.
|
||||
IqErrorCancelItemNotFound struct {
|
||||
XMLName xml.Name `xml:"error"`
|
||||
Chardata string `xml:",chardata"`
|
||||
Code string `xml:"code,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
ItemNotFound struct {
|
||||
Text string `xml:",chardata"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
} `xml:"item-not-found"`
|
||||
Text struct {
|
||||
Text string `xml:",chardata"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
} `xml:"text"`
|
||||
}
|
||||
|
||||
// IqResultSoftwareVersion прототип структурки для разбора IQ ответов на запрос о названии и версии клиентского ПО.
|
||||
IqResultSoftwareVersion struct {
|
||||
XMLName xml.Name `xml:"query"`
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/eleksir/go-xmpp"
|
||||
"github.com/xmppo/go-xmpp"
|
||||
)
|
||||
|
||||
// RandomPhrase выдаёт одну рандомную фразу из даденного списка фраз.
|
||||
@@ -125,7 +125,7 @@ func (j *Jabber) RotateStatus(room string) error {
|
||||
func (j *Jabber) JoinMuc(room string) error {
|
||||
log.Debugf("Sending disco#info from %s to %s", j.Talk.JID(), room)
|
||||
|
||||
if _, err := j.Talk.DiscoverInfo(j.Talk.JID(), room); err != nil {
|
||||
if _, err := j.Talk.DiscoverInfo(j.Talk.JID()); err != nil {
|
||||
return fmt.Errorf("unable to send disco#info to MUC %s: %w", room, err)
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ func (j *Jabber) JoinMuc(room string) error {
|
||||
var v xmpp.Presence
|
||||
|
||||
_ = json.Unmarshal([]byte(name), &v)
|
||||
log.Infof("Fake presence forged for %s just for on-enter check", name)
|
||||
log.Infof("Fake presence forged for %s just for on-enter check", v.JID)
|
||||
// Оно там внутри всё само обработает, если вдруг возникнет wire error, то зарекконетится.
|
||||
_ = j.BunyPresense(v)
|
||||
}
|
||||
@@ -251,7 +251,7 @@ func (j *Jabber) EstablishConnection() error {
|
||||
|
||||
log.Debugf("Sending disco#info to %s", j.C.Jabber.Server)
|
||||
|
||||
_, err = j.Talk.DiscoverInfo(j.Talk.JID(), j.C.Jabber.Server)
|
||||
_, err = j.Talk.DiscoverInfo(j.Talk.JID())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to send disco#info to jabber server: %w", err)
|
||||
@@ -315,7 +315,9 @@ func (j *Jabber) ProbeServerLiveness() error { //nolint:gocognit
|
||||
|
||||
// По-умолчанию, мы отправляем c2s пинг.
|
||||
default:
|
||||
log.Debugf("Sending c2s ping from %s to %s", j.Talk.JID(), j.C.Jabber.Server)
|
||||
if j.C.Debug.Ping {
|
||||
log.Debugf("Sending c2s ping from %s to %s", j.Talk.JID(), j.C.Jabber.Server)
|
||||
}
|
||||
|
||||
if err := j.Talk.PingC2S(j.Talk.JID(), j.C.Jabber.Server); err != nil {
|
||||
return err
|
||||
@@ -324,7 +326,9 @@ func (j *Jabber) ProbeServerLiveness() error { //nolint:gocognit
|
||||
j.ServerPingTimestampTx = time.Now().Unix()
|
||||
}
|
||||
} else { // Первая пуля пока не вылетела, отправляем.
|
||||
log.Debugf("Sending first c2s ping from %s to %s", j.Talk.JID(), j.C.Jabber.Server)
|
||||
if j.C.Debug.Ping {
|
||||
log.Debugf("Sending first c2s ping from %s to %s", j.Talk.JID(), j.C.Jabber.Server)
|
||||
}
|
||||
|
||||
if err := j.Talk.PingC2S(j.Talk.JID(), j.C.Jabber.Server); err != nil {
|
||||
return err
|
||||
@@ -335,14 +339,18 @@ func (j *Jabber) ProbeServerLiveness() error { //nolint:gocognit
|
||||
|
||||
// Сервер не анонсировал, что умеет в c2s пинги.
|
||||
default:
|
||||
log.Debug("Sending keepalive whitespace ping")
|
||||
if j.C.Debug.Ping {
|
||||
log.Debug("Sending keepalive whitespace ping")
|
||||
}
|
||||
|
||||
if _, err := j.Talk.SendKeepAlive(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else { // Сервер не ответил на disco#info.
|
||||
log.Debug("Sending keepalive whitespace ping")
|
||||
if j.C.Debug.Ping {
|
||||
log.Debug("Sending keepalive whitespace ping")
|
||||
}
|
||||
|
||||
if _, err := j.Talk.SendKeepAlive(); err != nil {
|
||||
return err
|
||||
@@ -408,7 +416,9 @@ func (j *Jabber) ProbeMUCLiveness() { //nolint:gocognit
|
||||
sleepTime := time.Duration(rand.Int63n(1000*j.C.Jabber.PingSplayDelay)) * time.Millisecond
|
||||
time.Sleep(sleepTime)
|
||||
|
||||
log.Debugf("Sending MUC ping from %s to %s", j.Talk.JID(), room)
|
||||
if j.C.Debug.Ping {
|
||||
log.Debugf("Sending MUC ping from %s to %s", j.Talk.JID(), room)
|
||||
}
|
||||
|
||||
if e := j.Talk.PingS2S(j.Talk.JID(), room); e != nil {
|
||||
err = fmt.Errorf("unable to ping MUC %s: %w", room, e)
|
||||
|
||||
Reference in New Issue
Block a user