sum7
/
yaja
Archived
1
0
Fork 0

rename and split xmpp xml structs packages

This commit is contained in:
Martin/Geno 2018-02-14 18:49:26 +01:00
parent aacc788efe
commit e2a59cb3ba
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
70 changed files with 660 additions and 546 deletions

View File

@ -7,8 +7,9 @@
[![chat on our conference room](https://camo.githubusercontent.com/a839cc0a3d4dac7ec82237381b165dd144365b6d/68747470733a2f2f74696e7975726c2e636f6d2f6a6f696e7468656d7563)](https://conversations.im/j/yaja@conference.chat.sum7.eu) [![chat on our conference room](https://camo.githubusercontent.com/a839cc0a3d4dac7ec82237381b165dd144365b6d/68747470733a2f2f74696e7975726c2e636f6d2f6a6f696e7468656d7563)](https://conversations.im/j/yaja@conference.chat.sum7.eu)
## Features ## Features
- Messages XML Library (first version - PR are welcome) - XMPP Library (first version - PR are welcome)
- Full RFC 6120 (XMPP - Core) - RFC 6120 (XMPP - Core)
- XEP 0030: Service Discovery
- XEP-0199: XMPP Ping - XEP-0199: XMPP Ping
- Client Library (WIP) - Client Library (WIP)
- Stream: TLS Required - Stream: TLS Required
@ -29,11 +30,12 @@
## Library ## Library
### Messages ### XMPP
all implementation of all comman (RFCs and XEPs) xml element all implementation of all comman (RFCs and XEPs) xml element
**Version** **Version**
- RFC 6120 (XMPP - Core) - RFC 6120 (XMPP - Core)
- XEP 0030: Service Discovery
- XEP-0199: XMPP Ping - XEP-0199: XMPP Ping
### Client ### Client

View File

@ -9,7 +9,7 @@ import (
"math/big" "math/big"
"strings" "strings"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
) )
func (client *Client) auth(password string) error { func (client *Client) auth(password string) error {
@ -19,8 +19,8 @@ func (client *Client) auth(password string) error {
} }
//auth: //auth:
mechanism := "" mechanism := ""
challenge := &messages.SASLChallenge{} challenge := &xmpp.SASLChallenge{}
response := &messages.SASLResponse{} response := &xmpp.SASLResponse{}
for _, m := range f.Mechanisms.Mechanism { for _, m := range f.Mechanisms.Mechanism {
client.Logging.Debugf("try auth with '%s'", m) client.Logging.Debugf("try auth with '%s'", m)
if m == "SCRAM-SHA-1" { if m == "SCRAM-SHA-1" {
@ -34,7 +34,7 @@ func (client *Client) auth(password string) error {
if m == "DIGEST-MD5" { if m == "DIGEST-MD5" {
mechanism = m mechanism = m
// Digest-MD5 authentication // Digest-MD5 authentication
client.Send(&messages.SASLAuth{ client.Send(&xmpp.SASLAuth{
Mechanism: m, Mechanism: m,
}) })
if err := client.ReadDecode(challenge); err != nil { if err := client.ReadDecode(challenge); err != nil {
@ -61,8 +61,8 @@ func (client *Client) auth(password string) error {
cnonceStr := cnonce() cnonceStr := cnonce()
digestURI := "xmpp/" + client.JID.Domain digestURI := "xmpp/" + client.JID.Domain
nonceCount := fmt.Sprintf("%08x", 1) nonceCount := fmt.Sprintf("%08x", 1)
digest := saslDigestResponse(client.JID.Local, realm, password, nonce, cnonceStr, "AUTHENTICATE", digestURI, nonceCount) digest := saslDigestResponse(client.JID.Node, realm, password, nonce, cnonceStr, "AUTHENTICATE", digestURI, nonceCount)
message := "username=\"" + client.JID.Local + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr + message := "username=\"" + client.JID.Node + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr +
"\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestURI + "\", response=" + digest + ", charset=" + charset "\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestURI + "\", response=" + digest + ", charset=" + charset
response.Body = base64.StdEncoding.EncodeToString([]byte(message)) response.Body = base64.StdEncoding.EncodeToString([]byte(message))
@ -72,10 +72,10 @@ func (client *Client) auth(password string) error {
if m == "PLAIN" { if m == "PLAIN" {
mechanism = m mechanism = m
// Plain authentication: send base64-encoded \x00 user \x00 password. // Plain authentication: send base64-encoded \x00 user \x00 password.
raw := "\x00" + client.JID.Local + "\x00" + password raw := "\x00" + client.JID.Node + "\x00" + password
enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw))) enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
base64.StdEncoding.Encode(enc, []byte(raw)) base64.StdEncoding.Encode(enc, []byte(raw))
client.Send(&messages.SASLAuth{ client.Send(&xmpp.SASLAuth{
Mechanism: "PLAIN", Mechanism: "PLAIN",
Body: string(enc), Body: string(enc),
}) })
@ -92,14 +92,14 @@ func (client *Client) auth(password string) error {
if err != nil { if err != nil {
return err return err
} }
fail := messages.SASLFailure{} fail := xmpp.SASLFailure{}
if err := client.Decode(&fail, element); err == nil { if err := client.Decode(&fail, element); err == nil {
if txt := fail.Text; txt != nil { if txt := fail.Text; txt != nil {
return errors.New(messages.XMLChildrenString(fail) + " : " + txt.Body) return errors.New(xmpp.XMLChildrenString(fail) + " : " + txt.Body)
} }
return errors.New(messages.XMLChildrenString(fail)) return errors.New(xmpp.XMLChildrenString(fail))
} }
if err := client.Decode(&messages.SASLSuccess{}, element); err != nil { if err := client.Decode(&xmpp.SASLSuccess{}, element); err != nil {
return errors.New("auth failed - with unexpected answer") return errors.New("auth failed - with unexpected answer")
} }
return nil return nil

View File

@ -10,7 +10,8 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
// Client holds XMPP connection opitons // Client holds XMPP connection opitons
@ -23,17 +24,17 @@ type Client struct {
Logging *log.Logger Logging *log.Logger
JID *messages.JID JID *xmppbase.JID
reply map[string]chan *messages.IQClient reply map[string]chan *xmpp.IQClient
skipError bool skipError bool
iq chan *messages.IQClient iq chan *xmpp.IQClient
presence chan *messages.PresenceClient presence chan *xmpp.PresenceClient
mesage chan *messages.MessageClient mesage chan *xmpp.MessageClient
} }
func NewClient(jid *messages.JID, password string) (*Client, error) { func NewClient(jid *xmppbase.JID, password string) (*Client, error) {
client := &Client{ client := &Client{
Protocol: "tcp", Protocol: "tcp",
JID: jid, JID: jid,

1
client/client_test.go Normal file
View File

@ -0,0 +1 @@
package client

View File

@ -3,7 +3,7 @@ package client
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
) )
func (client *Client) Read() (*xml.StartElement, error) { func (client *Client) Read() (*xml.StartElement, error) {
@ -15,7 +15,7 @@ func (client *Client) Read() (*xml.StartElement, error) {
switch nextToken.(type) { switch nextToken.(type) {
case xml.StartElement: case xml.StartElement:
element := nextToken.(xml.StartElement) element := nextToken.(xml.StartElement)
client.Logging.Debug("recv xml: ", messages.XMLStartElementToString(&element)) client.Logging.Debug("recv xml: ", xmpp.XMLStartElementToString(&element))
return &element, nil return &element, nil
} }
} }
@ -23,9 +23,9 @@ func (client *Client) Read() (*xml.StartElement, error) {
func (client *Client) Decode(p interface{}, element *xml.StartElement) error { func (client *Client) Decode(p interface{}, element *xml.StartElement) error {
err := client.in.DecodeElement(p, element) err := client.in.DecodeElement(p, element)
if err != nil { if err != nil {
client.Logging.Debugf("decode failed xml: %s to: %v", messages.XMLStartElementToString(element), p) client.Logging.Debugf("decode failed xml: %s to: %v", xmpp.XMLStartElementToString(element), p)
} else { } else {
client.Logging.Debugf("decode xml: %s to: %v with children %s", messages.XMLStartElementToString(element), p, messages.XMLChildrenString(p)) client.Logging.Debugf("decode xml: %s to: %v with children %s", xmpp.XMLStartElementToString(element), p, xmpp.XMLChildrenString(p))
} }
return err return err
} }
@ -34,15 +34,15 @@ func (client *Client) ReadDecode(p interface{}) error {
if err != nil { if err != nil {
return err return err
} }
var iq *messages.IQClient var iq *xmpp.IQClient
iq, ok := p.(*messages.IQClient) iq, ok := p.(*xmpp.IQClient)
if !ok { if !ok {
iq = &messages.IQClient{} iq = &xmpp.IQClient{}
} }
err = client.Decode(iq, element) err = client.Decode(iq, element)
if err == nil && iq.Ping != nil { if err == nil && iq.Ping != nil {
client.Logging.Info("ReadElement: auto answer ping") client.Logging.Info("ReadElement: auto answer ping")
iq.Type = messages.IQTypeResult iq.Type = xmpp.IQTypeResult
iq.To = iq.From iq.To = iq.From
iq.From = client.JID iq.From = client.JID
client.Send(iq) client.Send(iq)
@ -58,23 +58,23 @@ func (client *Client) encode(p interface{}) error {
if err != nil { if err != nil {
client.Logging.Debugf("encode failed %v", p) client.Logging.Debugf("encode failed %v", p)
} else { } else {
client.Logging.Debugf("encode %v with children %s", p, messages.XMLChildrenString(p)) client.Logging.Debugf("encode %v with children %s", p, xmpp.XMLChildrenString(p))
} }
return err return err
} }
func (client *Client) Send(p interface{}) error { func (client *Client) Send(p interface{}) error {
msg, ok := p.(*messages.MessageClient) msg, ok := p.(*xmpp.MessageClient)
if ok { if ok {
msg.From = client.JID msg.From = client.JID
return client.encode(msg) return client.encode(msg)
} }
iq, ok := p.(*messages.IQClient) iq, ok := p.(*xmpp.IQClient)
if ok { if ok {
iq.From = client.JID iq.From = client.JID
return client.encode(iq) return client.encode(iq)
} }
pc, ok := p.(*messages.PresenceClient) pc, ok := p.(*xmpp.PresenceClient)
if ok { if ok {
pc.From = client.JID pc.From = client.JID
return client.encode(pc) return client.encode(pc)

View File

@ -7,8 +7,9 @@ import (
"fmt" "fmt"
"net" "net"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
func (client *Client) setConnection(conn net.Conn) { func (client *Client) setConnection(conn net.Conn) {
@ -17,12 +18,12 @@ func (client *Client) setConnection(conn net.Conn) {
client.out = xml.NewEncoder(client.conn) client.out = xml.NewEncoder(client.conn)
} }
func (client *Client) startStream() (*messages.StreamFeatures, error) { func (client *Client) startStream() (*xmpp.StreamFeatures, error) {
// XMPP-Connection // XMPP-Connection
_, err := fmt.Fprintf(client.conn, "<?xml version='1.0'?>\n"+ _, err := fmt.Fprintf(client.conn, "<?xml version='1.0'?>\n"+
"<stream:stream to='%s' xmlns='%s'\n"+ "<stream:stream to='%s' xmlns='%s'\n"+
" xmlns:stream='%s' version='1.0'>\n", " xmlns:stream='%s' version='1.0'>\n",
model.XMLEscape(client.JID.Domain), messages.NSClient, messages.NSStream) model.XMLEscape(client.JID.Domain), xmpp.NSClient, xmpp.NSStream)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -30,10 +31,10 @@ func (client *Client) startStream() (*messages.StreamFeatures, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" { if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
return nil, errors.New("is not stream") return nil, errors.New("is not stream")
} }
f := &messages.StreamFeatures{} f := &xmpp.StreamFeatures{}
if err := client.ReadDecode(f); err != nil { if err := client.ReadDecode(f); err != nil {
return nil, err return nil, err
} }
@ -63,11 +64,11 @@ func (client *Client) connect(password string) error {
if _, err := client.startStream(); err != nil { if _, err := client.startStream(); err != nil {
return err return err
} }
if err := client.Send(&messages.TLSStartTLS{}); err != nil { if err := client.Send(&xmpp.TLSStartTLS{}); err != nil {
return err return err
} }
var p messages.TLSProceed var p xmpp.TLSProceed
if err := client.ReadDecode(&p); err != nil { if err := client.ReadDecode(&p); err != nil {
return err return err
} }
@ -97,29 +98,29 @@ func (client *Client) connect(password string) error {
if client.JID.Resource != "" { if client.JID.Resource != "" {
bind.Resource = client.JID.Resource bind.Resource = client.JID.Resource
} }
if err := client.Send(&messages.IQClient{ if err := client.Send(&xmpp.IQClient{
Type: messages.IQTypeSet, Type: xmpp.IQTypeSet,
To: messages.NewJID(client.JID.Domain), To: xmppbase.NewJID(client.JID.Domain),
Bind: bind, Bind: bind,
}); err != nil { }); err != nil {
return err return err
} }
var iq messages.IQClient var iq xmpp.IQClient
if err := client.ReadDecode(&iq); err != nil { if err := client.ReadDecode(&iq); err != nil {
return err return err
} }
if iq.Error != nil { if iq.Error != nil {
return errors.New(fmt.Sprintf("recv error on iq>bind: %s[%s]: %s -> %s -> %s", iq.Error.Code, iq.Error.Type, iq.Error.Text, messages.XMLChildrenString(iq.Error.StanzaErrorGroup), messages.XMLChildrenString(iq.Error.Other))) return errors.New(fmt.Sprintf("recv error on iq>bind: %s[%s]: %s -> %s -> %s", iq.Error.Code, iq.Error.Type, iq.Error.Text, xmpp.XMLChildrenString(iq.Error.StanzaErrorGroup), xmpp.XMLChildrenString(iq.Error.Other)))
} else if iq.Bind == nil { } else if iq.Bind == nil {
return errors.New("iq>bind is nil :" + messages.XMLChildrenString(iq.Other)) return errors.New("iq>bind is nil :" + xmpp.XMLChildrenString(iq.Other))
} }
bind = iq.Bind bind = iq.Bind
} }
if bind == nil { if bind == nil {
return errors.New("bind is nil") return errors.New("bind is nil")
} else if bind.JID != nil { } else if bind.JID != nil {
client.JID.Local = bind.JID.Local client.JID.Node = bind.JID.Node
client.JID.Domain = bind.JID.Domain client.JID.Domain = bind.JID.Domain
client.JID.Resource = bind.JID.Resource client.JID.Resource = bind.JID.Resource
client.Logging.Infof("set jid by server bind '%s'", bind.JID.Full()) client.Logging.Infof("set jid by server bind '%s'", bind.JID.Full())
@ -127,8 +128,8 @@ func (client *Client) connect(password string) error {
client.JID.Resource = bind.Resource client.JID.Resource = bind.Resource
client.Logging.Infof("set resource by server bind '%s'", bind.Resource) client.Logging.Infof("set resource by server bind '%s'", bind.Resource)
} else { } else {
return errors.New("bind>jid is nil" + messages.XMLChildrenString(bind)) return errors.New("bind>jid is nil" + xmpp.XMLChildrenString(bind))
} }
// set status // set status
return client.Send(&messages.PresenceClient{Show: messages.PresenceShowXA, Status: "online"}) return client.Send(&xmpp.PresenceClient{Show: xmpp.PresenceShowXA, Status: "online"})
} }

View File

@ -3,16 +3,16 @@ package client
import ( import (
"fmt" "fmt"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
) )
var DefaultChannelSize = 30 var DefaultChannelSize = 30
func (client *Client) Start() error { func (client *Client) Start() error {
client.iq = make(chan *messages.IQClient, DefaultChannelSize) client.iq = make(chan *xmpp.IQClient, DefaultChannelSize)
client.presence = make(chan *messages.PresenceClient, DefaultChannelSize) client.presence = make(chan *xmpp.PresenceClient, DefaultChannelSize)
client.mesage = make(chan *messages.MessageClient, DefaultChannelSize) client.mesage = make(chan *xmpp.MessageClient, DefaultChannelSize)
client.reply = make(map[string]chan *messages.IQClient) client.reply = make(map[string]chan *xmpp.IQClient)
for { for {
@ -21,18 +21,18 @@ func (client *Client) Start() error {
return err return err
} }
errMSG := &messages.StreamError{} errMSG := &xmpp.StreamError{}
err = client.Decode(errMSG, element) err = client.Decode(errMSG, element)
if err == nil { if err == nil {
return fmt.Errorf("recv stream error: %s: %s -> %s", errMSG.Text, messages.XMLChildrenString(errMSG.StreamErrorGroup), messages.XMLChildrenString(errMSG.Other)) return fmt.Errorf("recv stream error: %s: %s -> %s", errMSG.Text, xmpp.XMLChildrenString(errMSG.StreamErrorGroup), xmpp.XMLChildrenString(errMSG.Other))
} }
iq := &messages.IQClient{} iq := &xmpp.IQClient{}
err = client.Decode(iq, element) err = client.Decode(iq, element)
if err == nil { if err == nil {
if iq.Ping != nil { if iq.Ping != nil {
client.Logging.Debug("answer ping") client.Logging.Debug("answer ping")
iq.Type = messages.IQTypeResult iq.Type = xmpp.IQTypeResult
iq.To = iq.From iq.To = iq.From
iq.From = client.JID iq.From = client.JID
client.Send(iq) client.Send(iq)
@ -50,7 +50,7 @@ func (client *Client) Start() error {
continue continue
} }
pres := &messages.PresenceClient{} pres := &xmpp.PresenceClient{}
err = client.Decode(pres, element) err = client.Decode(pres, element)
if err == nil { if err == nil {
if client.skipError && pres.Error != nil { if client.skipError && pres.Error != nil {
@ -60,7 +60,7 @@ func (client *Client) Start() error {
continue continue
} }
msg := &messages.MessageClient{} msg := &xmpp.MessageClient{}
err = client.Decode(msg, element) err = client.Decode(msg, element)
if err == nil { if err == nil {
if client.skipError && msg.Error != nil { if client.skipError && msg.Error != nil {
@ -73,25 +73,25 @@ func (client *Client) Start() error {
} }
} }
func (client *Client) SendRecv(iq *messages.IQClient) *messages.IQClient { func (client *Client) SendRecv(iq *xmpp.IQClient) *xmpp.IQClient {
if iq.ID == "" { if iq.ID == "" {
iq.ID = messages.CreateCookieString() iq.ID = xmpp.CreateCookieString()
} }
ch := make(chan *messages.IQClient, 1) ch := make(chan *xmpp.IQClient, 1)
client.reply[iq.ID] = ch client.reply[iq.ID] = ch
client.Send(iq) client.Send(iq)
defer close(ch) defer close(ch)
return <-ch return <-ch
} }
func (client *Client) RecvIQ() *messages.IQClient { func (client *Client) RecvIQ() *xmpp.IQClient {
return <-client.iq return <-client.iq
} }
func (client *Client) RecvPresence() *messages.PresenceClient { func (client *Client) RecvPresence() *xmpp.PresenceClient {
return <-client.presence return <-client.presence
} }
func (client *Client) RecvMessage() *messages.MessageClient { func (client *Client) RecvMessage() *xmpp.MessageClient {
return <-client.mesage return <-client.mesage
} }

View File

@ -11,7 +11,7 @@ import (
"dev.sum7.eu/genofire/golang-lib/worker" "dev.sum7.eu/genofire/golang-lib/worker"
"dev.sum7.eu/genofire/yaja/client" "dev.sum7.eu/genofire/yaja/client"
"dev.sum7.eu/genofire/yaja/daemon/tester" "dev.sum7.eu/genofire/yaja/daemon/tester"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -56,7 +56,7 @@ var TesterCMD = &cobra.Command{
defer mainClient.Close() defer mainClient.Close()
for _, admin := range configTester.Admins { for _, admin := range configTester.Admins {
mainClient.Send(&messages.MessageClient{ mainClient.Send(&xmpp.MessageClient{
To: admin, To: admin,
Type: "chat", Type: "chat",
Body: "yaja tester starts", Body: "yaja tester starts",

View File

@ -1,9 +1,9 @@
package tester package tester
import "dev.sum7.eu/genofire/yaja/messages" import "dev.sum7.eu/genofire/yaja/xmpp/base"
type Account struct { type Account struct {
JID *messages.JID `json:"jid"` JID *xmppbase.JID `json:"jid"`
Password string `json:"password"` Password string `json:"password"`
Admins map[string]interface{} `json:"admins"` Admins map[string]interface{} `json:"admins"`
} }

View File

@ -6,7 +6,8 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
func (t *Tester) StartBot(status *Status) { func (t *Tester) StartBot(status *Status) {
@ -24,60 +25,60 @@ func (t *Tester) StartBot(status *Status) {
return return
} }
errMSG := &messages.StreamError{} errMSG := &xmpp.StreamError{}
err = status.client.Decode(errMSG, element) err = status.client.Decode(errMSG, element)
if err == nil { if err == nil {
status.Disconnect(fmt.Sprintf("recv stream error: %s: %s -> %s", errMSG.Text, messages.XMLChildrenString(errMSG.StreamErrorGroup), messages.XMLChildrenString(errMSG.Other))) status.Disconnect(fmt.Sprintf("recv stream error: %s: %s -> %s", errMSG.Text, xmpp.XMLChildrenString(errMSG.StreamErrorGroup), xmpp.XMLChildrenString(errMSG.Other)))
return return
} }
iq := &messages.IQClient{} iq := &xmpp.IQClient{}
err = status.client.Decode(iq, element) err = status.client.Decode(iq, element)
if err == nil { if err == nil {
if iq.Ping != nil { if iq.Ping != nil {
logCTX.Debug("answer ping") logCTX.Debug("answer ping")
iq.Type = messages.IQTypeResult iq.Type = xmpp.IQTypeResult
iq.To = iq.From iq.To = iq.From
iq.From = status.client.JID iq.From = status.client.JID
status.client.Send(iq) status.client.Send(iq)
} else { } else {
logCTX.Warnf("recv iq unsupport: %s", messages.XMLChildrenString(iq)) logCTX.Warnf("recv iq unsupport: %s", xmpp.XMLChildrenString(iq))
} }
continue continue
} }
pres := &messages.PresenceClient{} pres := &xmpp.PresenceClient{}
err = status.client.Decode(pres, element) err = status.client.Decode(pres, element)
if err == nil { if err == nil {
sender := pres.From sender := pres.From
logPres := logCTX.WithField("from", sender.Full()) logPres := logCTX.WithField("from", sender.Full())
if pres.Type == messages.PresenceTypeSubscribe { if pres.Type == xmpp.PresenceTypeSubscribe {
logPres.Debugf("recv presence subscribe") logPres.Debugf("recv presence subscribe")
pres.Type = messages.PresenceTypeSubscribed pres.Type = xmpp.PresenceTypeSubscribed
pres.To = sender pres.To = sender
pres.From = nil pres.From = nil
status.client.Send(pres) status.client.Send(pres)
logPres.Debugf("accept new subscribe") logPres.Debugf("accept new subscribe")
pres.Type = messages.PresenceTypeSubscribe pres.Type = xmpp.PresenceTypeSubscribe
pres.ID = "" pres.ID = ""
status.client.Send(pres) status.client.Send(pres)
logPres.Info("request also subscribe") logPres.Info("request also subscribe")
} else if pres.Type == messages.PresenceTypeSubscribed { } else if pres.Type == xmpp.PresenceTypeSubscribed {
logPres.Info("recv presence accepted subscribe") logPres.Info("recv presence accepted subscribe")
} else if pres.Type == messages.PresenceTypeUnsubscribe { } else if pres.Type == xmpp.PresenceTypeUnsubscribe {
logPres.Info("recv presence remove subscribe") logPres.Info("recv presence remove subscribe")
} else if pres.Type == messages.PresenceTypeUnsubscribed { } else if pres.Type == xmpp.PresenceTypeUnsubscribed {
logPres.Info("recv presence removed subscribe") logPres.Info("recv presence removed subscribe")
} else if pres.Type == messages.PresenceTypeUnavailable { } else if pres.Type == xmpp.PresenceTypeUnavailable {
logPres.Debug("recv presence unavailable") logPres.Debug("recv presence unavailable")
} else { } else {
logCTX.Warnf("recv presence unsupported: %s -> %s", pres.Type, messages.XMLChildrenString(pres)) logCTX.Warnf("recv presence unsupported: %s -> %s", pres.Type, xmpp.XMLChildrenString(pres))
} }
continue continue
} }
msg := &messages.MessageClient{} msg := &xmpp.MessageClient{}
err = status.client.Decode(msg, element) err = status.client.Decode(msg, element)
if err != nil { if err != nil {
logCTX.Warnf("unsupport xml recv: %s <-> %v", err, element) logCTX.Warnf("unsupport xml recv: %s <-> %v", err, element)
@ -89,7 +90,7 @@ func (t *Tester) StartBot(status *Status) {
status.Disconnect("recv msg with error not auth") status.Disconnect("recv msg with error not auth")
return return
} }
logCTX.Debugf("recv msg with error %s[%s]: %s -> %s -> %s", msg.Error.Code, msg.Error.Type, msg.Error.Text, messages.XMLChildrenString(msg.Error.StanzaErrorGroup), messages.XMLChildrenString(msg.Error.Other)) logCTX.Debugf("recv msg with error %s[%s]: %s -> %s -> %s", msg.Error.Code, msg.Error.Type, msg.Error.Text, xmpp.XMLChildrenString(msg.Error.StanzaErrorGroup), xmpp.XMLChildrenString(msg.Error.Other))
continue continue
} }
@ -98,12 +99,12 @@ func (t *Tester) StartBot(status *Status) {
switch msgText[0] { switch msgText[0] {
case "ping": case "ping":
status.client.Send(messages.MessageClient{Type: msg.Type, To: msg.From, Body: "pong"}) status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "pong"})
case "admin": case "admin":
if len(msgText) == 2 { if len(msgText) == 2 {
botAdmin(strings.SplitN(msgText[1], " ", 2), logCTX, status, msg.From, botAllowed(t.Admins, status.account.Admins)) botAdmin(strings.SplitN(msgText[1], " ", 2), logCTX, status, msg.From, botAllowed(t.Admins, status.account.Admins))
} else { } else {
status.client.Send(messages.MessageClient{Type: msg.Type, To: msg.From, Body: "list, add JID-BARE, del JID-BARE"}) status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "list, add JID-BARE, del JID-BARE"})
} }
case "disconnect": case "disconnect":
first := true first := true
@ -118,7 +119,7 @@ func (t *Tester) StartBot(status *Status) {
} }
if jid.Bare() == msg.From.Bare() { if jid.Bare() == msg.From.Bare() {
isAdmin = true isAdmin = true
status.client.Send(messages.MessageClient{Type: msg.Type, To: jid, Body: "last message, disconnect requested by " + msg.From.Bare()}) status.client.Send(xmpp.MessageClient{Type: msg.Type, To: jid, Body: "last message, disconnect requested by " + msg.From.Bare()})
} }
} }
@ -126,7 +127,7 @@ func (t *Tester) StartBot(status *Status) {
status.Disconnect(fmt.Sprintf("disconnect by admin '%s'", msg.From.Bare())) status.Disconnect(fmt.Sprintf("disconnect by admin '%s'", msg.From.Bare()))
return return
} }
status.client.Send(messages.MessageClient{Type: msg.Type, To: msg.From, Body: "not allowed, ask " + allAdmins}) status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "not allowed, ask " + allAdmins})
case "checkmsg": case "checkmsg":
if len(msgText) == 2 { if len(msgText) == 2 {
@ -140,15 +141,15 @@ func (t *Tester) StartBot(status *Status) {
} }
} }
} }
func botAllowed(list []*messages.JID, toConvert map[string]interface{}) []*messages.JID { func botAllowed(list []*xmppbase.JID, toConvert map[string]interface{}) []*xmppbase.JID {
alist := list alist := list
for jid := range toConvert { for jid := range toConvert {
alist = append(alist, messages.NewJID(jid)) alist = append(alist, xmppbase.NewJID(jid))
} }
return alist return alist
} }
func botAdmin(cmd []string, log *log.Entry, status *Status, from *messages.JID, allowed []*messages.JID) { func botAdmin(cmd []string, log *log.Entry, status *Status, from *xmppbase.JID, allowed []*xmppbase.JID) {
msg := "" msg := ""
if len(cmd) == 2 { if len(cmd) == 2 {
isAdmin := false isAdmin := false
@ -169,7 +170,7 @@ func botAdmin(cmd []string, log *log.Entry, status *Status, from *messages.JID,
delete(status.account.Admins, cmd[1]) delete(status.account.Admins, cmd[1])
msg = "ack" msg = "ack"
} else { } else {
msg = "unkown command" msg = "unknown command"
} }
} else { } else {
if len(cmd) == 1 && cmd[0] == "list" { if len(cmd) == 1 && cmd[0] == "list" {
@ -181,8 +182,8 @@ func botAdmin(cmd []string, log *log.Entry, status *Status, from *messages.JID,
} }
} }
} else { } else {
msg = "unkown command" msg = "unknown command"
} }
} }
status.client.Send(messages.MessageClient{Type: messages.MessageTypeChat, To: from, Body: msg}) status.client.Send(xmpp.MessageClient{Type: xmpp.MessageTypeChat, To: from, Body: msg})
} }

View File

@ -0,0 +1 @@
package tester

View File

@ -1,9 +1,10 @@
package tester package tester
import ( import (
"dev.sum7.eu/genofire/yaja/messages"
"github.com/FreifunkBremen/yanic/lib/duration" "github.com/FreifunkBremen/yanic/lib/duration"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type Config struct { type Config struct {
@ -15,9 +16,9 @@ type Config struct {
LoggingBots log.Level `toml:"logging_bots"` LoggingBots log.Level `toml:"logging_bots"`
Timeout duration.Duration `toml:"timeout"` Timeout duration.Duration `toml:"timeout"`
Interval duration.Duration `toml:"interval"` Interval duration.Duration `toml:"interval"`
Admins []*messages.JID `toml:"admins"` Admins []*xmppbase.JID `toml:"admins"`
Client struct { Client struct {
JID *messages.JID `toml:"jid"` JID *xmppbase.JID `toml:"jid"`
Password string `toml:"password"` Password string `toml:"password"`
} `toml:"client"` } `toml:"client"`
} }

View File

@ -4,8 +4,9 @@ import (
"fmt" "fmt"
"strings" "strings"
"dev.sum7.eu/genofire/yaja/messages"
"github.com/FreifunkBremen/yanic/lib/jsontime" "github.com/FreifunkBremen/yanic/lib/jsontime"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type Output struct { type Output struct {
@ -53,7 +54,7 @@ func (t *Tester) Output() *Output {
} }
continue continue
} }
toJID := messages.NewJID(to) toJID := xmppbase.NewJID(to)
link := &Link{ link := &Link{
Source: status.JID.Domain, Source: status.JID.Domain,
SourceJID: status.JID.Bare(), SourceJID: status.JID.Bare(),

View File

@ -6,14 +6,15 @@ import (
"time" "time"
"dev.sum7.eu/genofire/yaja/client" "dev.sum7.eu/genofire/yaja/client"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type Status struct { type Status struct {
backupClient *client.Client backupClient *client.Client
client *client.Client client *client.Client
account *Account account *Account
JID *messages.JID `json:"jid"` JID *xmppbase.JID `json:"jid"`
Domain string `json:"domain"` Domain string `json:"domain"`
Login bool `json:"is_online"` Login bool `json:"is_online"`
MessageForConnection map[string]string `json:"-"` MessageForConnection map[string]string `json:"-"`
@ -35,12 +36,12 @@ func NewStatus(backupClient *client.Client, acc *Account) *Status {
} }
func (s *Status) Disconnect(reason string) { func (s *Status) Disconnect(reason string) {
if s.Login { if s.Login {
msg := &messages.MessageClient{ msg := &xmpp.MessageClient{
Type: messages.MessageTypeChat, Type: xmpp.MessageTypeChat,
Body: fmt.Sprintf("you recieve a notify that '%s' disconnect: %s", s.JID.Full(), reason), Body: fmt.Sprintf("you receive a notify that '%s' disconnect: %s", s.JID.Full(), reason),
} }
for jid := range s.account.Admins { for jid := range s.account.Admins {
msg.To = messages.NewJID(jid) msg.To = xmppbase.NewJID(jid)
if err := s.backupClient.Send(msg); err != nil { if err := s.backupClient.Send(msg); err != nil {
s.client.Send(msg) s.client.Send(msg)
} }
@ -58,7 +59,7 @@ func (s *Status) Update(timeout time.Duration) {
} }
c := &client.Client{ c := &client.Client{
JID: messages.NewJID(s.account.JID.Bare()), JID: xmppbase.NewJID(s.account.JID.Bare()),
Protocol: "tcp4", Protocol: "tcp4",
Logging: s.client.Logging, Logging: s.client.Logging,
Timeout: timeout / 2, Timeout: timeout / 2,
@ -71,7 +72,7 @@ func (s *Status) Update(timeout time.Duration) {
s.IPv4 = false s.IPv4 = false
} }
c.JID = messages.NewJID(s.account.JID.Bare()) c.JID = xmppbase.NewJID(s.account.JID.Bare())
c.Protocol = "tcp6" c.Protocol = "tcp6"
if err := c.Connect(s.account.Password); err == nil { if err := c.Connect(s.account.Password); err == nil {

View File

@ -7,7 +7,8 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/client" "dev.sum7.eu/genofire/yaja/client"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type Tester struct { type Tester struct {
@ -18,7 +19,7 @@ type Tester struct {
mux sync.Mutex mux sync.Mutex
LoggingClients *log.Logger `json:"-"` LoggingClients *log.Logger `json:"-"`
LoggingBots log.Level `json:"-"` LoggingBots log.Level `json:"-"`
Admins []*messages.JID `json:"-"` Admins []*xmppbase.JID `json:"-"`
} }
func NewTester() *Tester { func NewTester() *Tester {
@ -88,7 +89,7 @@ func (t *Tester) Connect(acc *Account) {
} }
} }
func (t *Tester) UpdateConnectionStatus(from, to *messages.JID, recvmsg string) { func (t *Tester) UpdateConnectionStatus(from, to *xmppbase.JID, recvmsg string) {
logCTX := log.WithFields(log.Fields{ logCTX := log.WithFields(log.Fields{
"jid": to.Full(), "jid": to.Full(),
"from": from.Full(), "from": from.Full(),
@ -154,12 +155,12 @@ func (t *Tester) CheckStatus() {
logCTXTo.Debug("could not recv msg") logCTXTo.Debug("could not recv msg")
} }
} }
msg = messages.CreateCookieString() msg = xmpp.CreateCookieString()
logCTXTo = logCTXTo.WithField("msg-send", msg) logCTXTo = logCTXTo.WithField("msg-send", msg)
own.client.Send(&messages.MessageClient{ own.client.Send(&xmpp.MessageClient{
Body: "checkmsg " + msg, Body: "checkmsg " + msg,
Type: messages.MessageTypeChat, Type: xmpp.MessageTypeChat,
To: s.JID, To: s.JID,
}) })
own.MessageForConnection[s.JID.Bare()] = msg own.MessageForConnection[s.JID.Bare()] = msg

1
daemon/tester_test.go Normal file
View File

@ -0,0 +1 @@
package daemon

View File

@ -4,9 +4,10 @@ import (
"errors" "errors"
"sync" "sync"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type State struct { type State struct {
@ -15,7 +16,7 @@ type State struct {
} }
func (s *State) AddAccount(a *model.Account) error { func (s *State) AddAccount(a *model.Account) error {
if a.Local == "" { if a.Node == "" {
return errors.New("No localpart exists in account") return errors.New("No localpart exists in account")
} }
if d := a.Domain; d != nil { if d := a.Domain; d != nil {
@ -38,22 +39,22 @@ func (s *State) AddAccount(a *model.Account) error {
if domain.Accounts == nil { if domain.Accounts == nil {
domain.Accounts = make(map[string]*model.Account) domain.Accounts = make(map[string]*model.Account)
} }
_, ok = domain.Accounts[a.Local] _, ok = domain.Accounts[a.Node]
if ok { if ok {
return errors.New("exists already") return errors.New("exists already")
} }
domain.Accounts[a.Local] = a domain.Accounts[a.Node] = a
a.Domain = d a.Domain = d
return nil return nil
} }
return errors.New("no give domain") return errors.New("no give domain")
} }
func (s *State) Authenticate(jid *messages.JID, password string) (bool, error) { func (s *State) Authenticate(jid *xmppbase.JID, password string) (bool, error) {
logger := log.WithField("database", "auth") logger := log.WithField("database", "auth")
if domain, ok := s.Domains[jid.Domain]; ok { if domain, ok := s.Domains[jid.Domain]; ok {
if acc, ok := domain.Accounts[jid.Local]; ok { if acc, ok := domain.Accounts[jid.Node]; ok {
if acc.ValidatePassword(password) { if acc.ValidatePassword(password) {
return true, nil return true, nil
} else { } else {
@ -68,11 +69,11 @@ func (s *State) Authenticate(jid *messages.JID, password string) (bool, error) {
return false, nil return false, nil
} }
func (s *State) GetAccount(jid *messages.JID) *model.Account { func (s *State) GetAccount(jid *xmppbase.JID) *model.Account {
logger := log.WithField("database", "get") logger := log.WithField("database", "get")
if domain, ok := s.Domains[jid.Domain]; ok { if domain, ok := s.Domains[jid.Domain]; ok {
if acc, ok := domain.Accounts[jid.Local]; ok { if acc, ok := domain.Accounts[jid.Node]; ok {
return acc return acc
} else { } else {
logger.Debug("account not found") logger.Debug("account not found")

View File

@ -1,23 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.5 Client Namespace (a part)
type IQClient struct {
XMLName xml.Name `xml:"jabber:client iq"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *JID `xml:"to,attr,omitempty"`
Type IQType `xml:"type,attr"` // required
Error *ErrorClient
Bind *Bind // which XEP ?
Ping *Ping // which XEP ?
PrivateQuery *IQPrivateQuery // which XEP ?
PrivateRegister *IQPrivateRegister // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,25 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.5 Client Namespace (a part)
type MessageClient struct {
XMLName xml.Name `xml:"jabber:client message"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr,omitempty"`
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,29 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.5 Client Namespace (a part)
type PresenceClient struct {
XMLName xml.Name `xml:"jabber:client presence"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr,omitempty"`
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,33 +0,0 @@
package messages
const (
// RFC 6120 - A.1 Stream Namespace
NSStream = "http://etherx.jabber.org/streams"
// RFC 6120 - A.2 Stream Error Namespace
NSStreamError = "urn:ietf:params:xml:ns:xmpp-streams"
// RFC 6120 - A.3 StartTLS Namespace
NSStartTLS = "urn:ietf:params:xml:ns:xmpp-tls"
// RFC 6120 - A.4 SASL Namespace
NSSASL = "urn:ietf:params:xml:ns:xmpp-sasl"
// RFC 6120 - A.5 Client Namespace
NSClient = "jabber:client"
// RFC 6120 - A.6 Server Namespace
NSServer = "jabber:server"
// RFC 6120 - A.7 Resource Binding Namespace
NSBind = "urn:ietf:params:xml:ns:xmpp-bind"
// RFC 6120 - A.8 Stanza Error Binding Namespace
NSStanzaError = "urn:ietf:params:xml:ns:xmpp-stanzas"
NSIQRegister = "jabber:iq:register"
NSFeaturesIQRegister = "http://jabber.org/features/iq-register"
NSDisco = "http://jabber.org/protocol/disco#info"
)

View File

@ -1,19 +0,0 @@
package messages
// which XEP ????
import (
"encoding/xml"
)
type ClientQuery struct {
Item []RosterItem
}
type RosterItem struct {
XMLName xml.Name `xml:"jabber:iq:roster item"`
JID *JID `xml:",attr"`
Name string `xml:",attr"`
Subscription string `xml:",attr"`
Group []string
}

View File

@ -1,23 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.6 Server Namespace (a part)
type IQServer struct {
XMLName xml.Name `xml:"jabber:server iq"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *JID `xml:"to,attr"` // required
Type IQType `xml:"type,attr"` // required
Error *ErrorServer
Bind *Bind // which XEP ?
Ping *Ping // which XEP ?
PrivateQuery *IQPrivateQuery // which XEP ?
PrivateRegister *IQPrivateRegister // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,25 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.6 Server Namespace (a part)
type MessageServer struct {
XMLName xml.Name `xml:"jabber:server message"`
From *JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr"` // required
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,29 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.6 Server Namespace (a part)
type PresenceServer struct {
XMLName xml.Name `xml:"jabber:server presence"`
From *JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr"` // required
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -4,7 +4,7 @@ import (
"errors" "errors"
"sync" "sync"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type Domain struct { type Domain struct {
@ -13,37 +13,37 @@ type Domain struct {
sync.Mutex sync.Mutex
} }
func (d *Domain) GetJID() *messages.JID { func (d *Domain) GetJID() *xmppbase.JID {
return &messages.JID{ return &xmppbase.JID{
Domain: d.FQDN, Domain: d.FQDN,
} }
} }
func (d *Domain) UpdateAccount(a *Account) error { func (d *Domain) UpdateAccount(a *Account) error {
if a.Local == "" { if a.Node == "" {
return errors.New("No localpart exists in account") return errors.New("No localpart exists in account")
} }
d.Lock() d.Lock()
d.Accounts[a.Local] = a d.Accounts[a.Node] = a
d.Unlock() d.Unlock()
a.Domain = d a.Domain = d
return nil return nil
} }
type Account struct { type Account struct {
Local string `json:"-"` Node string `json:"-"`
Domain *Domain `json:"-"` Domain *Domain `json:"-"`
Password string `json:"password"` Password string `json:"password"`
Roster map[string]*Buddy `json:"roster"` Roster map[string]*Buddy `json:"roster"`
Bookmarks map[string]*Bookmark `json:"bookmarks"` Bookmarks map[string]*Bookmark `json:"bookmarks"`
} }
func NewAccount(jid *messages.JID, password string) *Account { func NewAccount(jid *xmppbase.JID, password string) *Account {
if jid == nil { if jid == nil {
return nil return nil
} }
return &Account{ return &Account{
Local: jid.Local, Node: jid.Node,
Domain: &Domain{ Domain: &Domain{
FQDN: jid.Domain, FQDN: jid.Domain,
}, },
@ -51,10 +51,10 @@ func NewAccount(jid *messages.JID, password string) *Account {
} }
} }
func (a *Account) GetJID() *messages.JID { func (a *Account) GetJID() *xmppbase.JID {
return &messages.JID{ return &xmppbase.JID{
Domain: a.Domain.FQDN, Domain: a.Domain.FQDN,
Local: a.Local, Node: a.Node,
} }
} }

View File

@ -3,16 +3,16 @@ package extension
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
) )
type IQExtensions []IQExtension type IQExtensions []IQExtension
type IQExtension interface { type IQExtension interface {
Extension Extension
Get(*messages.IQClient, *utils.Client) bool Get(*xmpp.IQClient, *utils.Client) bool
Set(*messages.IQClient, *utils.Client) bool Set(*xmpp.IQClient, *utils.Client) bool
} }
func (iex IQExtensions) Spaces() (result []string) { func (iex IQExtensions) Spaces() (result []string) {
@ -27,7 +27,7 @@ func (iex IQExtensions) Process(element *xml.StartElement, client *utils.Client)
log := client.Log.WithField("extension", "iq") log := client.Log.WithField("extension", "iq")
// iq encode // iq encode
var msg messages.IQClient var msg xmpp.IQClient
if err := client.In.DecodeElement(&msg, element); err != nil { if err := client.In.DecodeElement(&msg, element); err != nil {
return false return false
} }
@ -38,11 +38,11 @@ func (iex IQExtensions) Process(element *xml.StartElement, client *utils.Client)
count := 0 count := 0
for _, extension := range iex { for _, extension := range iex {
switch msg.Type { switch msg.Type {
case messages.IQTypeGet: case xmpp.IQTypeGet:
if extension.Get(&msg, client) { if extension.Get(&msg, client) {
count++ count++
} }
case messages.IQTypeSet: case xmpp.IQTypeSet:
if extension.Set(&msg, client) { if extension.Set(&msg, client) {
count++ count++
} }
@ -51,7 +51,7 @@ func (iex IQExtensions) Process(element *xml.StartElement, client *utils.Client)
// not extensions found // not extensions found
if count != 1 { if count != 1 {
log.Debugf("%s - %s: %s", msg.XMLName.Space, msg.Type, messages.XMLChildrenString(msg.Other)) log.Debugf("%s - %s: %s", msg.XMLName.Space, msg.Type, xmpp.XMLChildrenString(msg.Other))
} }
return true return true

View File

@ -4,7 +4,7 @@ import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/database" "dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
) )
@ -16,7 +16,7 @@ type IQDisco struct {
func (ex *IQDisco) Spaces() []string { return []string{"http://jabber.org/protocol/disco#items"} } func (ex *IQDisco) Spaces() []string { return []string{"http://jabber.org/protocol/disco#items"} }
func (ex *IQDisco) Get(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQDisco) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "disco-item").WithField("id", msg.ID) log := client.Log.WithField("extension", "disco-item").WithField("id", msg.ID)
// query encode // query encode
@ -58,10 +58,10 @@ func (ex *IQDisco) Get(msg *messages.IQClient, client *utils.Client) bool {
} }
// reply // reply
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID, To: client.JID,
From: messages.NewJID(client.JID.Domain), From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
} }

View File

@ -3,7 +3,7 @@ package extension
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
) )
@ -15,7 +15,7 @@ type IQExtensionDiscovery struct {
func (ex *IQExtensionDiscovery) Spaces() []string { return []string{} } func (ex *IQExtensionDiscovery) Spaces() []string { return []string{} }
func (ex *IQExtensionDiscovery) Get(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQExtensionDiscovery) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "roster").WithField("id", msg.ID) log := client.Log.WithField("extension", "roster").WithField("id", msg.ID)
// query encode // query encode
@ -58,10 +58,10 @@ func (ex *IQExtensionDiscovery) Get(msg *messages.IQClient, client *utils.Client
} }
// replay // replay
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID, To: client.JID,
From: messages.NewJID(client.JID.Domain), From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
} }

View File

@ -3,7 +3,7 @@ package extension
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
) )
@ -16,7 +16,7 @@ type IQLast struct {
func (ex *IQLast) Spaces() []string { return []string{"jabber:iq:last"} } func (ex *IQLast) Spaces() []string { return []string{"jabber:iq:last"} }
func (ex *IQLast) Get(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQLast) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "last").WithField("id", msg.ID) log := client.Log.WithField("extension", "last").WithField("id", msg.ID)
// query encode // query encode
@ -46,10 +46,10 @@ func (ex *IQLast) Get(msg *messages.IQClient, client *utils.Client) bool {
} }
// reply // reply
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID, To: client.JID,
From: messages.NewJID(client.JID.Domain), From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
} }

View File

@ -1,8 +1,9 @@
package extension package extension
import ( import (
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type IQPing struct { type IQPing struct {
@ -11,7 +12,7 @@ type IQPing struct {
func (ex *IQPing) Spaces() []string { return []string{"urn:xmpp:ping"} } func (ex *IQPing) Spaces() []string { return []string{"urn:xmpp:ping"} }
func (ex *IQPing) Get(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQPing) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "ping").WithField("id", msg.ID) log := client.Log.WithField("extension", "ping").WithField("id", msg.ID)
if msg.Ping == nil { if msg.Ping == nil {
@ -19,10 +20,10 @@ func (ex *IQPing) Get(msg *messages.IQClient, client *utils.Client) bool {
} }
// reply // reply
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID, To: client.JID,
From: messages.NewJID(client.JID.Domain), From: xmppbase.NewJID(client.JID.Domain),
ID: msg.ID, ID: msg.ID,
} }

View File

@ -3,7 +3,7 @@ package extension
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
) )
@ -12,7 +12,7 @@ type IQPrivateBookmark struct {
IQExtension IQExtension
} }
func (ex *IQPrivateBookmark) Handle(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQPrivateBookmark) Handle(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "private").WithField("id", msg.ID) log := client.Log.WithField("extension", "private").WithField("id", msg.ID)
// storage encode // storage encode
@ -36,10 +36,10 @@ func (ex *IQPrivateBookmark) Handle(msg *messages.IQClient, client *utils.Client
} }
// reply // reply
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID, To: client.JID,
From: messages.NewJID(client.JID.Domain), From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
} }

View File

@ -3,7 +3,7 @@ package extension
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
) )
@ -12,7 +12,7 @@ type IQPrivateMetacontact struct {
IQExtension IQExtension
} }
func (ex *IQPrivateMetacontact) Handle(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQPrivateMetacontact) Handle(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "private-metacontact").WithField("id", msg.ID) log := client.Log.WithField("extension", "private-metacontact").WithField("id", msg.ID)
// storage encode // storage encode
@ -37,10 +37,10 @@ func (ex *IQPrivateMetacontact) Handle(msg *messages.IQClient, client *utils.Cli
} }
// reply // reply
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID, To: client.JID,
From: messages.NewJID(client.JID.Domain), From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
} }

View File

@ -3,7 +3,7 @@ package extension
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
) )
@ -12,7 +12,7 @@ type IQPrivateRoster struct {
IQExtension IQExtension
} }
func (ex *IQPrivateRoster) Handle(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQPrivateRoster) Handle(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "private").WithField("id", msg.ID) log := client.Log.WithField("extension", "private").WithField("id", msg.ID)
// roster encode // roster encode
@ -41,10 +41,10 @@ func (ex *IQPrivateRoster) Handle(msg *messages.IQClient, client *utils.Client)
} }
// reply // reply
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID, To: client.JID,
From: messages.NewJID(client.JID.Domain), From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
} }

View File

@ -4,7 +4,7 @@ import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/database" "dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
) )
@ -15,7 +15,7 @@ type IQRoster struct {
func (ex *IQRoster) Spaces() []string { return []string{"jabber:iq:roster"} } func (ex *IQRoster) Spaces() []string { return []string{"jabber:iq:roster"} }
func (ex *IQRoster) Get(msg *messages.IQClient, client *utils.Client) bool { func (ex *IQRoster) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "roster").WithField("id", msg.ID) log := client.Log.WithField("extension", "roster").WithField("id", msg.ID)
// query encode // query encode
@ -59,8 +59,8 @@ func (ex *IQRoster) Get(msg *messages.IQClient, client *utils.Client) bool {
} }
// reply // reply
client.Messages <- &messages.IQClient{ client.Messages <- &xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: client.JID.String(), To: client.JID.String(),
From: client.JID.Domain, From: client.JID.Domain,
ID: msg.ID, ID: msg.ID,

View File

@ -3,8 +3,8 @@ package extension
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
) )
type Presence struct { type Presence struct {
@ -19,11 +19,11 @@ func (p *Presence) Process(element *xml.StartElement, client *utils.Client) bool
log := client.Log.WithField("extension", "presence") log := client.Log.WithField("extension", "presence")
// iq encode // iq encode
var msg messages.PresenceClient var msg xmpp.PresenceClient
if err := client.In.DecodeElement(&msg, element); err != nil { if err := client.In.DecodeElement(&msg, element); err != nil {
return false return false
} }
client.Messages <- &messages.PresenceClient{ client.Messages <- &xmpp.PresenceClient{
ID: msg.ID, ID: msg.ID,
} }
log.Debug("send") log.Debug("send")

View File

@ -4,14 +4,15 @@ import (
"crypto/tls" "crypto/tls"
"net" "net"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/database" "dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/extension" "dev.sum7.eu/genofire/yaja/server/extension"
"dev.sum7.eu/genofire/yaja/server/toclient" "dev.sum7.eu/genofire/yaja/server/toclient"
"dev.sum7.eu/genofire/yaja/server/toserver" "dev.sum7.eu/genofire/yaja/server/toserver"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
log "github.com/sirupsen/logrus" "dev.sum7.eu/genofire/yaja/xmpp/base"
"golang.org/x/crypto/acme/autocert"
) )
type Server struct { type Server struct {
@ -109,7 +110,7 @@ func (srv *Server) handleClient(conn net.Conn) {
} }
} }
func (srv *Server) DomainRegisterAllowed(jid *messages.JID) bool { func (srv *Server) DomainRegisterAllowed(jid *xmppbase.JID) bool {
if jid.Domain == "" { if jid.Domain == "" {
return false return false
} }

View File

@ -4,9 +4,11 @@ import (
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
// Start state // Start state
@ -26,13 +28,13 @@ func (state *Start) Process() State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" { if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
state.Client.Log.Warn("is no stream") state.Client.Log.Warn("is no stream")
return state return state
} }
for _, attr := range element.Attr { for _, attr := range element.Attr {
if attr.Name.Local == "to" { if attr.Name.Local == "to" {
state.Client.JID = &messages.JID{Domain: attr.Value} state.Client.JID = &xmppbase.JID{Domain: attr.Value}
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full()) state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
} }
} }
@ -43,14 +45,14 @@ func (state *Start) Process() State {
fmt.Fprintf(state.Client.Conn, `<?xml version='1.0'?> fmt.Fprintf(state.Client.Conn, `<?xml version='1.0'?>
<stream:stream id='%x' version='1.0' xmlns='%s' xmlns:stream='%s'>`, <stream:stream id='%x' version='1.0' xmlns='%s' xmlns:stream='%s'>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream) xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream)
fmt.Fprintf(state.Client.Conn, `<stream:features> fmt.Fprintf(state.Client.Conn, `<stream:features>
<starttls xmlns='%s'> <starttls xmlns='%s'>
<required/> <required/>
</starttls> </starttls>
</stream:features>`, </stream:features>`,
messages.NSStream) xmpp.NSStream)
return state.Next return state.Next
} }
@ -74,11 +76,11 @@ func (state *TLSUpgrade) Process() State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
if element.Name.Space != messages.NSStartTLS || element.Name.Local != "starttls" { if element.Name.Space != xmpp.NSStartTLS || element.Name.Local != "starttls" {
state.Client.Log.Warn("is no starttls", element) state.Client.Log.Warn("is no starttls", element)
return nil return nil
} }
fmt.Fprintf(state.Client.Conn, "<proceed xmlns='%s'/>", messages.NSStartTLS) fmt.Fprintf(state.Client.Conn, "<proceed xmlns='%s'/>", xmpp.NSStartTLS)
// perform the TLS handshake // perform the TLS handshake
var tlsConfig *tls.Config var tlsConfig *tls.Config
if m := state.TLSManager; m != nil { if m := state.TLSManager; m != nil {

View File

@ -11,7 +11,7 @@ type SendingClient struct {
Client *utils.Client Client *utils.Client
} }
// Process messages // Process xmpp
func (state *SendingClient) Process() State { func (state *SendingClient) Process() State {
state.Client.Log = state.Client.Log.WithField("state", "normal") state.Client.Log = state.Client.Log.WithField("state", "normal")
state.Client.Log.Debug("sending") state.Client.Log.Debug("sending")
@ -37,7 +37,7 @@ type ReceivingClient struct {
Client *utils.Client Client *utils.Client
} }
// Process messages // Process xmpp
func (state *ReceivingClient) Process() State { func (state *ReceivingClient) Process() State {
element, err := state.Client.Read() element, err := state.Client.Read()
if err != nil { if err != nil {

View File

@ -6,12 +6,15 @@ import (
"fmt" "fmt"
"strings" "strings"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/database" "dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/extension" "dev.sum7.eu/genofire/yaja/server/extension"
"dev.sum7.eu/genofire/yaja/server/state" "dev.sum7.eu/genofire/yaja/server/state"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
"golang.org/x/crypto/acme/autocert" "dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
) )
// ConnectionStartup return steps through TCP TLS state // ConnectionStartup return steps through TCP TLS state
@ -47,7 +50,7 @@ type TLSStream struct {
domainRegisterAllowed utils.DomainRegisterAllowed domainRegisterAllowed utils.DomainRegisterAllowed
} }
// Process messages // Process xmpp
func (state *TLSStream) Process() state.State { func (state *TLSStream) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "tls stream") state.Client.Log = state.Client.Log.WithField("state", "tls stream")
state.Client.Log.Debug("running") state.Client.Log.Debug("running")
@ -58,7 +61,7 @@ func (state *TLSStream) Process() state.State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" { if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
state.Client.Log.Warn("is no stream") state.Client.Log.Warn("is no stream")
return state return state
} }
@ -72,8 +75,8 @@ func (state *TLSStream) Process() state.State {
<mechanism>PLAIN</mechanism> <mechanism>PLAIN</mechanism>
</mechanisms> </mechanisms>
</stream:features>`, </stream:features>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream, xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream,
messages.NSSASL, messages.NSFeaturesIQRegister) xmpp.NSSASL, xmppiq.NSFeaturesIQRegister)
} else { } else {
fmt.Fprintf(state.Client.Conn, `<?xml version='1.0'?> fmt.Fprintf(state.Client.Conn, `<?xml version='1.0'?>
<stream:stream id='%x' version='1.0' xmlns='%s' xmlns:stream='%s'> <stream:stream id='%x' version='1.0' xmlns='%s' xmlns:stream='%s'>
@ -82,8 +85,8 @@ func (state *TLSStream) Process() state.State {
<mechanism>PLAIN</mechanism> <mechanism>PLAIN</mechanism>
</mechanisms> </mechanisms>
</stream:features>`, </stream:features>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream, xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream,
messages.NSSASL) xmpp.NSSASL)
} }
return state.Next return state.Next
@ -97,7 +100,7 @@ type SASLAuth struct {
domainRegisterAllowed utils.DomainRegisterAllowed domainRegisterAllowed utils.DomainRegisterAllowed
} }
// Process messages // Process xmpp
func (state *SASLAuth) Process() state.State { func (state *SASLAuth) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "sasl auth") state.Client.Log = state.Client.Log.WithField("state", "sasl auth")
state.Client.Log.Debug("running") state.Client.Log.Debug("running")
@ -109,7 +112,7 @@ func (state *SASLAuth) Process() state.State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
var auth messages.SASLAuth var auth xmpp.SASLAuth
if err = state.Client.In.DecodeElement(&auth, element); err != nil { if err = state.Client.In.DecodeElement(&auth, element); err != nil {
state.Client.Log.Info("start substate for registration") state.Client.Log.Info("start substate for registration")
return &RegisterFormRequest{ return &RegisterFormRequest{
@ -131,7 +134,7 @@ func (state *SASLAuth) Process() state.State {
} }
info := strings.Split(string(data), "\x00") info := strings.Split(string(data), "\x00")
// should check that info[1] starts with state.Client.JID // should check that info[1] starts with state.Client.JID
state.Client.JID.Local = info[1] state.Client.JID.Node = info[1]
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full()) state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
success, err := state.database.Authenticate(state.Client.JID, info[2]) success, err := state.database.Authenticate(state.Client.JID, info[2])
if err != nil { if err != nil {
@ -140,11 +143,11 @@ func (state *SASLAuth) Process() state.State {
} }
if success { if success {
state.Client.Log.Info("success auth") state.Client.Log.Info("success auth")
fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", messages.NSSASL) fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", xmpp.NSSASL)
return state.Next return state.Next
} }
state.Client.Log.Warn("failed auth") state.Client.Log.Warn("failed auth")
fmt.Fprintf(state.Client.Conn, "<failure xmlns='%s'><not-authorized/></failure>", messages.NSSASL) fmt.Fprintf(state.Client.Conn, "<failure xmlns='%s'><not-authorized/></failure>", xmpp.NSSASL)
return nil return nil
} }
@ -155,7 +158,7 @@ type AuthedStart struct {
Client *utils.Client Client *utils.Client
} }
// Process messages // Process xmpp
func (state *AuthedStart) Process() state.State { func (state *AuthedStart) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "authed started") state.Client.Log = state.Client.Log.WithField("state", "authed started")
state.Client.Log.Debug("running") state.Client.Log.Debug("running")
@ -173,8 +176,8 @@ func (state *AuthedStart) Process() state.State {
<required/> <required/>
</bind> </bind>
</stream:features>`, </stream:features>`,
messages.NSStream, state.Client.JID.Domain, messages.CreateCookie(), messages.NSClient, xmpp.NSStream, state.Client.JID.Domain, xmpp.CreateCookie(), xmpp.NSClient,
messages.NSBind) xmpp.NSBind)
return state.Next return state.Next
} }
@ -185,7 +188,7 @@ type AuthedStream struct {
Client *utils.Client Client *utils.Client
} }
// Process messages // Process xmpp
func (state *AuthedStream) Process() state.State { func (state *AuthedStream) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "authed stream") state.Client.Log = state.Client.Log.WithField("state", "authed stream")
state.Client.Log.Debug("running") state.Client.Log.Debug("running")
@ -198,12 +201,12 @@ func (state *AuthedStream) Process() state.State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
var msg messages.IQClient var msg xmpp.IQClient
if err = state.Client.In.DecodeElement(&msg, element); err != nil { if err = state.Client.In.DecodeElement(&msg, element); err != nil {
state.Client.Log.Warn("is no iq: ", err) state.Client.Log.Warn("is no iq: ", err)
return nil return nil
} }
if msg.Type != messages.IQTypeSet { if msg.Type != xmpp.IQTypeSet {
state.Client.Log.Warn("is no set iq") state.Client.Log.Warn("is no set iq")
return nil return nil
} }
@ -222,12 +225,12 @@ func (state *AuthedStream) Process() state.State {
state.Client.JID.Resource = msg.Bind.Resource state.Client.JID.Resource = msg.Bind.Resource
} }
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full()) state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
state.Client.Out.Encode(&messages.IQClient{ state.Client.Out.Encode(&xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: state.Client.JID, To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain), From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID, ID: msg.ID,
Bind: &messages.Bind{JID: state.Client.JID}, Bind: &xmpp.Bind{JID: state.Client.JID},
}) })
return state.Next return state.Next

View File

@ -4,10 +4,12 @@ import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/database" "dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model" "dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/state" "dev.sum7.eu/genofire/yaja/server/state"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
) )
type RegisterFormRequest struct { type RegisterFormRequest struct {
@ -28,12 +30,12 @@ func (state *RegisterFormRequest) Process() state.State {
return nil return nil
} }
var msg messages.IQClient var msg xmpp.IQClient
if err := state.Client.In.DecodeElement(&msg, state.element); err != nil { if err := state.Client.In.DecodeElement(&msg, state.element); err != nil {
state.Client.Log.Warn("is no iq: ", err) state.Client.Log.Warn("is no iq: ", err)
return state return state
} }
if msg.Type != messages.IQTypeGet { if msg.Type != xmpp.IQTypeGet {
state.Client.Log.Warn("is no get iq") state.Client.Log.Warn("is no get iq")
return state return state
} }
@ -46,12 +48,12 @@ func (state *RegisterFormRequest) Process() state.State {
state.Client.Log.Warn("is no iq register") state.Client.Log.Warn("is no iq register")
return nil return nil
} }
state.Client.Out.Encode(&messages.IQClient{ state.Client.Out.Encode(&xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: state.Client.JID, To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain), From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID, ID: msg.ID,
PrivateRegister: &messages.IQPrivateRegister{ PrivateRegister: &xmppiq.IQPrivateRegister{
Instructions: "Choose a username and password for use with this service.", Instructions: "Choose a username and password for use with this service.",
Username: "", Username: "",
Password: "", Password: "",
@ -83,12 +85,12 @@ func (state *RegisterRequest) Process() state.State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
var msg messages.IQClient var msg xmpp.IQClient
if err = state.Client.In.DecodeElement(&msg, element); err != nil { if err = state.Client.In.DecodeElement(&msg, element); err != nil {
state.Client.Log.Warn("is no iq: ", err) state.Client.Log.Warn("is no iq: ", err)
return state return state
} }
if msg.Type != messages.IQTypeGet { if msg.Type != xmpp.IQTypeGet {
state.Client.Log.Warn("is no get iq") state.Client.Log.Warn("is no get iq")
return state return state
} }
@ -101,21 +103,21 @@ func (state *RegisterRequest) Process() state.State {
return nil return nil
} }
state.Client.JID.Local = msg.PrivateRegister.Username state.Client.JID.Node = msg.PrivateRegister.Username
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full()) state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
account := model.NewAccount(state.Client.JID, msg.PrivateRegister.Password) account := model.NewAccount(state.Client.JID, msg.PrivateRegister.Password)
err = state.database.AddAccount(account) err = state.database.AddAccount(account)
if err != nil { if err != nil {
state.Client.Out.Encode(&messages.IQClient{ state.Client.Out.Encode(&xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: state.Client.JID, To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain), From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID, ID: msg.ID,
PrivateRegister: msg.PrivateRegister, PrivateRegister: msg.PrivateRegister,
Error: &messages.ErrorClient{ Error: &xmpp.ErrorClient{
Code: "409", Code: "409",
Type: "cancel", Type: "cancel",
StanzaErrorGroup: messages.StanzaErrorGroup{ StanzaErrorGroup: xmpp.StanzaErrorGroup{
Conflict: &xml.Name{}, Conflict: &xml.Name{},
}, },
}, },
@ -123,10 +125,10 @@ func (state *RegisterRequest) Process() state.State {
state.Client.Log.Warn("database error: ", err) state.Client.Log.Warn("database error: ", err)
return state return state
} }
state.Client.Out.Encode(&messages.IQClient{ state.Client.Out.Encode(&xmpp.IQClient{
Type: messages.IQTypeResult, Type: xmpp.IQTypeResult,
To: state.Client.JID, To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain), From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID, ID: msg.ID,
}) })

View File

@ -6,12 +6,13 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/database" "dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/extension" "dev.sum7.eu/genofire/yaja/server/extension"
"dev.sum7.eu/genofire/yaja/server/state" "dev.sum7.eu/genofire/yaja/server/state"
"dev.sum7.eu/genofire/yaja/server/utils" "dev.sum7.eu/genofire/yaja/server/utils"
"golang.org/x/crypto/acme/autocert" "dev.sum7.eu/genofire/yaja/xmpp"
) )
// ConnectionStartup return steps through TCP TLS state // ConnectionStartup return steps through TCP TLS state
@ -41,7 +42,7 @@ type Dailback struct {
Client *utils.Client Client *utils.Client
} }
// Process messages // Process xmpp
func (state *Dailback) Process() state.State { func (state *Dailback) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "dialback") state.Client.Log = state.Client.Log.WithField("state", "dialback")
state.Client.Log.Debug("running") state.Client.Log.Debug("running")
@ -73,7 +74,7 @@ type TLSStream struct {
domainRegisterAllowed utils.DomainRegisterAllowed domainRegisterAllowed utils.DomainRegisterAllowed
} }
// Process messages // Process xmpp
func (state *TLSStream) Process() state.State { func (state *TLSStream) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "tls stream") state.Client.Log = state.Client.Log.WithField("state", "tls stream")
state.Client.Log.Debug("running") state.Client.Log.Debug("running")
@ -84,7 +85,7 @@ func (state *TLSStream) Process() state.State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" { if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
state.Client.Log.Warn("is no stream") state.Client.Log.Warn("is no stream")
return state return state
} }
@ -97,8 +98,8 @@ func (state *TLSStream) Process() state.State {
</mechanisms> </mechanisms>
<bidi xmlns='urn:xmpp:features:bidi'/> <bidi xmlns='urn:xmpp:features:bidi'/>
</stream:features>`, </stream:features>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream, xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream,
messages.NSSASL) xmpp.NSSASL)
return state.Next return state.Next
} }
@ -111,7 +112,7 @@ type SASLAuth struct {
domainRegisterAllowed utils.DomainRegisterAllowed domainRegisterAllowed utils.DomainRegisterAllowed
} }
// Process messages // Process xmpp
func (state *SASLAuth) Process() state.State { func (state *SASLAuth) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "sasl auth") state.Client.Log = state.Client.Log.WithField("state", "sasl auth")
state.Client.Log.Debug("running") state.Client.Log.Debug("running")
@ -123,7 +124,7 @@ func (state *SASLAuth) Process() state.State {
state.Client.Log.Warn("unable to read: ", err) state.Client.Log.Warn("unable to read: ", err)
return nil return nil
} }
var auth messages.SASLAuth var auth xmpp.SASLAuth
if err = state.Client.In.DecodeElement(&auth, element); err != nil { if err = state.Client.In.DecodeElement(&auth, element); err != nil {
return nil return nil
} }
@ -136,6 +137,6 @@ func (state *SASLAuth) Process() state.State {
state.Client.Log.Debug(auth.Mechanism, string(data)) state.Client.Log.Debug(auth.Mechanism, string(data))
state.Client.Log.Info("success auth") state.Client.Log.Info("success auth")
fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", messages.NSSASL) fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", xmpp.NSSASL)
return state.Next return state.Next
} }

View File

@ -4,9 +4,10 @@ import (
"encoding/xml" "encoding/xml"
"net" "net"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
type Client struct { type Client struct {
@ -16,7 +17,7 @@ type Client struct {
Out *xml.Encoder Out *xml.Encoder
In *xml.Decoder In *xml.Decoder
JID *messages.JID JID *xmppbase.JID
account *model.Account account *model.Account
Messages chan interface{} Messages chan interface{}

View File

@ -1,5 +1,5 @@
package utils package utils
import "dev.sum7.eu/genofire/yaja/messages" import "dev.sum7.eu/genofire/yaja/xmpp/base"
type DomainRegisterAllowed func(*messages.JID) bool type DomainRegisterAllowed func(*xmppbase.JID) bool

View File

@ -1,4 +1,4 @@
package messages package xmppbase
import ( import (
"errors" "errors"
@ -13,7 +13,7 @@ func init() {
// JID struct // JID struct
type JID struct { type JID struct {
Local string Node string
Domain string Domain string
Resource string Resource string
} }
@ -28,7 +28,7 @@ func NewJID(jidString string) *JID {
jidSplit := jidSplitTmp[0] jidSplit := jidSplitTmp[0]
return &JID{ return &JID{
Local: jidSplit[1], Node: jidSplit[1],
Domain: jidSplit[2], Domain: jidSplit[2],
Resource: jidSplit[3], Resource: jidSplit[3],
} }
@ -39,13 +39,16 @@ func (jid *JID) Bare() string {
if jid == nil { if jid == nil {
return "" return ""
} }
if jid.Local != "" { if jid.Node != "" {
return jid.Local + "@" + jid.Domain return jid.Node + "@" + jid.Domain
} }
return jid.Domain return jid.Domain
} }
func (jid *JID) String() string { return jid.Bare() } // IsBare checks if jid has node and domain but no resource
func (jid *JID) IsBare() bool {
return jid != nil && jid.Node != "" && jid.Domain != "" && jid.Resource == ""
}
// Full get the "full" jid as string // Full get the "full" jid as string
func (jid *JID) Full() string { func (jid *JID) Full() string {
@ -58,6 +61,13 @@ func (jid *JID) Full() string {
return jid.Bare() return jid.Bare()
} }
// IsFull checks if jid has all three parts of a JID
func (jid *JID) IsFull() bool {
return jid != nil && jid.Node != "" && jid.Domain != "" && jid.Resource != ""
}
func (jid *JID) String() string { return jid.Bare() }
//MarshalText to bytearray //MarshalText to bytearray
func (jid JID) MarshalText() ([]byte, error) { func (jid JID) MarshalText() ([]byte, error) {
return []byte(jid.Full()), nil return []byte(jid.Full()), nil
@ -69,7 +79,7 @@ func (jid *JID) UnmarshalText(data []byte) (err error) {
if newJID == nil { if newJID == nil {
return errors.New("not a valid jid") return errors.New("not a valid jid")
} }
jid.Local = newJID.Local jid.Node = newJID.Node
jid.Domain = newJID.Domain jid.Domain = newJID.Domain
jid.Resource = newJID.Resource jid.Resource = newJID.Resource
return nil return nil

View File

@ -1,4 +1,4 @@
package messages package xmppbase
import ( import (
"testing" "testing"
@ -13,57 +13,57 @@ func TestNewJID(t *testing.T) {
checkList := map[string]*JID{ checkList := map[string]*JID{
"juliet@example.com": { "juliet@example.com": {
Local: "juliet", Node: "juliet",
Domain: "example.com", Domain: "example.com",
}, },
"juliet@example.com/foo": { "juliet@example.com/foo": {
Local: "juliet", Node: "juliet",
Domain: "example.com", Domain: "example.com",
Resource: "foo", Resource: "foo",
}, },
"juliet@example.com/foo bar": { "juliet@example.com/foo bar": {
Local: "juliet", Node: "juliet",
Domain: "example.com", Domain: "example.com",
Resource: "foo bar", Resource: "foo bar",
}, },
"juliet@example.com/foo@bar": { "juliet@example.com/foo@bar": {
Local: "juliet", Node: "juliet",
Domain: "example.com", Domain: "example.com",
Resource: "foo@bar", Resource: "foo@bar",
}, },
"foo\\20bar@example.com": { "foo\\20bar@example.com": {
Local: "foo\\20bar", Node: "foo\\20bar",
Domain: "example.com", Domain: "example.com",
}, },
"fussball@example.com": { "fussball@example.com": {
Local: "fussball", Node: "fussball",
Domain: "example.com", Domain: "example.com",
}, },
"fu&#xDF;ball@example.com": { "fu&#xDF;ball@example.com": {
Local: "fu&#xDF;ball", Node: "fu&#xDF;ball",
Domain: "example.com", Domain: "example.com",
}, },
"&#x3C0;@example.com": { "&#x3C0;@example.com": {
Local: "&#x3C0;", Node: "&#x3C0;",
Domain: "example.com", Domain: "example.com",
}, },
"&#x3A3;@example.com/foo": { "&#x3A3;@example.com/foo": {
Local: "&#x3A3;", Node: "&#x3A3;",
Domain: "example.com", Domain: "example.com",
Resource: "foo", Resource: "foo",
}, },
"&#x3C3;@example.com/foo": { "&#x3C3;@example.com/foo": {
Local: "&#x3C3;", Node: "&#x3C3;",
Domain: "example.com", Domain: "example.com",
Resource: "foo", Resource: "foo",
}, },
"&#x3C2;@example.com/foo": { "&#x3C2;@example.com/foo": {
Local: "&#x3C2;", Node: "&#x3C2;",
Domain: "example.com", Domain: "example.com",
Resource: "foo", Resource: "foo",
}, },
"king@example.com/&#x265A;": { "king@example.com/&#x265A;": {
Local: "king", Node: "king",
Domain: "example.com", Domain: "example.com",
Resource: "&#x265A;", Resource: "&#x265A;",
}, },
@ -97,7 +97,7 @@ func TestNewJID(t *testing.T) {
continue continue
} }
assert.Equal(jidValid.Local, jid.Local, "the local part was not right detectet:"+jidString) assert.Equal(jidValid.Node, jid.Node, "the local part was not right detectet:"+jidString)
assert.Equal(jidValid.Domain, jid.Domain, "the domain part was not right detectet:"+jidString) assert.Equal(jidValid.Domain, jid.Domain, "the domain part was not right detectet:"+jidString)
assert.Equal(jidValid.Resource, jid.Resource, "the resource part was not right detectet:"+jidString) assert.Equal(jidValid.Resource, jid.Resource, "the resource part was not right detectet:"+jidString)
assert.Equal(jidValid.Full(), jidString, "the function full of jid did not work") assert.Equal(jidValid.Full(), jidString, "the function full of jid did not work")
@ -113,11 +113,11 @@ func TestJIDBare(t *testing.T) {
checkList := map[string]*JID{ checkList := map[string]*JID{
"aaa@example.com": { "aaa@example.com": {
Local: "aaa", Node: "aaa",
Domain: "example.com", Domain: "example.com",
}, },
"aab@example.com": { "aab@example.com": {
Local: "aab", Node: "aab",
Domain: "example.com", Domain: "example.com",
Resource: "foo", Resource: "foo",
}, },
@ -140,7 +140,7 @@ func TestMarshal(t *testing.T) {
err := jid.UnmarshalText([]byte("juliet@example.com/foo")) err := jid.UnmarshalText([]byte("juliet@example.com/foo"))
assert.NoError(err) assert.NoError(err)
assert.Equal(jid.Local, "juliet") assert.Equal(jid.Node, "juliet")
assert.Equal(jid.Domain, "example.com") assert.Equal(jid.Domain, "example.com")
assert.Equal(jid.Resource, "foo") assert.Equal(jid.Resource, "foo")
@ -149,7 +149,7 @@ func TestMarshal(t *testing.T) {
assert.Error(err) assert.Error(err)
jid = &JID{ jid = &JID{
Local: "romeo", Node: "romeo",
Domain: "example.com", Domain: "example.com",
Resource: "bar", Resource: "bar",
} }

View File

@ -1,8 +1,8 @@
package messages package xmpp
import "encoding/xml" import "encoding/xml"
// RFC 6120 - A.5 Client Namespace (a part) // ErrorClient implements RFC 6120 - A.5 Client Namespace (a part)
type ErrorClient struct { type ErrorClient struct {
XMLName xml.Name `xml:"jabber:client error"` XMLName xml.Name `xml:"jabber:client error"`
Code string `xml:"code,attr,omitempty"` Code string `xml:"code,attr,omitempty"`

26
xmpp/client_iq.go Normal file
View File

@ -0,0 +1,26 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
)
// IQClient implements RFC 6120 - A.5 Client Namespace (a part)
type IQClient struct {
XMLName xml.Name `xml:"jabber:client iq"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *xmppbase.JID `xml:"to,attr,omitempty"`
Type IQType `xml:"type,attr"` // required
Error *ErrorClient
Bind *Bind // RFC 6120 A.7 Resource binding namespace (But in a IQ?)
Ping *xmppiq.Ping // XEP-0199: XMPP Ping (see iq/ping.go)
PrivateQuery *xmppiq.IQPrivateQuery // which XEP ?
PrivateRegister *xmppiq.IQPrivateRegister // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

27
xmpp/client_message.go Normal file
View File

@ -0,0 +1,27 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// MessageClient implements RFC 6120 - A.5 Client Namespace (a part)
type MessageClient struct {
XMLName xml.Name `xml:"jabber:client message"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr,omitempty"`
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

31
xmpp/client_presence.go Normal file
View File

@ -0,0 +1,31 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// PresenceClient implements RFC 6120 - A.5 Client Namespace (a part)
type PresenceClient struct {
XMLName xml.Name `xml:"jabber:client presence"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr,omitempty"`
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,10 +1,12 @@
package messages package xmpp
import ( import (
"encoding/xml" "encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
) )
// RFC 6120 - A.1 Stream Namespace // StreamFeatures implements RFC 6120 - A.1 Stream Namespace
type StreamFeatures struct { type StreamFeatures struct {
XMLName xml.Name `xml:"http://etherx.jabber.org/streams features"` XMLName xml.Name `xml:"http://etherx.jabber.org/streams features"`
StartTLS *TLSStartTLS StartTLS *TLSStartTLS
@ -13,25 +15,25 @@ type StreamFeatures struct {
Session bool Session bool
} }
// RFC 6120 - A.3 StartTLS Namespace // TLSStartTLS implements RFC 6120 - A.3 StartTLS Namespace
type TLSStartTLS struct { type TLSStartTLS struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls starttls"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls starttls"`
Required *string `xml:"required"` Required *string `xml:"required"`
} }
// RFC 6120 - A.3 StartTLS Namespace // TLSProceed implements RFC 6120 - A.3 StartTLS Namespace
type TLSProceed struct { type TLSProceed struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls proceed"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls proceed"`
} }
// RFC 6120 - A.3 StartTLS Namespace // TLSFailure implements RFC 6120 - A.3 StartTLS Namespace
type TLSFailure struct { type TLSFailure struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls failure"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls failure"`
} }
// RFC 6120 A.7 Resource binding namespace // Bind implements RFC 6120 A.7 Resource binding namespace
type Bind struct { type Bind struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
Resource string `xml:"resource"` Resource string `xml:"resource"`
JID *JID `xml:"jid"` JID *xmppbase.JID `xml:"jid"`
} }

View File

@ -1,5 +1,6 @@
package messages package xmpp
// ErrorType is a Enum of error attribute type
type ErrorType string type ErrorType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace // RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,5 +1,6 @@
package messages package xmpp
// IQType is a Enum of iq attribute type
type IQType string type IQType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace // RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,5 +1,6 @@
package messages package xmpp
// MessageType is a Enum of message attribute type
type MessageType string type MessageType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace // RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,5 +1,6 @@
package messages package xmpp
// PresenceType is a Enum of presence attribute type
type PresenceType string type PresenceType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace // RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace
@ -13,6 +14,7 @@ const (
PresenceTypeUnsubscribed PresenceType = "unsubscribed" PresenceTypeUnsubscribed PresenceType = "unsubscribed"
) )
// PresenceShow is a Enum of presence element show
type PresenceShow string type PresenceShow string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace // RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,8 +1,8 @@
package messages package xmpp
import "encoding/xml" import "encoding/xml"
// RFC 6120 A.8 Resource binding namespace // StanzaErrorGroup implements RFC 6120 A.8 Resource binding namespace
type StanzaErrorGroup struct { type StanzaErrorGroup struct {
BadRequest *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-stanzas bad-request"` BadRequest *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-stanzas bad-request"`
Conflict *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-stanzas conflict"` Conflict *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-stanzas conflict"`

View File

@ -1,8 +1,8 @@
package messages package xmpp
import "encoding/xml" import "encoding/xml"
// RFC 6120 A.2 Stream Error Namespace // StreamErrorGroup implements RFC 6120 A.2 Stream Error Namespace
type StreamErrorGroup struct { type StreamErrorGroup struct {
BadFormat *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams bad-format"` BadFormat *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams bad-format"`
BadNamespacePrefix *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams bad-namespace-prefix"` BadNamespacePrefix *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams bad-namespace-prefix"`
@ -31,7 +31,7 @@ type StreamErrorGroup struct {
UnsupportedVersion *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams unsupported-version"` UnsupportedVersion *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams unsupported-version"`
} }
// RFC 6120 A.2 Stream Error Namespace // StreamError implements RFC 6120 A.2 Stream Error Namespace
type StreamError struct { type StreamError struct {
XMLName xml.Name `xml:"http://etherx.jabber.org/streams error"` XMLName xml.Name `xml:"http://etherx.jabber.org/streams error"`
Text *Text Text *Text

View File

@ -1,8 +1,8 @@
package messages package xmpp
import "encoding/xml" import "encoding/xml"
// RFC 6120 part of A.2 Stream Error Namespace, A.4 SASL Namespace and A.8 Stanza Error Namespace // Text implements RFC 6120 part of A.2 Stream Error Namespace, A.4 SASL Namespace and A.8 Stanza Error Namespace
type Text struct { type Text struct {
// `xml:"urn:ietf:params:xml:ns:xmpp-streams text"` // `xml:"urn:ietf:params:xml:ns:xmpp-streams text"`
// `xml:"urn:ietf:params:xml:ns:xmpp-sasl text"` // `xml:"urn:ietf:params:xml:ns:xmpp-sasl text"`
@ -12,13 +12,13 @@ type Text struct {
Body string `xml:",innerxml"` Body string `xml:",innerxml"`
} }
// Fallback - any hasn't matched element // XMLElement is for Unmarshal undefined structs a fallback - any hasn't matched element
type XMLElement struct { type XMLElement struct {
XMLName xml.Name XMLName xml.Name
InnerXML string `xml:",innerxml"` InnerXML string `xml:",innerxml"`
} }
// which XEP ? // Delay implements which XEP ?
type Delay struct { type Delay struct {
Stamp string `xml:"stamp,attr"` Stamp string `xml:"stamp,attr"`
} }

18
xmpp/iq/namespaces.go Normal file
View File

@ -0,0 +1,18 @@
package xmppiq
const (
// NSIQPing implements XEP-0199: XMPP Ping - 10
NSIQPing = "urn:xmpp:ping"
// NSIQDiscoInfo implements XEP 0030: Service Discovery - 11.1 disco#info
NSIQDiscoInfo = "http://jabber.org/protocol/disco#info"
// NSIQDiscoItems implements XEP 0030: Service Discovery - 11.2 disco#items
NSIQDiscoItems = "http://jabber.org/protocol/disco#items"
// NSIQRegister implements which XEP ?
NSIQRegister = "jabber:iq:register"
// NSFeaturesIQRegister implements which XEP ?
NSFeaturesIQRegister = "http://jabber.org/features/iq-register"
)

10
xmpp/iq/ping.go Normal file
View File

@ -0,0 +1,10 @@
package xmppiq
import (
"encoding/xml"
)
// XEP-0199: XMPP Ping
type Ping struct {
XMLName xml.Name `xml:"urn:xmpp:ping ping"`
}

View File

@ -0,0 +1,44 @@
package xmppiq
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// IQDiscoQueryInfo implements XEP 0030: Service Discovery - 11.1 disco#info
type IQDiscoQueryInfo struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#info query"`
Node *string `xml:"node,attr"`
Identities []*IQDiscoIdentity
Features []*IQDiscoFeature
}
// IQDiscoIdentity implements XEP 0030: Service Discovery - 11.1 disco#info
type IQDiscoIdentity struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#info identity"`
Category string `xml:"category"` //required
Name *string `xml:"name"`
Type string `xml:"type"` //required
}
// IQDiscoFeature implements XEP 0030: Service Discovery - 11.1 disco#info
type IQDiscoFeature struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#info feature"`
Var string `xml:"var"` //required
}
// IQDiscoQueryItem implements XEP 0030: Service Discovery - 11.2 disco#items
type IQDiscoQueryItem struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#items query"`
Node *string `xml:"node,attr"`
Items []*IQDiscoItem
}
// IQDiscoItem implements XEP 0030: Service Discovery - 11.2 disco#items
type IQDiscoItem struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#items item"`
JID *xmppbase.JID `xml:"jid"`
Node *string `xml:"node"`
Name *string `xml:"name"`
}

View File

@ -1,14 +1,9 @@
package messages package xmppiq
import ( import (
"encoding/xml" "encoding/xml"
) )
// XEP-0199: XMPP Ping
type Ping struct {
XMLName xml.Name `xml:"urn:xmpp:ping ping"`
}
// which XEP ???? // which XEP ????
// where to put: (server part debug? is it part) // where to put: (server part debug? is it part)
type IQPrivateQuery struct { type IQPrivateQuery struct {

27
xmpp/namespaces.go Normal file
View File

@ -0,0 +1,27 @@
package xmpp
const (
// NSStream implements RFC 6120 - A.1 Stream Namespace
NSStream = "http://etherx.jabber.org/streams"
// NSStreamError implements RFC 6120 - A.2 Stream Error Namespace
NSStreamError = "urn:ietf:params:xml:ns:xmpp-streams"
// NSStartTLS implements RFC 6120 - A.3 StartTLS Namespace
NSStartTLS = "urn:ietf:params:xml:ns:xmpp-tls"
// NSSASL implements RFC 6120 - A.4 SASL Namespace
NSSASL = "urn:ietf:params:xml:ns:xmpp-sasl"
// NSClient implements RFC 6120 - A.5 Client Namespace
NSClient = "jabber:client"
// NSServer implements RFC 6120 - A.6 Server Namespace
NSServer = "jabber:server"
// NSBind implements RFC 6120 - A.7 Resource Binding Namespace
NSBind = "urn:ietf:params:xml:ns:xmpp-bind"
// NSStanzaError implements RFC 6120 - A.8 Stanza Error Binding Namespace
NSStanzaError = "urn:ietf:params:xml:ns:xmpp-stanzas"
)

21
xmpp/roster.go Normal file
View File

@ -0,0 +1,21 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// ClientQuery implements which XEP ????
type ClientQuery struct {
Item []RosterItem
}
// RosterItem implements which XEP ????
type RosterItem struct {
XMLName xml.Name `xml:"jabber:iq:roster item"`
JID *xmppbase.JID `xml:",attr"`
Name string `xml:",attr"`
Subscription string `xml:",attr"`
Group []string
}

View File

@ -1,46 +1,46 @@
package messages package xmpp
import ( import (
"encoding/xml" "encoding/xml"
) )
// RFC 6120 - A.4 SASL Namespace // SASLMechanisms implements RFC 6120 - A.4 SASL Namespace
type SASLMechanisms struct { type SASLMechanisms struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl mechanisms"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl mechanisms"`
Mechanism []string `xml:"mechanism"` Mechanism []string `xml:"mechanism"`
} }
// SASLAuth element // SASLAuth implements SASLAuth element
type SASLAuth struct { type SASLAuth struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl auth"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl auth"`
Mechanism string `xml:"mechanism,attr"` Mechanism string `xml:"mechanism,attr"`
Body string `xml:",chardata"` Body string `xml:",chardata"`
} }
// SASLChallenge element // SASLChallenge implements SASLChallenge element
type SASLChallenge struct { type SASLChallenge struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl challenge"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl challenge"`
Body string `xml:",chardata"` Body string `xml:",chardata"`
} }
// SASLResponse element // SASLResponse implements SASLResponse element
type SASLResponse struct { type SASLResponse struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl response"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl response"`
Body string `xml:",chardata"` Body string `xml:",chardata"`
} }
// SASLSuccess element // SASLSuccess implements SASLSuccess element
type SASLSuccess struct { type SASLSuccess struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl success"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl success"`
Body string `xml:",chardata"` Body string `xml:",chardata"`
} }
// SASLAbout element // SASLAbout implements SASLAbout element
type SASLAbout struct { type SASLAbout struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl abort"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl abort"`
} }
// RFC 6120 - A.4 SASL Namespace // SASLFailure implements RFC 6120 - A.4 SASL Namespace
type SASLFailure struct { type SASLFailure struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl failure"` XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl failure"`

View File

@ -1,8 +1,8 @@
package messages package xmpp
import "encoding/xml" import "encoding/xml"
// RFC 6120 - A.6 Server Namespace (a part) // ErrorServer implements RFC 6120 - A.6 Server Namespace (a part)
type ErrorServer struct { type ErrorServer struct {
XMLName xml.Name `xml:"jabber:server error"` XMLName xml.Name `xml:"jabber:server error"`
Code string `xml:"code,attr,omitempty"` Code string `xml:"code,attr,omitempty"`

24
xmpp/server_iq.go Normal file
View File

@ -0,0 +1,24 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
)
// IQServer implements RFC 6120 - A.6 Server Namespace (a part)
type IQServer struct {
XMLName xml.Name `xml:"jabber:server iq"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *xmppbase.JID `xml:"to,attr"` // required
Type IQType `xml:"type,attr"` // required
Error *ErrorServer
Bind *Bind // RFC 6120 A.7 Resource binding namespace (But in a IQ?)
Ping *xmppiq.Ping // XEP-0199: XMPP Ping (see iq/ping.go)
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

27
xmpp/server_message.go Normal file
View File

@ -0,0 +1,27 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// MessageServer implements RFC 6120 - A.6 Server Namespace (a part)
type MessageServer struct {
XMLName xml.Name `xml:"jabber:server message"`
From *xmppbase.JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr"` // required
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

31
xmpp/server_presence.go Normal file
View File

@ -0,0 +1,31 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// PresenceServer implements RFC 6120 - A.6 Server Namespace (a part)
type PresenceServer struct {
XMLName xml.Name `xml:"jabber:server presence"`
From *xmppbase.JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr"` // required
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,4 +1,4 @@
package messages package xmpp
import ( import (
"crypto/rand" "crypto/rand"
@ -21,7 +21,6 @@ func XMLStartElementToString(element *xml.StartElement) string {
} }
func XMLChildrenString(o interface{}) (result string) { func XMLChildrenString(o interface{}) (result string) {
first := true
val := reflect.ValueOf(o) val := reflect.ValueOf(o)
if val.Kind() == reflect.Interface && !val.IsNil() { if val.Kind() == reflect.Interface && !val.IsNil() {
elm := val.Elem() elm := val.Elem()
@ -29,25 +28,24 @@ func XMLChildrenString(o interface{}) (result string) {
val = elm val = elm
} }
} }
if val.Kind() != reflect.Struct { if val.Kind() == reflect.Struct {
return first := true
} for i := 0; i < val.NumField(); i++ {
// struct valueField := val.Field(i)
for i := 0; i < val.NumField(); i++ { if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
valueField := val.Field(i) elm := valueField.Elem()
if valueField.Kind() == reflect.Interface && !valueField.IsNil() { if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
elm := valueField.Elem() valueField = elm
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr { }
valueField = elm
} }
}
if xmlElement, ok := valueField.Interface().(*xml.Name); ok && xmlElement != nil { if xmlElement, ok := valueField.Interface().(*xml.Name); ok && xmlElement != nil {
if first { if first {
first = false first = false
result += xmlElement.Local result += xmlElement.Local
} else { } else {
result += ", " + xmlElement.Local result += ", " + xmlElement.Local
}
} }
} }
} }