func (self *AuthElement) Handle(st stream.ServerStream, opts features.Options) error { mechs := map[string]Handler{} // create this on stack - no garbage for _, mech := range opts.(AuthConfig) { if handler, ok := mechanism_handlers[mech]; ok { mechs[mech] = handler } } if handler := mechs[self.Mechanism]; handler != nil { if err := handler(self, st); err != nil { log.Println("Authorization failed:", err) if err := st.WriteElement(NewFailute(NotAuthorized{})); err != nil { return err } return err } } else { if err := st.WriteElement(NewFailute(InvalidMechanism{})); err != nil { return err } return fmt.Errorf("No handler for mechanism %v", self.Mechanism) } return nil }
func (self *BindElement) Handle(strm stream.ServerStream, opts features.Options) error { request_id := opts.(*iq.IQElement) // FIXME(goxmpp): 2014-04-03: auth check, state presence check, resource check required var state *BindState strm.State().Get(&state) if state.VerifyResource(self.Resource) { state.Resource = self.Resource } else { // TODO(goxmpp): 2014-04-03 } var authState *auth.AuthState strm.State().Get(&authState) strm.SetClientJID(authState.UserName + "@" + strm.ServerName() + "/" + state.Resource) log.Printf("Bound to JID: %#v", strm.ClientJID()) // TODO(goxmpp): 2014-04-03: might be easier to just use original IQ? response_iq := iq.NewIQElement() response_iq.Type = "result" response_iq.ID = request_id.ID response_iq.AddElement(&BindElement{JID: strm.ClientJID()}) if err := strm.WriteElement(response_iq); err != nil { return err } return nil }
func (s *StartTLSElement) Handle(st stream.ServerStream, opts features.Options) error { conf := opts.(*startTLSConf) cert, err := tls.LoadX509KeyPair(conf.PEMPath, conf.KeyPath) if err != nil { log.Println("Could not load keys:", err) return err } config := &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.VerifyClientCertIfGiven, Rand: rand.Reader, } err = st.UpdateRW(func(srwc io.ReadWriteCloser) (io.ReadWriteCloser, error) { if conn, ok := srwc.(net.Conn); ok { tls_conn := tls.Server(conn, config) // Once we inialized - let client proceed if err := st.WriteElement(&ProceedElement{}); err != nil { return nil, err } // Now do a handshake if err := tls_conn.Handshake(); err != nil { log.Println("TLS Handshake error:", err) return nil, err } return tls_conn, nil } return nil, errors.New("Wrong ReadWriteCloser, expected connection") }) if err != nil { log.Println("Could not replace connection", err) return err } state := NewStartTLSState() state.Started = true st.State().Push(state) st.ReOpen() return nil }
func (self *SessionElement) Handle(strm stream.ServerStream, opts features.Options) error { request_id := opts.(*iq.IQElement) // FIXME(goxmpp): 2014-04-04: auth check, state presence check, resource check required var state *SessionState if err := strm.State().Get(&state); err != nil { state = &SessionState{} strm.State().Push(state) } state.Active = true log.Printf("Session opened") // TODO(goxmpp): 2014-04-03: might be easier to just use original IQ? response_iq := iq.NewIQElement() response_iq.Type = "result" response_iq.ID = request_id.ID if err := strm.WriteElement(response_iq); err != nil { return err } return nil }
func (c *compressElement) Handle(s stream.ServerStream, opts features.Options) error { var compressor Compressor conf := opts.(CompressionConfig) if _, ok := conf[c.Method]; ok { if compr, ok := Methods[c.Method]; ok { compressor = compr } } if compressor == nil { if err := s.WriteElement(&MethodNotSupportedError{}); err != nil { return err } return fmt.Errorf("Unsupported compression method requested") } var state *CompressState if err := s.State().Get(&state); err != nil { state = NewCompressState() s.State().Push(state) } state.Compressed = true if err := s.WriteElement(&CompressionSuccess{}); err != nil { return err } if err := swapStreamRW(s, compressor); err != nil { if err := s.WriteElement(&ProcessingFailedError{}); err != nil { return err } return err } s.ReOpen() return nil }