Code

first hack at in-band registration
authorishmal <ishmal@users.sourceforge.net>
Sun, 21 May 2006 03:51:47 +0000 (03:51 +0000)
committerishmal <ishmal@users.sourceforge.net>
Sun, 21 May 2006 03:51:47 +0000 (03:51 +0000)
src/pedro/pedrogui.cpp
src/pedro/pedrogui.h
src/pedro/pedroxmpp.cpp
src/pedro/pedroxmpp.h

index e2ab05a2e373543613dd3aef27fc53e951bd80c6..cbfea0938daee5df99b4024e6738b3c37be60f83 100644 (file)
@@ -428,7 +428,7 @@ bool Roster::buttonPressCallback(GdkEventButton* event)
 bool Roster::doSetup()
 {
     set_size_request(200,200);
-    
+
     pixbuf_available = Gdk::Pixbuf::create_from_inline(
                       sizeof(icon_available), icon_available, false);
     pixbuf_away     = Gdk::Pixbuf::create_from_inline(
@@ -1145,7 +1145,7 @@ bool ConnectDialog::doSetup()
     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
 
-    table.resize(5, 2);
+    table.resize(6, 2);
     get_vbox()->pack_start(table);
 
     parent.client.setHost("gristle.org");
@@ -1184,6 +1184,11 @@ bool ConnectDialog::doSetup()
     resourceField.set_text(parent.client.getResource());
     table.attach(resourceField, 1, 2, 4, 5);
 
+    registerLabel.set_text("Register");
+    table.attach(registerLabel, 0, 1, 5, 6);
+    registerButton.set_active(false);
+    table.attach(registerButton, 1, 2, 5, 6);
+
     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
     add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
 
@@ -1943,6 +1948,7 @@ void PedroGui::connectCallback()
         client.setUsername(dialog.getUser());
         client.setPassword(dialog.getPass());
         client.setResource(dialog.getResource());
+        client.setDoRegister(dialog.getRegister());
         client.connect();
         }
 }
index b42ee7ab815d528c955b930468ab002428866e37..2605a894e1e003b4e150fb6f2ce531eda25eb7ae 100644 (file)
@@ -104,7 +104,7 @@ private:
     Glib::RefPtr<Gdk::Pixbuf> pixbuf_error;
     Glib::RefPtr<Gdk::Pixbuf> pixbuf_offline;
     Glib::RefPtr<Gdk::Pixbuf> pixbuf_xa;
-    
+
     class RosterColumns : public Gtk::TreeModel::ColumnRecord
     {
     public:
@@ -379,6 +379,8 @@ public:
        { return passField.get_text(); }
    DOMString getResource()
        { return resourceField.get_text(); }
+   bool getRegister()
+       { return registerButton.get_active(); }
 
 private:
 
@@ -387,18 +389,20 @@ private:
 
     bool doSetup();
 
-    Gtk::Table table;
-
-    Gtk::Label hostLabel;
-    Gtk::Entry hostField;
-    Gtk::Label portLabel;
-    Gtk::SpinButton portSpinner;
-    Gtk::Label userLabel;
-    Gtk::Entry userField;
-    Gtk::Label passLabel;
-    Gtk::Entry passField;
-    Gtk::Label resourceLabel;
-    Gtk::Entry resourceField;
+    Gtk::Table       table;
+
+    Gtk::Label       hostLabel;
+    Gtk::Entry       hostField;
+    Gtk::Label       portLabel;
+    Gtk::SpinButton  portSpinner;
+    Gtk::Label       userLabel;
+    Gtk::Entry       userField;
+    Gtk::Label       passLabel;
+    Gtk::Entry       passField;
+    Gtk::Label       resourceLabel;
+    Gtk::Entry       resourceField;
+    Gtk::Label       registerLabel;
+    Gtk::CheckButton registerButton;
 
     PedroGui &parent;
 };
index f5ce69e0b04a7438c7db3e93790e3dce373e717c..7ee3d599e0be1354ad42b0f6547555c7419449f4 100644 (file)
@@ -2393,6 +2393,7 @@ void XmppClient::assign(const XmppClient &other)
     password      = other.password;
     resource      = other.resource;
     connected     = other.connected;
+    doRegister    = other.doRegister;
     groupChats    = other.groupChats;
 }
 
@@ -2402,6 +2403,7 @@ void XmppClient::init()
     sock          = new TcpSocket();
     msgId         = 0;
     connected     = false;
+    doRegister    = false;
 
     for (int i=0 ; i<outputStreamCount ; i++)
         {
@@ -2816,7 +2818,7 @@ bool XmppClient::processPresence(Element *root)
                 groupChatUserAdd(fromGid, fromNick, "");
                 }
             else
-                groupChatUserDelete(fromGid, fromNick);               
+                groupChatUserDelete(fromGid, fromNick);
             groupChatUserShow(fromGid, fromNick, show);
             XmppEvent event(XmppEvent::EVENT_MUC_PRESENCE);
             event.setGroup(fromGid);
@@ -2833,7 +2835,7 @@ bool XmppClient::processPresence(Element *root)
         DOMString dummy;
         parseJid(fullJid, shortJid, dummy);
         rosterShow(shortJid, show); //users in roster do not have resource
-        
+
         XmppEvent event(XmppEvent::EVENT_PRESENCE);
         event.setFrom(fullJid);
         event.setPresence(presence);
@@ -3496,7 +3498,76 @@ bool XmppClient::saslAuthenticate()
 }
 
 
+/**
+ * Perform JEP-077 In-Band Registration
+ */
+bool XmppClient::inBandRegistration()
+{
+    Parser parser;
+
+    char *fmt =
+     "<iq type='get' id='reg1'>"
+         "<query xmlns='jabber:iq:register'/>"
+         "</iq>\n";
+    if (!write(fmt))
+        return false;
+
+    DOMString recbuf = readStanza();
+    Element *elem = parser.parse(recbuf);
+    elem->print();
+
+    //# does the entity send the "instructions" tag?
+    bool hasInstructions =
+         (elem->findElements("instructions").size() > 0);
+    delete elem;
+
+    if (!hasInstructions)
+        {
+        error("server did not offer registration");
+        return false;
+        }
+
+    fmt =
+     "<iq type='set' id='reg2'>"
+         "<query xmlns='jabber:iq:register'>"
+         "<username>%s</username>"
+         "<password>&s</password>"
+         "</query>"
+         "</iq>\n";
+    if (!write(fmt, toXml(username).c_str(), toXml(password).c_str() ))
+        return false;
+
+
+    recbuf = readStanza();
+    elem = parser.parse(recbuf);
+    elem->print();
+
+    std::vector<Element *> list = elem->findElements("error");
+    if (list.size()>0)
+        {
+        Element *errElem = list[0];
+        DOMString code = errElem->getAttribute("code");
+        DOMString errMsg = "Registration error. ";
+        if (code == "409")
+            {
+            errMsg.append("conflict with existing user name");
+            }
+        if (code == "406")
+            {
+            errMsg.append("some registration information was not provided");
+            }
+        error((char *)errMsg.c_str());
+        delete elem;
+        return false;
+        }
+
+    delete elem;
+
+    XmppEvent evt(XmppEvent::EVENT_REGISTRATION_NEW);
+    dispatchXmppEvent(evt);
 
+    return true;
+}
 
 
 bool XmppClient::createSession()
@@ -3510,6 +3581,13 @@ bool XmppClient::createSession()
         return false;
         }
 
+    //register, if user requests
+    if (doRegister)
+        {
+        if (!inBandRegistration())
+            return false;
+        }
+
     char *fmt =
      "<stream:stream "
           "to='%s' "
@@ -3794,7 +3872,7 @@ void XmppClient::rosterShow(const DOMString &jid, const DOMString &show)
     DOMString theShow = show;
     if (theShow == "")
         theShow = "available";
-    
+
     std::vector<XmppUser>::iterator iter;
     for (iter=roster.begin() ; iter != roster.end() ; iter++)
         {
@@ -4334,6 +4412,8 @@ int XmppClient::inputStreamOpen(const DOMString &fromJid, const DOMString &strea
     return streamNr;
 }
 
+
+
 /**
  *
  */
@@ -4772,7 +4852,7 @@ DOMString XmppGroupChat::getGroupJid()
 }
 
 
-void XmppGroupChat::userAdd(const DOMString &nick, 
+void XmppGroupChat::userAdd(const DOMString &nick,
                             const DOMString &jid)
 {
     std::vector<XmppUser>::iterator iter;
@@ -4785,7 +4865,7 @@ void XmppGroupChat::userAdd(const DOMString &nick,
     userList.push_back(user);
 }
 
-void XmppGroupChat::userShow(const DOMString &nick, 
+void XmppGroupChat::userShow(const DOMString &nick,
                              const DOMString &show)
 {
     DOMString theShow = show;
index d938a25fd76dfc6830b2e6d8c3dc21284f16ab69..74985bfa24b01f96cbe6fdc70409f354722f7bb8 100644 (file)
@@ -97,6 +97,7 @@ typedef enum
     EVENT_CONNECTED,
     EVENT_DISCONNECTED,
     EVENT_PRESENCE,
+    EVENT_REGISTRATION_NEW,
     EVENT_ROSTER,
     EVENT_MESSAGE,
     EVENT_MUC_JOIN,
@@ -552,6 +553,10 @@ public:
      */
     virtual bool write(char *fmt, ...);
 
+    //#######################
+    //# V A R I A B L E S
+    //#######################
+
     /**
      *
      */
@@ -633,12 +638,33 @@ public:
      */
     virtual DOMString getJid()
         { return jid; }
+
     /**
      *
      */
     virtual int getMsgId()
         { return msgId++; }
 
+    /**
+     *
+     */
+    virtual void setDoRegister(bool val)
+        { doRegister = val; }
+
+
+    /**
+     *
+     */
+    virtual bool getDoRegister()
+        { return doRegister; }
+
+
+
+    //#######################
+    //# P R O C E S S I N G
+    //#######################
+
+
     /**
      *
      */
@@ -689,7 +715,7 @@ public:
      *
      */
     virtual void rosterShow(const DOMString &jid, const DOMString &show);
-    
+
     //#######################
     //# CHAT (individual)
     //#######################
@@ -934,8 +960,12 @@ private:
 
     bool iqAuthenticate(const DOMString &streamId);
 
+    bool inBandRegistration();
+
     bool keepGoing;
 
+    bool doRegister;
+
     static const int writeBufLen = 2048;
 
     unsigned char writeBuf[writeBufLen];
@@ -994,7 +1024,7 @@ public:
     /**
      *
      */
-    virtual void userAdd(const DOMString &nick, 
+    virtual void userAdd(const DOMString &nick,
                          const DOMString &jid);
     /**
      *