コード例 #1
0
ファイル: jid.py プロジェクト: linusyang/pjabberd
 def __init__(self, jid, use_id=False):
     """Tries to create a JID out of 'jid'. Raises an exception if the JID
     is malformed.
     """
     if use_id:
         jid_number = jid
         res = None
         try:
             c = DBautocommit().cursor()
             c.execute("SELECT jid FROM jids WHERE id = %d" %
                       (jid_number))
             res = c.fetchone()
         except:
             logging.debug('JID: init from number failed')
         if res and len(res) > 0:
             jid = res[0]
         else:
             jid = ''
     m = JID.jidre.match(jid)
     if not m:
         raise Exception, '[JID] %s is not a proper JID' % jid
 
     self.node = m.group(2)
     self.domain = m.group(3)
     self.resource = m.group(5)
コード例 #2
0
ファイル: roster.py プロジェクト: Kiesco08/pjabberd
    def getContactInfo(self, cjid, includeGroups=True):
        """Returns information about a contact with JID cjid in this user's
        roster. Returns a RosterItem if the contact exists in the roster;
        False otherwise.
        If includeGroups is True, groups are added to the RosterItem as well.
        """
        con = DBautocommit()
        c = con.cursor()

        c.execute("SELECT roster.contactid, roster.name, roster.subscription\
                   FROM roster\
                       JOIN jids ON jids.id = roster.contactid\
                   WHERE userid = ? AND jids.jid = ?", (self.uid, cjid))
        res = c.fetchone()
        if res:
            cid = res[0]
            name = res[1]
            sub = res[2]
        else:
            c.close()
            return False

        if includeGroups:
            # get the groups
            c.execute("SELECT rgs.name\
                       FROM rostergroups AS rgs\
                           JOIN rostergroupitems AS rgi ON rgi.groupid = rgs.groupid\
                       WHERE rgs.userid = ? AND rgi.contactid = ?", (self.uid, cid))
            groups = [group['name'] for group in c]

            return RosterItem(cjid, name, sub, groups, cid)
        else:

            return RosterItem(cjid, name, sub, id=cid)
コード例 #3
0
ファイル: jid.py プロジェクト: Kiesco08/pjabberd
 def exists(self):
     """Returns True if this JID exists in the DB"""
     c = DBautocommit().cursor()
     c.execute("SELECT jid FROM jids WHERE jid = ? AND password != ''",
               (self.getBare(),))
     res = c.fetchone()
     if res:
         return True
     else:
         return False
コード例 #4
0
 def exists(self):
     """Returns True if this JID exists in the DB"""
     c = DBautocommit().cursor()
     c.execute("SELECT jid FROM jids WHERE jid = ? AND password != ''",
               (self.getBare(), ))
     res = c.fetchone()
     if res:
         return True
     else:
         return False
コード例 #5
0
ファイル: roster.py プロジェクト: Kiesco08/pjabberd
    def getSubscription(self, cid):
        """Returns the subscription id of this user's contact with id cid"""
        con = DBautocommit()
        c = con.cursor()
        c.execute("SELECT subscription FROM roster\
                   WHERE userid = ? AND contactid = ?", (self.uid, cid))
        res = c.fetchone()
        if res:
            sub = res[0]

            return sub
        else:
            raise Exception, "No such contact in roster"
コード例 #6
0
    def getSubscription(self, cid):
        """Returns the subscription id of this user's contact with id cid"""
        con = DBautocommit()
        c = con.cursor()
        c.execute(
            "SELECT subscription FROM roster\
                   WHERE userid = ? AND contactid = ?", (self.uid, cid))
        res = c.fetchone()
        if res:
            sub = res[0]

            return sub
        else:
            raise Exception, "No such contact in roster"
コード例 #7
0
ファイル: jid.py プロジェクト: linusyang/pjabberd
 def exists(self):
     """Returns True if this JID exists in the DB"""
     res = None
     try:
         c = DBautocommit().cursor()
         c.execute("SELECT jid FROM jids WHERE jid = ? AND password != ''",
                   (self.getBare(),))
         res = c.fetchone()
     except:
         logging.debug('JID: check existence failed')
     if res:
         return True
     else:
         return False
コード例 #8
0
ファイル: jid.py プロジェクト: linusyang/pjabberd
 def getNumId(self):
     """Returns this JID's database numeric ID"""
     res = None
     try:
         c = DBautocommit().cursor()
         c.execute("SELECT id FROM jids WHERE jid = ?",
                   (self.getBare(),))
         res = c.fetchone()
     except:
         logging.debug('JID: get numeric ID failed')
     if res and len(res) > 0:
         return res[0]
     else:
         return -1
コード例 #9
0
ファイル: roster.py プロジェクト: Kiesco08/pjabberd
    def getSubPrimaryName(self, cid):
        """Gets the primary name of a subscription for this user and this
        contact suitable for including in the subscription attribute of a
        roster's item element.
        """
        con = DBautocommit()
        c = con.cursor()
        c.execute("SELECT subscription FROM roster\
                       WHERE roster.userid = ? AND roster.contactid = ?", (self.uid, cid))
        res = c.fetchone()
        if res is None:
            sub = 'none'
        else:
            sub = Subscription.getPrimaryNameFromState(res[0])

        return sub
コード例 #10
0
    def handle(self, username, digest):
        con = DBautocommit()
        c = con.cursor()
        c.execute("SELECT password FROM jids WHERE \
            jid = ?", (username + '@%s' % self.msg.conn.server.hostname, ))
        res = c.fetchone()
        if res:
            password = res[0]
        else:
            c.close()
            con.close()
            raise IQAuthError
        c.close()
        con.close()

        s = sha1()
        s.update(self.streamid + password)
        hashtext = s.hexdigest()

        if hashtext == digest:
            d = self.msg.conn.data
            d['user']['jid'] = '%s@%s' % (username,
                                          self.msg.conn.server.hostname)

            # record the JID for local delivery
            self.msg.conn.server.conns[self.msg.conn.id] = (JID(
                d['user']['jid']), self.msg.conn)

            self.msg.conn.parser.resetParser()
            return
        else:
            raise IQAuthError
コード例 #11
0
    def getSubPrimaryName(self, cid):
        """Gets the primary name of a subscription for this user and this
        contact suitable for including in the subscription attribute of a
        roster's item element.
        """
        con = DBautocommit()
        c = con.cursor()
        c.execute(
            "SELECT subscription FROM roster\
                       WHERE roster.userid = ? AND roster.contactid = ?",
            (self.uid, cid))
        res = c.fetchone()
        if res is None:
            sub = 'none'
        else:
            sub = Subscription.getPrimaryNameFromState(res[0])

        return sub
コード例 #12
0
ファイル: roster.py プロジェクト: Kiesco08/pjabberd
    def __init__(self, jid):
        """Initializes the roster object, but does not fetch any
        roster-specific data from the DB. It checks if the jid
        exists in the roster and raises an exception if it doesn't.

        jid -- textual representation of a bare JID.
        """
        self.items = {}
        self.jid = jid

        con = DBautocommit()
        c = con.cursor()
        # get our own id
        c.execute("SELECT id FROM jids WHERE jid = ?", (self.jid,))
        res = c.fetchone()
        if res is None:
            raise Exception, "No record of this JID in the DB"

        self.uid = res[0]
コード例 #13
0
ファイル: roster.py プロジェクト: Kiesco08/pjabberd
    def getPresenceSubscriptions(self):
        """Returns a list of JIDs of contacts of this user to whom the user
        is subscribed (to/both).
        """
        con = DBautocommit()
        c = con.cursor()
        c.execute("SELECT jids.jid\
                   FROM roster\
                   JOIN jids ON jids.id = roster.contactid\
                   WHERE roster.userid = ? AND\
                       roster.subscription IN (?, ?, ?)",
                       (self.uid, Subscription.TO,
                        Subscription.TO_PENDING_IN, Subscription.BOTH))
        jids = []
        res = c.fetchall()
        for row in res:
            jids.append(row[0])

        return jids
コード例 #14
0
ファイル: roster.py プロジェクト: Kiesco08/pjabberd
    def getPresenceSubscribers(self):
        """Returns a list of JIDs of contacts of this user who are interested
        in the user's presence info (from/both).
        """
        con = DBautocommit()
        c = con.cursor()
        c.execute("SELECT jids.jid\
                   FROM roster\
                   JOIN jids ON jids.id = roster.contactid\
                   WHERE roster.userid = ? AND\
                       roster.subscription IN (?, ?, ?)",
                       (self.uid, Subscription.FROM,
                        Subscription.FROM_PENDING_OUT, Subscription.BOTH))
        jids = []
        res = c.fetchall()
        for row in res:
            jids.append(row[0])

        return jids
コード例 #15
0
    def __init__(self, jid):
        """Initializes the roster object, but does not fetch any
        roster-specific data from the DB. It checks if the jid
        exists in the roster and raises an exception if it doesn't.

        jid -- textual representation of a bare JID.
        """
        self.items = {}
        self.jid = jid

        con = DBautocommit()
        c = con.cursor()
        # get our own id
        c.execute("SELECT id FROM jids WHERE jid = ?", (self.jid, ))
        res = c.fetchone()
        if res is None:
            raise Exception, "No record of this JID in the DB"

        self.uid = res[0]
コード例 #16
0
    def getPresenceSubscribers(self):
        """Returns a list of JIDs of contacts of this user who are interested
        in the user's presence info (from/both).
        """
        con = DBautocommit()
        c = con.cursor()
        c.execute(
            "SELECT jids.jid\
                   FROM roster\
                   JOIN jids ON jids.id = roster.contactid\
                   WHERE roster.userid = ? AND\
                       roster.subscription IN (?, ?, ?)",
            (self.uid, Subscription.FROM, Subscription.FROM_PENDING_OUT,
             Subscription.BOTH))
        jids = []
        res = c.fetchall()
        for row in res:
            jids.append(row[0])

        return jids
コード例 #17
0
    def getPresenceSubscriptions(self):
        """Returns a list of JIDs of contacts of this user to whom the user
        is subscribed (to/both).
        """
        con = DBautocommit()
        c = con.cursor()
        c.execute(
            "SELECT jids.jid\
                   FROM roster\
                   JOIN jids ON jids.id = roster.contactid\
                   WHERE roster.userid = ? AND\
                       roster.subscription IN (?, ?, ?)",
            (self.uid, Subscription.TO, Subscription.TO_PENDING_IN,
             Subscription.BOTH))
        jids = []
        res = c.fetchall()
        for row in res:
            jids.append(row[0])

        return jids
コード例 #18
0
ファイル: auth_mechanisms.py プロジェクト: Kiesco08/pjabberd
    def handle(self, username, digest):
        con = DBautocommit()
        c = con.cursor()
        c.execute("SELECT password FROM jids WHERE \
            jid = ?", (username + '@%s' % self.msg.conn.server.hostname,))
        res = c.fetchone()
        if res:
            password = res[0]
        else:
            c.close()
            con.close()
            raise IQAuthError
        c.close()
        con.close()

        s = sha1()
        s.update(self.streamid + password)
        hashtext = s.hexdigest()

        if hashtext == digest:
            d = self.msg.conn.data
            d['user']['jid'] = '%s@%s' % (username,
                                          self.msg.conn.server.hostname)

            # record the JID for local delivery
            self.msg.conn.server.conns[self.msg.conn.id] = (JID(d['user']['jid']),
                                                            self.msg.conn)

            self.msg.conn.parser.resetParser()
            return
        else:
            raise IQAuthError
コード例 #19
0
    def getContactInfo(self, cjid, includeGroups=True):
        """Returns information about a contact with JID cjid in this user's
        roster. Returns a RosterItem if the contact exists in the roster;
        False otherwise.
        If includeGroups is True, groups are added to the RosterItem as well.
        """
        con = DBautocommit()
        c = con.cursor()

        c.execute(
            "SELECT roster.contactid, roster.name, roster.subscription\
                   FROM roster\
                       JOIN jids ON jids.id = roster.contactid\
                   WHERE userid = ? AND jids.jid = ?", (self.uid, cjid))
        res = c.fetchone()
        if res:
            cid = res[0]
            name = res[1]
            sub = res[2]
        else:
            c.close()
            return False

        if includeGroups:
            # get the groups
            c.execute(
                "SELECT rgs.name\
                       FROM rostergroups AS rgs\
                           JOIN rostergroupitems AS rgi ON rgi.groupid = rgs.groupid\
                       WHERE rgs.userid = ? AND rgi.contactid = ?",
                (self.uid, cid))
            groups = [group['name'] for group in c]

            return RosterItem(cjid, name, sub, groups, cid)
        else:

            return RosterItem(cjid, name, sub, id=cid)
コード例 #20
0
    def handle(self, b64text):
        """Verify the username/password in response"""
        authtext = ''
        if b64text:
            try:
                authtext = fromBase64(b64text)
            except:
                raise SASLIncorrectEncodingError

            auth = authtext.split('\x00')

            if len(auth) != 3:
                raise SASLIncorrectEncodingError

            con = DBautocommit()
            c = con.cursor()
            c.execute("SELECT * FROM jids WHERE \
                jid = ? AND password = ?"                                         , (auth[1] + \
                                            '@' + self.msg.conn.server.hostname, auth[2]))
            res = c.fetchall()
            if len(res) == 0:
                c.close()
                con.close()
                raise SASLAuthError
            c.close()
            con.close()

        self.msg.conn.data['sasl']['complete'] = True
        self.msg.conn.data['sasl']['in-progress'] = False
        self.msg.conn.data['user']['jid'] = '%s@%s' % (
            auth[1], self.msg.conn.server.hostname)

        # record the JID for local delivery
        self.msg.conn.server.conns[self.msg.conn.id] = (JID(
            self.msg.conn.data['user']['jid']), self.msg.conn)

        self.msg.conn.parser.resetParser()

        return Element('success',
                       {'xmlns': 'urn:ietf:params:xml:ns:xmpp-sasl'})
コード例 #21
0
ファイル: auth_mechanisms.py プロジェクト: Kiesco08/pjabberd
    def handle(self, b64text):
        """Verify the username/password in response"""
        authtext = ''
        if b64text:
            try:
                authtext = fromBase64(b64text)
            except:
                raise SASLIncorrectEncodingError

            auth = authtext.split('\x00')

            if len(auth) != 3:
                raise SASLIncorrectEncodingError

            con = DBautocommit()
            c = con.cursor()
            c.execute("SELECT * FROM jids WHERE \
                jid = ? AND password = ?", (auth[1] + \
                                            '@' + self.msg.conn.server.hostname, auth[2]))
            res = c.fetchall()
            if len(res) == 0:
                c.close()
                con.close()
                raise SASLAuthError
            c.close()
            con.close()

        self.msg.conn.data['sasl']['complete'] = True
        self.msg.conn.data['sasl']['in-progress'] = False
        self.msg.conn.data['user']['jid'] = '%s@%s' % (auth[1], self.msg.conn.server.hostname)

        # record the JID for local delivery
        self.msg.conn.server.conns[self.msg.conn.id] = (JID(self.msg.conn.data['user']['jid']),
                                                        self.msg.conn)

        self.msg.conn.parser.resetParser()

        return Element('success',
                       {'xmlns' : 'urn:ietf:params:xml:ns:xmpp-sasl'})
コード例 #22
0
ファイル: auth_mechanisms.py プロジェクト: Kiesco08/pjabberd
    def handle(self, data=None):
        """Performs DIGEST-MD5 auth based on current state.

        data -- either None for initial challenge, base64-encoded text when
                the client responds to challenge 1, or the tree when the client
                responds to challenge 2.
        """

        # TODO: authz
        # TODO: subsequent auth

        qop = 'qop="auth"'
        charset = 'charset=utf-8'
        algo = 'algorithm=md5-sess'

        if self.state == SASLDigestMD5.INIT: # initial challenge
            self.nonce = generateId()
            self.state = SASLDigestMD5.SENT_CHALLENGE1

            nonce = 'nonce="%s"' % self.nonce
            realm = 'realm="%s"' % self.realm

            res = Element('challenge',
                          {'xmlns' : 'urn:ietf:params:xml:ns:xmpp-sasl'})
            res.text = base64.b64encode(','.join([realm, qop, nonce, charset, algo]))

            return res
        elif self.state == SASLDigestMD5.SENT_CHALLENGE1 and data:
            # response to client's reponse (ie. challenge 2)
            try:
                text = fromBase64(data)
            except:
                raise SASLIncorrectEncodingError

            pairs = self._parse(text)
            try:
                username = pairs['username']
                nonce = pairs['nonce']
                realm = pairs['realm']
                cnonce = pairs['cnonce']
                nc = pairs['nc']
                qop = pairs['qop']
                response = pairs['response']
                digest_uri = pairs['digest-uri']
            except KeyError:
                self._handleFailure()
                raise SASLAuthError

            self.username = username

            # authz is ignored for now
            if nonce != self.nonce or realm != self.realm \
                or int(nc, 16) != 1 or qop[0] != 'auth' or not response\
                or not digest_uri:
                self._handleFailure()
                raise SASLAuthError

            # fetch the password now
            con = DBautocommit()
            c = con.cursor()
            c.execute("SELECT password FROM jids WHERE \
                jid = ?", (username + '@%s' % self.msg.conn.server.hostname,))
            for row in c:
                password = row['password']
                break
            else:
                self._handleFailure()
                c.close()
                con.close()
                raise SASLAuthError
            c.close()
            con.close()

            # compute the digest as per RFC 2831
            a1 = "%s:%s:%s" % (H("%s:%s:%s" % (username, realm, password)),
                               nonce, cnonce)
            a2 = ":%s" % digest_uri
            a2client = "AUTHENTICATE:%s" % digest_uri

            digest = HEX(KD(HEX(H(a1)),
                            "%s:%s:%s:%s:%s" % (nonce, nc,
                                                  cnonce, "auth",
                                                  HEX(H(a2client)))))

            if digest == response:
                rspauth = HEX(KD(HEX(H(a1)),
                                 "%s:%s:%s:%s:%s" % (nonce, nc,
                                                       cnonce, "auth",
                                                       HEX(H(a2)))))

                self.state = SASLDigestMD5.SENT_CHALLENGE2

                res = Element('challenge',
                              {'xmlns' : 'urn:ietf:params:xml:ns:xmpp-sasl'})
                res.text = base64.b64encode(u"rspauth=%s" % rspauth)

                return res

            else:
                self._handleFailure()
                raise SASLAuthError
        elif self.state == SASLDigestMD5.SENT_CHALLENGE2 and isinstance(data, Element):
            # expect to get <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
            respInd = data.tag.find('{urn:ietf:params:xml:ns:xmpp-sasl}response')
            d = self.msg.conn.data
            if respInd != -1 and len(data) == 0:
                self.state = SASLDigestMD5.INIT
                d['sasl']['complete'] = True
                d['sasl']['in-progress'] = False
                d['user']['jid'] = '%s@%s' % (self.username,
                                            self.msg.conn.server.hostname)

                # record the JID for local delivery
                self.msg.conn.server.conns[self.msg.conn.id] = (JID(d['user']['jid']),
                                                                self.msg.conn)

                self.msg.conn.parser.resetParser()

                res = Element('success',
                              {'xmlns' : 'urn:ietf:params:xml:ns:xmpp-sasl'})
                return res
            else:
                self._handleFailure()
                raise SASLAuthError
        else:
            self._handleFailure()
            raise SASLAuthError
コード例 #23
0
    def handle(self, data=None):
        """Performs DIGEST-MD5 auth based on current state.

        data -- either None for initial challenge, base64-encoded text when
                the client responds to challenge 1, or the tree when the client
                responds to challenge 2.
        """

        # TODO: authz
        # TODO: subsequent auth

        qop = 'qop="auth"'
        charset = 'charset=utf-8'
        algo = 'algorithm=md5-sess'

        if self.state == SASLDigestMD5.INIT:  # initial challenge
            self.nonce = generateId()
            self.state = SASLDigestMD5.SENT_CHALLENGE1

            nonce = 'nonce="%s"' % self.nonce
            realm = 'realm="%s"' % self.realm

            res = Element('challenge',
                          {'xmlns': 'urn:ietf:params:xml:ns:xmpp-sasl'})
            res.text = base64.b64encode(','.join(
                [realm, qop, nonce, charset, algo]))

            return res
        elif self.state == SASLDigestMD5.SENT_CHALLENGE1 and data:
            # response to client's reponse (ie. challenge 2)
            try:
                text = fromBase64(data)
            except:
                raise SASLIncorrectEncodingError

            pairs = self._parse(text)
            try:
                username = pairs['username']
                nonce = pairs['nonce']
                realm = pairs['realm']
                cnonce = pairs['cnonce']
                nc = pairs['nc']
                qop = pairs['qop']
                response = pairs['response']
                digest_uri = pairs['digest-uri']
            except KeyError:
                self._handleFailure()
                raise SASLAuthError

            self.username = username

            # authz is ignored for now
            if nonce != self.nonce or realm != self.realm \
                or int(nc, 16) != 1 or qop[0] != 'auth' or not response\
                or not digest_uri:
                self._handleFailure()
                raise SASLAuthError

            # fetch the password now
            con = DBautocommit()
            c = con.cursor()
            c.execute(
                "SELECT password FROM jids WHERE \
                jid = ?", (username + '@%s' % self.msg.conn.server.hostname, ))
            for row in c:
                password = row['password']
                break
            else:
                self._handleFailure()
                c.close()
                con.close()
                raise SASLAuthError
            c.close()
            con.close()

            # compute the digest as per RFC 2831
            a1 = "%s:%s:%s" % (H("%s:%s:%s" %
                                 (username, realm, password)), nonce, cnonce)
            a2 = ":%s" % digest_uri
            a2client = "AUTHENTICATE:%s" % digest_uri

            digest = HEX(
                KD(
                    HEX(H(a1)), "%s:%s:%s:%s:%s" %
                    (nonce, nc, cnonce, "auth", HEX(H(a2client)))))

            if digest == response:
                rspauth = HEX(
                    KD(
                        HEX(H(a1)), "%s:%s:%s:%s:%s" %
                        (nonce, nc, cnonce, "auth", HEX(H(a2)))))

                self.state = SASLDigestMD5.SENT_CHALLENGE2

                res = Element('challenge',
                              {'xmlns': 'urn:ietf:params:xml:ns:xmpp-sasl'})
                res.text = base64.b64encode(u"rspauth=%s" % rspauth)

                return res

            else:
                self._handleFailure()
                raise SASLAuthError
        elif self.state == SASLDigestMD5.SENT_CHALLENGE2 and isinstance(
                data, Element):
            # expect to get <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
            respInd = data.tag.find(
                '{urn:ietf:params:xml:ns:xmpp-sasl}response')
            d = self.msg.conn.data
            if respInd != -1 and len(data) == 0:
                self.state = SASLDigestMD5.INIT
                d['sasl']['complete'] = True
                d['sasl']['in-progress'] = False
                d['user']['jid'] = '%s@%s' % (self.username,
                                              self.msg.conn.server.hostname)

                # record the JID for local delivery
                self.msg.conn.server.conns[self.msg.conn.id] = (JID(
                    d['user']['jid']), self.msg.conn)

                self.msg.conn.parser.resetParser()

                res = Element('success',
                              {'xmlns': 'urn:ietf:params:xml:ns:xmpp-sasl'})
                return res
            else:
                self._handleFailure()
                raise SASLAuthError
        else:
            self._handleFailure()
            raise SASLAuthError