コード例 #1
0
ファイル: bind_feature.go プロジェクト: oxpa/bullxmpp
func (t *BindFeature) Negotate(strm *stream.Stream) error {
	if strm.Jid.Resource != "" {
		t.Resource = &strm.Jid.Resource
	}
	id := strconv.Itoa(rand.Intn(1000))
	iq := Iq{To: strm.Jid.Server(), Id: &id, Payload: t}
	typ := IqTypeSet
	iq.Type = &typ
	if err := strm.Send(&iq); err != nil {
		return err
	}
	resp, err := strm.Read()
	if err != nil {
		return err
	}
	if resp == nil {
		return stream.ErrUnexpectedEOF
	}
	switch rsp := resp.(type) {
	case *Iq:
		if rsp.Type != nil && *rsp.Type == IqTypeResult && rsp.Payload != nil {
			if newt, ok := rsp.Payload.(*BindFeature); ok {
				if newt.Jid != nil {
					strm.Jid = newt.Jid
					return nil
				}
			} else {
				return stream.ErrMalformedProtocol
			}
		}
	case *stream.Error:
		return rsp
	}
	return stream.ErrMalformedProtocol
}
コード例 #2
0
ファイル: tls_feature.go プロジェクト: oxpa/bullxmpp
func (t *TLSFeature) Negotate(strm *stream.Stream) error {
	if err := strm.Send(t); err != nil {
		return err
	}
	data, err := strm.Read()
	if err != nil {
		return err
	}
	if data == nil {
		return stream.ErrUnexpectedEOF
	}
	switch resp := data.(type) {
	case *starttls.Proceed:
		return turnTLS(strm)
	case *starttls.Failure:
		return resp
	}
	return stream.ErrMalformedProtocol
}
コード例 #3
0
ファイル: sasl_feature.go プロジェクト: oxpa/bullxmpp
func sasl_PLAIN(strm *stream.Stream, password string) error {
	var err error
	data := "\x00" + strm.Jid.Node + "\x00" + password
	method := "PLAIN"
	if err = strm.Send(&sasl.Auth{&method, base64_encode(data)}); err != nil {
		return err
	}
	resp, err := strm.Read()
	if err != nil {
		return err
	}
	switch resp := resp.(type) {
	case *sasl.Success:
		return nil
	case *sasl.Failure:
		return resp
	case *stream.Error:
		return resp
	}
	return stream.ErrMalformedProtocol
}
コード例 #4
0
ファイル: session_feature.go プロジェクト: oxpa/bullxmpp
func (t *SessionFeature) Negotate(strm *stream.Stream) error {
	id := strconv.Itoa(rand.Intn(1000))
	typ := IqTypeSet
	iq := Iq{From: strm.Jid, Id: &id, Payload: t, Type: &typ}
	if err := strm.Send(&iq); err != nil {
		return err
	}
	resp, err := strm.Read()
	if err != nil {
		return err
	}
	if resp == nil {
		return stream.ErrUnexpectedEOF
	}
	switch resp := resp.(type) {
	case *Iq:
		if resp.Type != nil && *resp.Type == IqTypeResult {
			return nil
		}
	case *stream.Error:
		return resp
	}
	return stream.ErrMalformedProtocol
}
コード例 #5
0
ファイル: sasl_feature.go プロジェクト: oxpa/bullxmpp
func sasl_DIGEST_MD5(strm *stream.Stream, password string) error {
	var err error
	var resp interface{}
	method := "DIGEST-MD5"
	if err = strm.Send(&sasl.Auth{&method, []byte{}}); err != nil {
		return err
	}
	resp, err = strm.Read()
	if err != nil {
		return err
	}
	if resp == nil {
		return stream.ErrUnexpectedEOF
	}
	switch rsp := resp.(type) {
	case *sasl.Challenge:
		var t []byte
		if t, err = base64.StdEncoding.DecodeString(string(rsp.Data)); err != nil {
			return err
		}
		var tokens map[string]string
		if tokens, err = get_map(t); err != nil {
			return err
		}
		nonce := tokens["nonce"]
		cnonce := make_cnonce()
		nc := "00000001"
		digest_uri := "xmpp/" + strm.Jid.Domain
		realm := strm.Jid.Domain
		qop_list := strings.Split(tokens["qop"], ",")
		exists := false
		for _, x := range qop_list {
			if x == "auth" {
				exists = true
				break
			}
		}
		if !exists {
			return errors.New("No known qop method")
		}
		qop := "auth"
		a0 := md5_sum([]byte(strm.Jid.Node + ":" + realm + ":" + password))
		a1 := string(a0) + ":" + nonce + ":" + cnonce
		a2 := "AUTHENTICATE:" + digest_uri
		t = []byte(hex(md5_sum([]byte(a1))) + ":" + nonce + ":" + nc + ":" + cnonce +
			":" + qop + ":" + hex(md5_sum([]byte(a2))))
		response := hex(md5_sum(t))
		response = `charset=utf-8,username="******",realm="` + realm +
			`",nonce=` + nonce + ",cnonce=" + cnonce + ",nc=" + nc +
			`,qop="` + qop + `",digest-uri="` + digest_uri + `",response=` + response
		if err = strm.Send(&sasl.Response{base64_encode(response)}); err != nil {
			return err
		}
		resp, err = strm.Read()
		if err != nil {
			return err
		}
		if resp == nil {
			return stream.ErrUnexpectedEOF
		}
		switch rsp := resp.(type) {
		case *sasl.Challenge:
			if err = strm.Send(&sasl.Response{}); err != nil {
				return err
			}
			if resp, err = strm.Read(); err != nil {
				return err
			}
			if resp == nil {
				return stream.ErrUnexpectedEOF
			}
			switch rsp := resp.(type) {
			case *sasl.Success:
				return nil
			case *sasl.Failure:
				return rsp
			case *stream.Error:
				return rsp
			}
		case *sasl.Failure:
			return rsp
		case *stream.Error:
			return rsp
		}
	}
	return stream.ErrMalformedProtocol
}
コード例 #6
0
ファイル: sasl_feature.go プロジェクト: oxpa/bullxmpp
func sasl_SCRAM_SHA_1(strm *stream.Stream, password string) error {
	var err error
	var resp interface{}
	cnonce := make_cnonce()
	clientFirstMessageBare := "n=" + strm.Jid.Node + ",r=" + cnonce
	data := "n,," + clientFirstMessageBare
	method := "SCRAM-SHA-1"
	if err = strm.Send(&sasl.Auth{&method, base64_encode(data)}); err != nil {
		return err
	}
	if resp, err = strm.Read(); err != nil {
		return err
	}
	if resp == nil {
		return stream.ErrUnexpectedEOF
	}
	switch rsp := resp.(type) {
	case *sasl.Challenge:
		var t []byte
		if t, err = base64.StdEncoding.DecodeString(string(rsp.Data)); err != nil {
			return err
		}
		ch := string(t)
		serverFirstMessage := ch
		tokens := scram_attributes(ch)
		var salt []byte
		if salt, err = base64.StdEncoding.DecodeString(tokens["s"]); err != nil {
			return err
		}
		i, _ := strconv.Atoi(tokens["i"])
		r := tokens["r"]
		saltedpassword := scram_Hi([]byte(jid.Resourceprep(password)), salt, i)
		clientKey := scram_HMAC(saltedpassword, []byte("Client Key"))
		storedKey := scram_H(clientKey)
		clientFinalMessageWithoutProof := "c=biws,r=" + r
		authMessage := []byte(clientFirstMessageBare + "," + serverFirstMessage + "," +
			clientFinalMessageWithoutProof)
		clientSignature := scram_HMAC(storedKey, []byte(authMessage))
		clientProof := scram_XOR(clientKey, clientSignature)
		serverKey := scram_HMAC(saltedpassword, []byte("Server Key"))
		serverSignature := scram_HMAC(serverKey, authMessage)
		response := clientFinalMessageWithoutProof + ",p=" + string(base64_encode(string(clientProof)))
		if err = strm.Send(&sasl.Response{base64_encode(response)}); err != nil {
			return err
		}
		if resp, err = strm.Read(); err != nil {
			return err
		}
		if resp == nil {
			return stream.ErrUnexpectedEOF
		}
		switch rsp := resp.(type) {
		case *sasl.Success:
			var t []byte
			if t, err = base64.StdEncoding.DecodeString(string(rsp.Data)); err != nil {
				return err
			}
			tokens = scram_attributes(string(t))
			v := tokens["v"]
			if t, err = base64.StdEncoding.DecodeString(v); err != nil {
				return err
			}
			if string(t) != string(serverSignature) {
				return errors.New("Server Signature mismatch")
			}

			return nil
		case *sasl.Failure:
			return rsp
		case *stream.Error:
			return rsp
		}
	case *sasl.Failure:
		return rsp
	case *stream.Error:
		return rsp
	}
	return stream.ErrMalformedProtocol
}