예제 #1
0
func TestNewChallenge(t *testing.T) {
	c := sta.NewChallenge("localhost")
	out, err := xml.Marshal(c)
	if err != nil || out == nil {
		t.Errorf("TestNewChallenge fail: %v \n ", err)
	}

}
예제 #2
0
func (c *ClientConnection) negotiateStream(domainTable *DomainTable) (e error) {
	buf := make([]byte, RECV_BUF_LEN)
	c.readSocket(buf)
	stream := new(stanza.Stream)
	xml.Unmarshal(buf, stream)
	c.domainpart = stream.To

	domain, err := domainTable.GetDomain(c.domainpart)
	if err != nil {
		c.conn.Write([]byte("bad host"))
		e = err
		return
	} else {
		c.domain = domain
	}

	response := c.buildStreamOpening()
	c.conn.Write(response)

	// read the client's response
	c.readSocket(buf)
	authStanza := new(stanza.Auth)
	xml.Unmarshal(buf, authStanza)
	switch {
	case authStanza.Mechanism == "DIGEST-MD5":
		challenge := stanza.NewChallenge(c.domainpart)
		out, _ := xml.Marshal(challenge)
		c.conn.Write(out)
		c.readSocket(buf)
		var response stanza.Response
		xml.Unmarshal(buf, response)
		_, challenge.Data = auth.ResponseDigestMd5(response.Data)
		out, _ = xml.Marshal(challenge)
		c.conn.Write(out)
		c.authenticated = true
		c.readSocket(buf)
	case authStanza.Mechanism == "PLAIN":
		c.username, _ = authStanza.GetCredentials()
		c.authenticated = true
	default:
		// TODO: real auth response
		c.conn.Write([]byte("</stream>"))
	}
	if !c.authenticated {
		println("Authentication failed!")
		// TODO: real auth response
		c.conn.Write([]byte("</stream>"))
		return
	}
	success := stanza.Success{Xmlns: authStanza.Xmlns}
	response, _ = xml.Marshal(success)
	c.conn.Write(response)

	// Read the client's stream restart
	c.readSocket(buf)
	response2 := c.buildStreamOpening()
	c.conn.Write(response2)

	// Receive and handle bind request
	c.readSocket(buf)
	iq := new(stanza.Iq)
	xml.Unmarshal(buf, iq)
	// TODO: this is terrible, resource won't always be there
	if len(iq.Bind[0].Resource) > 0 {
		c.resource = iq.Bind[0].Resource[0].Data
	} else {
		c.resource = "autogen"
	}
	responseIq := stanza.Iq{Type: "result", Id: iq.Id}
	b := stanza.Bind{Xmlns: iq.Bind[0].Xmlns}
	b.Jid = make([]*stanza.Jid, 1)
	b.Jid[0] = &stanza.Jid{Data: c.username + "@" + c.domainpart + "/" + c.resource}
	responseIq.Bind = make([]stanza.Bind, 1)
	responseIq.Bind[0] = b
	response, _ = xml.Marshal(responseIq)
	c.conn.Write(response)

	// Receive and handle session request
	c.readSocket(buf)
	iq = new(stanza.Iq)
	xml.Unmarshal(buf, iq)
	responseIq = stanza.Iq{Type: "result", Id: iq.Id, From: c.domainpart}
	response, _ = xml.Marshal(responseIq)
	c.conn.Write(response)

	// Receive and handle roster request
	c.readSocket(buf)

	iq = new(stanza.Iq)
	xml.Unmarshal(buf, iq)
	responseIq = stanza.Iq{Type: "result", To: iq.From, Id: iq.Id}
	responseIq.Query = make([]stanza.Query, 1)
	responseIq.Query[0].Xmlns = "jabber:iq:roster"
	response, _ = xml.Marshal(responseIq)
	c.conn.Write(response)
	return
}