Example #1
0
func (this *Server) handleConnection(out net.Conn, ip net.IP, port int) {

	req, err := msg.DecodeMessage(out)
	if err != nil {
		log.Println(err)
		return
	}

	conn := &Connection{Req: req, Out: out, Realm: Realm}

	switch req.Type() {
	case msg.Binding | msg.Request:

		if this.auth == nil {
			log.Println("Binding to address:", ip, port)
			res := msg.NewResponse(msg.Success, req)
			xorAddr := msg.NewXORAddress(ip, port, res.Header())
			res.AddAttribute(xorAddr)

			out.Write(res.EncodeMessage())

			this.conns <- conn
			return
		}

		if this.Validate(conn) {
			conn.Write(msg.NewResponse(msg.Success, req))
			this.conns <- conn
		}

	default: // Unrecognized messages
		this.conns <- conn
	}
}
Example #2
0
// Sends a request where you expect to get a response back
func (this *Client) SendReqRes(req *msg.Message) (*Connection, error) {

	conn, err := net.DialTimeout("tcp", this.server, 15*time.Second)
	if err != nil {
		log.Println("Failed to create connection: ", err)
		return nil, err
	}

	laddr := conn.LocalAddr()
	ip := laddr.(*net.TCPAddr).IP
	port := laddr.(*net.TCPAddr).Port

	xor := msg.NewXORAddress(ip, port, req.Header())
	req.AddAttribute(xor)

	if this.nonce != nil && this.realm != nil {
		req.AddAttribute(this.user)
		req.AddAttribute(this.realm)
		req.AddAttribute(this.nonce)

		username := this.user.String()
		realm := this.realm.String()

		integrity := msg.NewIntegrityAttr(username, this.password, realm, req)
		req.AddAttribute(integrity)
	}

	conn.Write(req.EncodeMessage())

	res, err := msg.DecodeMessage(conn)

	if err != nil {
		conn.Close()
		return nil, err
	}

	if eattr, err := res.Attribute(msg.ErrorCode); err == nil {
		if code, err := eattr.(*msg.StunError).Code(); err == nil {
			log.Println("error code", code)
			switch code {

			case msg.StaleNonce:
				log.Println("Stale Nonce, calling authenticate...")
				return this.Authenticate(res, req)

			case msg.Unauthorized:
				log.Println("unauthorized")

				if _, err := req.Attribute(msg.MessageIntegrity); err == nil {
					conn.Close()
					return nil, errors.New("Invalid credentials")
				} else {
					return this.Authenticate(res, req)
				}
			}
		}
	}

	return &Connection{res, conn}, nil
}
Example #3
0
func (this *Connection) Write(res *msg.Message) {

	xorAddr := msg.NewXORAddress(this.IP(), this.Port(), res.Header())
	res.AddAttribute(xorAddr)

	if this.HasAuth {
		i := msg.NewIntegrityAttr(this.User, this.Passwd, this.Realm, this.Req)
		res.AddAttribute(i)
	}

	this.Out.Write(res.EncodeMessage())
}