def __eq__(self, stored_password):
        """
        compares the current lazy crypted password with a stored password
        """
        if isinstance(stored_password, self.__class__):
            return ((self is stored_password)
                    or ((self.crypt.key == stored_password.crypt.key) and
                        (self.password == stored_password.password)))

        if self.crypt.key:
            if ':' in self.crypt.key:
                key = self.crypt.key.split(':')[1]
            else:
                key = self.crypt.key
        else:
            key = ''
        if stored_password is None:
            return False
        elif stored_password.count('$') == 2:
            (digest_alg, salt, hash) = stored_password.split('$')
            h = simple_hash(self.password, key, salt, digest_alg)
            temp_pass = '******' % (digest_alg, salt, h)
        else:  # no salting
            # guess digest_alg
            digest_alg = DIGEST_ALG_BY_SIZE.get(len(stored_password), None)
            if not digest_alg:
                return False
            else:
                temp_pass = simple_hash(self.password, key, '', digest_alg)
        return temp_pass == stored_password
    def __eq__(self, stored_password):
        """
        compares the current lazy crypted password with a stored password
        """
        if isinstance(stored_password, self.__class__):
            return (self is stored_password) or (
                (self.crypt.key == stored_password.crypt.key) and (self.password == stored_password.password)
            )

        if self.crypt.key:
            if ":" in self.crypt.key:
                key = self.crypt.key.split(":")[1]
            else:
                key = self.crypt.key
        else:
            key = ""
        if stored_password is None:
            return False
        elif stored_password.count("$") == 2:
            (digest_alg, salt, hash) = stored_password.split("$")
            h = simple_hash(self.password, key, salt, digest_alg)
            temp_pass = "******" % (digest_alg, salt, h)
        else:  # no salting
            # guess digest_alg
            digest_alg = DIGEST_ALG_BY_SIZE.get(len(stored_password), None)
            if not digest_alg:
                return False
            else:
                temp_pass = simple_hash(self.password, key, "", digest_alg)
        return temp_pass == stored_password
Пример #3
0
    def test_simple_hash(self):
        """ Tests the simple_hash function """

        # no key, no salt, digest_alg=None
        self.assertRaises(RuntimeError, simple_hash, 'web2py rocks!', key='', salt='', digest_alg=None)

        # no key, no salt, digest_alg = md5
        data_md5 = simple_hash('web2py rocks!', key='', salt='', digest_alg=md5)
        self.assertEqual(data_md5, '37d95defba6c8834cb8cae86ee888568')

        # no key, no salt, 'md5'
        data_md5 = simple_hash('web2py rocks!', key='', salt='', digest_alg='md5')
        self.assertEqual(data_md5, '37d95defba6c8834cb8cae86ee888568')

        # no key, no salt, 'sha1'
        data_sha1 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha1')
        self.assertEqual(data_sha1, '00489a46753d8db260c71542611cdef80652c4b7')

        # no key, no salt, 'sha224'
        data_sha224 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha224')
        self.assertEqual(data_sha224, '84d7054271842c2c17983baa2b1447e0289d101140a8c002d49d60da')

        # no key, no salt, 'sha256'
        data_sha256 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha256')
        self.assertEqual(data_sha256, '0849f224d8deb267e4598702aaec1bd749e6caec90832469891012a4be24af08')

        # no key, no salt, 'sha384'
        data_sha384 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha384')
        self.assertEqual(data_sha384,
                         '3cffaf39371adbe84eb10f588d2718207d8e965e9172a27a278321b86977351376ae79f92e91d8c58cad86c491282d5f')

        # no key, no salt, 'sha512'
        data_sha512 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha512')
        self.assertEqual(data_sha512, 'fa3237f594743e1d7b6c800bb134b3255cf4a98ab8b01e2ec23256328c9f8059'
                                      '64fdef25a038d6cc3fda1b2fb45d66461eeed5c4669e506ec8bdfee71348db7e')
Пример #4
0
def checkDuplicatedLogin(wSessionId, wGroup, wCompanyType):
    """
        This function checks if the current user as more than five minutes of log and 
        than check if it is the same IP, if not, logout
        @param wCalledFunction The function called before the analysis of IP
        @return The function return
    """
    if auth.user:
        # check if the user was removed from the system
        if auth.user.actived_user == False:
            from gluon.utils import simple_hash
            if 'session_id_legislator' in request.cookies.keys():
                cookey_key = str(request.cookies['session_id_legislator'])
            else:
                cookey_key = str(random()*1000000000)
            db(db.auth_user.id==auth.user.id).update(last_ip=request.env.remote_addr,
                last_session=wSessionId,password=simple_hash(cookey_key,digest_alg='sha512')[:299])
            session.clear()
            raise HTTP(1001)
        if (session.current_state==None or session.current_company_name==None or
            session.current_city==None):
            searchs.setSessionCompanyInfo(request.env.remote_addr,wSessionId,request.now)
        #ups you cannot access this function 
        if not (session.current_role in wGroup):
            session.clear()
            raise HTTP(401)
        if not (session.current_company_type in wCompanyType):
            session.clear()
            raise HTTP(401)
        # fill the session
        if type(session.current_user_lastcheck) != datetime:
            #avoid break when the session is not correctly filled
            session.current_user_lastcheck = request.now
        if (((request.now-session.current_user_lastcheck).seconds) > 300):
            if session.current_user_id!=None and session.current_user_ip!=None and session.current_user_session!=None:
                ret = db.executesql("SELECT id FROM auth_user WHERE id={0} AND last_ip='{1}' AND last_session='{2}'".format(
                     session.current_user_id,session.current_user_ip,session.current_user_session))
            else:
                # clear the session to avoid any access to the system, guarantee logout
                session.clear()
                raise HTTP(1000)
            if len(ret)>0:# ok the last ip is the current ip
                session.current_user_lastcheck = request.now
                return True
            else:
                # clear the session to avoid any access to the system, guarantee logout
                session.clear()
                raise HTTP(1002)
        else:
            return True
    return True
    def __str__(self):
        """
        Encrypted self.password and caches it in self.crypted.
        If self.crypt.salt the output is in the format
        <algorithm>$<salt>$<hash>

        Try get the digest_alg from the key (if it exists)
        else assume the default digest_alg. If not key at all, set key=''

        If a salt is specified use it, if salt is True, set salt to uuid
        (this should all be backward compatible)

        Options:
        key = 'uuid'
        key = 'md5:uuid'
        key = 'sha512:uuid'
        ...
        key = 'pbkdf2(1000,64,sha512):uuid' 1000 iterations and 64 chars length
        """
        if self.crypted:
            return self.crypted
        if self.crypt.key:
            if ":" in self.crypt.key:
                digest_alg, key = self.crypt.key.split(":", 1)
            else:
                digest_alg, key = self.crypt.digest_alg, self.crypt.key
        else:
            digest_alg, key = self.crypt.digest_alg, ""
        if self.crypt.salt:
            if self.crypt.salt == True:
                salt = str(uuid()).replace("-", "")[-16:]
            else:
                salt = self.crypt.salt
        else:
            salt = ""
        hashed = simple_hash(self.password, key, salt, digest_alg)
        self.crypted = "%s$%s$%s" % (digest_alg, salt, hashed)
        return self.crypted
    def __str__(self):
        """
        Encrypted self.password and caches it in self.crypted.
        If self.crypt.salt the output is in the format
        <algorithm>$<salt>$<hash>

        Try get the digest_alg from the key (if it exists)
        else assume the default digest_alg. If not key at all, set key=''

        If a salt is specified use it, if salt is True, set salt to uuid
        (this should all be backward compatible)

        Options:
        key = 'uuid'
        key = 'md5:uuid'
        key = 'sha512:uuid'
        ...
        key = 'pbkdf2(1000,64,sha512):uuid' 1000 iterations and 64 chars length
        """
        if self.crypted:
            return self.crypted
        if self.crypt.key:
            if ':' in self.crypt.key:
                digest_alg, key = self.crypt.key.split(':', 1)
            else:
                digest_alg, key = self.crypt.digest_alg, self.crypt.key
        else:
            digest_alg, key = self.crypt.digest_alg, ''
        if self.crypt.salt:
            if self.crypt.salt == True:
                salt = str(uuid()).replace('-', '')[-16:]
            else:
                salt = self.crypt.salt
        else:
            salt = ''
        hashed = simple_hash(self.password, key, salt, digest_alg)
        self.crypted = '%s$%s$%s' % (digest_alg, salt, hashed)
        return self.crypted
Пример #7
0
def _delete_token(delete_key, session_id=response.session_id):
    return simple_hash(delete_key + session_id, digest_alg='sha512')
Пример #8
0
 def get_cookie_hash(self, data):
     return simple_hash('%s$%s'%(get_key(), data))
Пример #9
0
    def test_simple_hash(self):
        """ Tests the simple_hash function """

        # no key, no salt, digest_alg=None
        self.assertRaises(RuntimeError,
                          simple_hash,
                          'web2py rocks!',
                          key='',
                          salt='',
                          digest_alg=None)

        # no key, no salt, digest_alg = md5
        data_md5 = simple_hash('web2py rocks!',
                               key='',
                               salt='',
                               digest_alg=md5)
        self.assertEqual(data_md5, '37d95defba6c8834cb8cae86ee888568')

        # no key, no salt, 'md5'
        data_md5 = simple_hash('web2py rocks!',
                               key='',
                               salt='',
                               digest_alg='md5')
        self.assertEqual(data_md5, '37d95defba6c8834cb8cae86ee888568')

        # no key, no salt, 'sha1'
        data_sha1 = simple_hash('web2py rocks!',
                                key='',
                                salt='',
                                digest_alg='sha1')
        self.assertEqual(data_sha1, '00489a46753d8db260c71542611cdef80652c4b7')

        # no key, no salt, 'sha224'
        data_sha224 = simple_hash('web2py rocks!',
                                  key='',
                                  salt='',
                                  digest_alg='sha224')
        self.assertEqual(
            data_sha224,
            '84d7054271842c2c17983baa2b1447e0289d101140a8c002d49d60da')

        # no key, no salt, 'sha256'
        data_sha256 = simple_hash('web2py rocks!',
                                  key='',
                                  salt='',
                                  digest_alg='sha256')
        self.assertEqual(
            data_sha256,
            '0849f224d8deb267e4598702aaec1bd749e6caec90832469891012a4be24af08')

        # no key, no salt, 'sha384'
        data_sha384 = simple_hash('web2py rocks!',
                                  key='',
                                  salt='',
                                  digest_alg='sha384')
        self.assertEqual(
            data_sha384,
            '3cffaf39371adbe84eb10f588d2718207d8e965e9172a27a278321b86977351376ae79f92e91d8c58cad86c491282d5f'
        )

        # no key, no salt, 'sha512'
        data_sha512 = simple_hash('web2py rocks!',
                                  key='',
                                  salt='',
                                  digest_alg='sha512')
        self.assertEqual(
            data_sha512,
            'fa3237f594743e1d7b6c800bb134b3255cf4a98ab8b01e2ec23256328c9f8059'
            '64fdef25a038d6cc3fda1b2fb45d66461eeed5c4669e506ec8bdfee71348db7e')
Пример #10
0
def encrypt_password(password):
    salt = str(web2py_uuid()).replace('-', '')[-16:]
    digest_alg = 'pbkdf2(1000,20,sha512)'
    key = None
    h = simple_hash(password, key, salt, digest_alg)
    return '%s$%s$%s' % (digest_alg, salt, h)
Пример #11
0
def verifyURL(request, hmac_key=None, hash_vars=True, salt=None, user_signature=None):
    """
    Verifies that a request's args & vars have not been tampered with by the user

    :param request: web2py's request object
    :param hmac_key: the key to authenticate with, must be the same one previously
                    used when calling URL()
    :param hash_vars: which vars to include in our hashing. (Optional)
                    Only uses the 1st value currently
                    True (or undefined) means all, False none,
                    an iterable just the specified keys

    do not call directly. Use instead:

    URL.verify(hmac_key='...')

    the key has to match the one used to generate the URL.

        >>> r = Storage()
        >>> gv = Storage(p=(1,3),q=2,_signature='a32530f0d0caa80964bb92aad2bedf8a4486a31f')
        >>> r.update(dict(application='a', controller='c', function='f', extension='html'))
        >>> r['args'] = ['x', 'y', 'z']
        >>> r['get_vars'] = gv
        >>> verifyURL(r, 'key')
        True
        >>> verifyURL(r, 'kay')
        False
        >>> r.get_vars.p = (3, 1)
        >>> verifyURL(r, 'key')
        True
        >>> r.get_vars.p = (3, 2)
        >>> verifyURL(r, 'key')
        False

    """

    if not '_signature' in request.get_vars:
        return False  # no signature in the request URL

    # check if user_signature requires
    if user_signature:
        from globals import current
        if not current.session or not current.session.auth:
            return False
        hmac_key = current.session.auth.hmac_key
    if not hmac_key:
        return False

    # get our sig from request.get_vars for later comparison
    original_sig = request.get_vars._signature

    # now generate a new hmac for the remaining args & vars
    vars, args = request.get_vars, request.args

    # remove the signature var since it was not part of our signed message
    request.get_vars.pop('_signature')

    # join all the args & vars into one long string

    # always include all of the args
    other = args and urllib.quote('/' + '/'.join([str(x) for x in args])) or ''
    h_args = '/%s/%s/%s.%s%s' % (request.application,
                                 request.controller,
                                 request.function,
                                 request.extension,
                                 other)

    # but only include those vars specified (allows more flexibility for use with
    # forms or ajax)

    list_vars = []
    for (key, vals) in sorted(vars.items()):
        if not isinstance(vals, (list, tuple)):
            vals = [vals]
        for val in vals:
            list_vars.append((key, val))

    # which of the vars are to be included?
    if hash_vars is True:       # include them all
        h_vars = list_vars
    elif hash_vars is False:    # include none of them
        h_vars = ''
    else:                       # include just those specified
        # wrap in a try - if the desired vars have been removed it'll fail
        try:
            if hash_vars and not isinstance(hash_vars, (list, tuple)):
                hash_vars = [hash_vars]
            h_vars = [(k, v) for (k, v) in list_vars if k in hash_vars]
        except:
            # user has removed one of our vars! Immediate fail
            return False
    # build the full message string with both args & vars
    message = h_args + '?' + urllib.urlencode(sorted(h_vars))

    # hash with the hmac_key provided
    sig = simple_hash(message, str(hmac_key), salt or '', digest_alg='sha1')

    # put _signature back in get_vars just in case a second call to URL.verify is performed
    # (otherwise it'll immediately return false)
    request.get_vars['_signature'] = original_sig

    # return whether or not the signature in the request matched the one we just generated
    # (I.E. was the message the same as the one we originally signed)

    return compare(original_sig, sig)
Пример #12
0
def URL(
    a=None,
    c=None,
    f=None,
    r=None,
    args=None,
    vars=None,
    anchor='',
    extension=None,
    env=None,
    hmac_key=None,
    hash_vars=True,
    salt=None,
    user_signature=None,
    scheme=None,
    host=None,
    port=None,
    encode_embedded_slash=False,
    url_encode=True,
    language=None,
):
    """
    generates a url '/a/c/f' corresponding to application a, controller c
    and function f. If r=request is passed, a, c, f are set, respectively,
    to r.application, r.controller, r.function.

    The more typical usage is:

        URL('index')

    that generates a url for the index function
    within the present application and controller.

    Args:
        a: application (default to current if r is given)
        c: controller (default to current if r is given)
        f: function (default to current if r is given)
        r: request (optional)
        args: any arguments (optional). Additional "path" elements
        vars: any variables (optional). Querystring elements
        anchor: anchorname, without # (optional)
        extension: force an extension
        hmac_key: key to use when generating hmac signature (optional)
        hash_vars: which of the vars to include in our hmac signature
            True (default) - hash all vars, False - hash none of the vars,
            iterable - hash only the included vars ['key1','key2']
        salt: salt hashing with this string
        user_signature: signs automatically the URL in such way that only the
            user can access the URL (use with `URL.verify` or
            `auth.requires_signature()`)
        scheme: URI scheme (True, 'http' or 'https', etc); forces absolute URL (optional)
        host: string to force absolute URL with host (True means http_host)
        port: optional port number (forces absolute URL)
        encode_embedded_slash: encode slash characters included in args
        url_encode: encode characters included in vars

    Raises:
        SyntaxError: when no application, controller or function is available
            or when a CRLF is found in the generated url

    Examples:

    >>> str(URL(a='a', c='c', f='f', args=['x', 'y', 'z'],
    ...     vars={'p':1, 'q':2}, anchor='1'))
    '/a/c/f/x/y/z?p=1&q=2#1'

    >>> str(URL(a='a', c='c', f='f', args=['x', 'y', 'z'],
    ...     vars={'p':(1,3), 'q':2}, anchor='1'))
    '/a/c/f/x/y/z?p=1&p=3&q=2#1'

    >>> str(URL(a='a', c='c', f='f', args=['x', 'y', 'z'],
    ...     vars={'p':(3,1), 'q':2}, anchor='1'))
    '/a/c/f/x/y/z?p=3&p=1&q=2#1'

    >>> str(URL(a='a', c='c', f='f', anchor='1+2'))
    '/a/c/f#1%2B2'

    >>> str(URL(a='a', c='c', f='f', args=['x', 'y', 'z'],
    ...     vars={'p':(1,3), 'q':2}, anchor='1', hmac_key='key'))
    '/a/c/f/x/y/z?p=1&p=3&q=2&_signature=a32530f0d0caa80964bb92aad2bedf8a4486a31f#1'

    >>> str(URL(a='a', c='c', f='f', args=['w/x', 'y/z']))
    '/a/c/f/w/x/y/z'

    >>> str(URL(a='a', c='c', f='f', args=['w/x', 'y/z'], encode_embedded_slash=True))
    '/a/c/f/w%2Fx/y%2Fz'

    >>> str(URL(a='a', c='c', f='f', args=['%(id)d'], url_encode=False))
    '/a/c/f/%(id)d'

    >>> str(URL(a='a', c='c', f='f', args=['%(id)d'], url_encode=True))
    '/a/c/f/%25%28id%29d'

    >>> str(URL(a='a', c='c', f='f', vars={'id' : '%(id)d' }, url_encode=False))
    '/a/c/f?id=%(id)d'

    >>> str(URL(a='a', c='c', f='f', vars={'id' : '%(id)d' }, url_encode=True))
    '/a/c/f?id=%25%28id%29d'

    >>> str(URL(a='a', c='c', f='f', anchor='%(id)d', url_encode=False))
    '/a/c/f#%(id)d'

    >>> str(URL(a='a', c='c', f='f', anchor='%(id)d', url_encode=True))
    '/a/c/f#%25%28id%29d'
    """

    from gluon.main import current

    if args in (None, []):
        args = []
    vars = vars or {}
    application = None
    controller = None
    function = None

    if not isinstance(args, (list, tuple)):
        args = [args]

    if not r:
        if a and not c and not f:
            (f, a, c) = (a, c, f)
        elif a and c and not f:
            (c, f, a) = (a, c, f)
        from gluon import current
        if hasattr(current, 'request'):
            r = current.request

    if r:
        application = r.application
        controller = r.controller
        function = r.function
        if extension is None and r.extension != 'html':
            extension = r.extension
    if a:
        application = a
    if c:
        controller = c
    if f:
        if not isinstance(f, str):
            if hasattr(f, '__name__'):
                function = f.__name__
            else:
                raise SyntaxError('when calling URL, function or function name required')
        elif '/' in f:
            if f.startswith("/"):
                f = f[1:]
            items = f.split('/')
            function = f = items[0]
            args = items[1:] + args
        else:
            function = f

        # if the url gets a static resource, don't force extention
        if controller == 'static':
            extension = None
            # add static version to url
            if hasattr(current, 'response'):
                response = current.response
                if response.static_version and response.static_version_urls:
                    args = [function] + args
                    function = '_'+str(response.static_version)

        if '.' in function:
            function, extension = function.rsplit('.', 1)

    function2 = '%s.%s' % (function, extension or 'html')

    if not (application and controller and function):
        raise SyntaxError('not enough information to build the url (%s %s %s)' % (application, controller, function))

    if args:
        if url_encode:
            if encode_embedded_slash:
                other = '/' + '/'.join([urllib.quote(str(
                    x), '') for x in args])
            else:
                other = args and urllib.quote(
                    '/' + '/'.join([str(x) for x in args]))
        else:
            other = args and ('/' + '/'.join([str(x) for x in args]))
    else:
        other = ''

    if other.endswith('/'):
        other += '/'    # add trailing slash to make last trailing empty arg explicit

    list_vars = []
    for (key, vals) in sorted(vars.items()):
        if key == '_signature':
            continue
        if not isinstance(vals, (list, tuple)):
            vals = [vals]
        for val in vals:
            list_vars.append((key, val))

    if user_signature:
        from globals import current
        if current.session.auth:
            hmac_key = current.session.auth.hmac_key

    if hmac_key:
        # generate an hmac signature of the vars & args so can later
        # verify the user hasn't messed with anything

        h_args = '/%s/%s/%s%s' % (application, controller, function2, other)

        # how many of the vars should we include in our hash?
        if hash_vars is True:       # include them all
            h_vars = list_vars
        elif hash_vars is False:    # include none of them
            h_vars = ''
        else:                       # include just those specified
            if hash_vars and not isinstance(hash_vars, (list, tuple)):
                hash_vars = [hash_vars]
            h_vars = [(k, v) for (k, v) in list_vars if k in hash_vars]

        # re-assembling the same way during hash authentication
        message = h_args + '?' + urllib.urlencode(sorted(h_vars))
        sig = simple_hash(
            message, hmac_key or '', salt or '', digest_alg='sha1')
        # add the signature into vars
        list_vars.append(('_signature', sig))

    if list_vars:
        if url_encode:
            other += '?%s' % urllib.urlencode(list_vars)
        else:
            other += '?%s' % '&'.join(['%s=%s' % var[:2] for var in list_vars])
    if anchor:
        if url_encode:
            other += '#' + urllib.quote(str(anchor))
        else:
            other += '#' + (str(anchor))
    if extension:
        function += '.' + extension

    if regex_crlf.search(''.join([application, controller, function, other])):
        raise SyntaxError('CRLF Injection Detected')

    url = url_out(r, application, controller, function,
                  args, other, scheme, host, port, language=language)
    return url