2016-08-14 19:48:51 +00:00
|
|
|
package bxmpp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/42wim/matterbridge/bridge/config"
|
|
|
|
log "github.com/Sirupsen/logrus"
|
|
|
|
"github.com/mattn/go-xmpp"
|
2017-01-13 23:35:45 +00:00
|
|
|
"crypto/tls"
|
2016-08-14 19:48:51 +00:00
|
|
|
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Bxmpp struct {
|
2016-11-13 22:06:37 +00:00
|
|
|
xc *xmpp.Client
|
|
|
|
xmppMap map[string]string
|
|
|
|
Config *config.Protocol
|
|
|
|
Remote chan config.Message
|
|
|
|
Account string
|
2016-08-14 19:48:51 +00:00
|
|
|
}
|
|
|
|
|
2016-09-18 17:21:15 +00:00
|
|
|
var flog *log.Entry
|
|
|
|
var protocol = "xmpp"
|
2016-08-14 19:48:51 +00:00
|
|
|
|
|
|
|
func init() {
|
2016-09-18 17:21:15 +00:00
|
|
|
flog = log.WithFields(log.Fields{"module": protocol})
|
2016-08-14 19:48:51 +00:00
|
|
|
}
|
|
|
|
|
2016-11-13 22:06:37 +00:00
|
|
|
func New(cfg config.Protocol, account string, c chan config.Message) *Bxmpp {
|
2016-08-14 19:48:51 +00:00
|
|
|
b := &Bxmpp{}
|
|
|
|
b.xmppMap = make(map[string]string)
|
2016-11-03 23:05:15 +00:00
|
|
|
b.Config = &cfg
|
2016-11-13 22:06:37 +00:00
|
|
|
b.Account = account
|
2016-08-14 19:48:51 +00:00
|
|
|
b.Remote = c
|
2016-08-15 21:16:07 +00:00
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bxmpp) Connect() error {
|
|
|
|
var err error
|
2016-09-19 22:03:01 +00:00
|
|
|
flog.Infof("Connecting %s", b.Config.Server)
|
2016-08-14 19:48:51 +00:00
|
|
|
b.xc, err = b.createXMPP()
|
|
|
|
if err != nil {
|
2016-09-18 17:21:15 +00:00
|
|
|
flog.Debugf("%#v", err)
|
2016-08-15 21:16:07 +00:00
|
|
|
return err
|
2016-08-14 19:48:51 +00:00
|
|
|
}
|
2016-09-18 17:21:15 +00:00
|
|
|
flog.Info("Connection succeeded")
|
2016-08-14 19:48:51 +00:00
|
|
|
go b.handleXmpp()
|
2016-08-15 21:16:07 +00:00
|
|
|
return nil
|
2016-08-14 19:48:51 +00:00
|
|
|
}
|
|
|
|
|
2016-09-18 17:21:15 +00:00
|
|
|
func (b *Bxmpp) JoinChannel(channel string) error {
|
|
|
|
b.xc.JoinMUCNoHistory(channel+"@"+b.Config.Muc, b.Config.Nick)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-08-14 19:48:51 +00:00
|
|
|
func (b *Bxmpp) Send(msg config.Message) error {
|
2016-09-19 22:03:01 +00:00
|
|
|
flog.Debugf("Receiving %#v", msg)
|
2016-11-13 22:06:37 +00:00
|
|
|
b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: msg.Username + msg.Text})
|
2016-08-14 19:48:51 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bxmpp) createXMPP() (*xmpp.Client, error) {
|
2017-01-13 23:35:45 +00:00
|
|
|
tc := new(tls.Config)
|
|
|
|
tc.InsecureSkipVerify = b.Config.SkipTLSVerify
|
2016-08-14 19:48:51 +00:00
|
|
|
options := xmpp.Options{
|
2016-09-18 17:21:15 +00:00
|
|
|
Host: b.Config.Server,
|
|
|
|
User: b.Config.Jid,
|
|
|
|
Password: b.Config.Password,
|
2016-08-14 19:48:51 +00:00
|
|
|
NoTLS: true,
|
|
|
|
StartTLS: true,
|
2017-01-13 23:35:45 +00:00
|
|
|
TLSConfig: tc,
|
|
|
|
|
2016-08-14 19:48:51 +00:00
|
|
|
//StartTLS: false,
|
|
|
|
Debug: true,
|
|
|
|
Session: true,
|
|
|
|
Status: "",
|
|
|
|
StatusMessage: "",
|
|
|
|
Resource: "",
|
|
|
|
InsecureAllowUnencryptedAuth: false,
|
|
|
|
//InsecureAllowUnencryptedAuth: true,
|
|
|
|
}
|
|
|
|
var err error
|
|
|
|
b.xc, err = options.NewClient()
|
|
|
|
return b.xc, err
|
|
|
|
}
|
|
|
|
|
2016-11-26 14:02:39 +00:00
|
|
|
func (b *Bxmpp) xmppKeepAlive() chan bool {
|
|
|
|
done := make(chan bool)
|
2016-08-14 19:48:51 +00:00
|
|
|
go func() {
|
|
|
|
ticker := time.NewTicker(90 * time.Second)
|
2016-11-26 14:02:39 +00:00
|
|
|
defer ticker.Stop()
|
2016-08-14 19:48:51 +00:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-ticker.C:
|
2016-11-26 14:02:39 +00:00
|
|
|
b.xc.PingC2S("", "")
|
|
|
|
case <-done:
|
|
|
|
return
|
2016-08-14 19:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
2016-11-26 14:02:39 +00:00
|
|
|
return done
|
2016-08-14 19:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Bxmpp) handleXmpp() error {
|
2016-11-26 14:02:39 +00:00
|
|
|
done := b.xmppKeepAlive()
|
|
|
|
defer close(done)
|
2016-11-26 14:06:05 +00:00
|
|
|
nodelay := time.Time{}
|
2016-08-14 19:48:51 +00:00
|
|
|
for {
|
|
|
|
m, err := b.xc.Recv()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
switch v := m.(type) {
|
|
|
|
case xmpp.Chat:
|
|
|
|
var channel, nick string
|
|
|
|
if v.Type == "groupchat" {
|
|
|
|
s := strings.Split(v.Remote, "@")
|
|
|
|
if len(s) == 2 {
|
|
|
|
channel = s[0]
|
|
|
|
}
|
|
|
|
s = strings.Split(s[1], "/")
|
|
|
|
if len(s) == 2 {
|
|
|
|
nick = s[1]
|
|
|
|
}
|
2016-11-26 14:06:05 +00:00
|
|
|
if nick != b.Config.Nick && v.Stamp == nodelay && v.Text != "" {
|
2016-11-13 22:06:37 +00:00
|
|
|
flog.Debugf("Sending message from %s on %s to gateway", nick, b.Account)
|
|
|
|
b.Remote <- config.Message{Username: nick, Text: v.Text, Channel: channel, Account: b.Account}
|
2016-08-14 19:48:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
case xmpp.Presence:
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|