Here's the attachment.

On 10/28/06, Nadav Samet <[EMAIL PROTECTED]> wrote:

On 10/28/06, Andrew Grover < [EMAIL PROTECTED]> wrote:

On 10/27/06, Nadav Samet <[EMAIL PROTECTED]> wrote:
> You can always send the username/password as a cookie (tg_remember_me), and
> use it as a way of authentication. This will not require any new table.

Is saving username and password in a cookie an OK thing to do?

In many situations not. Actually, the code attached saves the password encrypted using the provider's encryption algorithm, which is better (but the default is plain-text).

Unfortunately, validate_password() wants the password in plain-text, so I had to monkey-patch the providers again to accept either encrypted password or plain-text password:

def validate_password(self, user, user_name, password):
    return user.password in (password, self.encrypt_password(password))

and in IdentityVisitPlugin.__init__, I've added:
       self.provider.__class__.validate_password = validate_password   

(the full version is attached).

The only thing I see that might turn into a security problem, is that if someone got the encrypted password by hacking to the SQL server. Then he'll be able to login without knowing the real password. But any other autologin solution I know is vulnerable when the SQL server is hacked.

Can anyone advice if this is a security risk to accept both encrypted password and the plain-text one?



--
Sincerely yours,
Nadav
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "TurboGears Trunk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/turbogears-trunk
-~----------~----~----~----~------~----~------~--~---

from turbogears import identity
from turbogears.config import get
from turbogears.identity.visitor import log
import cherrypy
import time

BaseIdentityVisitPlugin = identity.visitor.IdentityVisitPlugin

def validate_password(self, user, user_name, password):
    return user.password in (password, self.encrypt_password(password))

class IdentityVisitPlugin(BaseIdentityVisitPlugin):
    def __init__(self):
        self.remember_me_field = get( "identity.form.remember_me", "remember_me" )
        # Default name for remember me cookie
        self.remember_me_cookie_name = get( 'identity.remember_me.cookie.name', 'tg_remember_me')
        self.remember_me_cookie_path = get( 'identity.remember_me.cookie.path', '/')
        self.remember_me_cookie_domain = get( 'identity.remember_me.cookie.path', None)
        self.remember_me_enabled = get( 'identity.remember_me.on', True)
        super(IdentityVisitPlugin, self).__init__()
        if self.remember_me_enabled:
            self.identity_sources.append(self.identity_from_remember_me)
        self.provider.__class__.validate_password = validate_password    

    def identity_from_remember_me( self, visit_key ):
        '''
        Inspect the remember me cookie to pull out identity information.
        
        Returns an identity dictionary or none if the cookie contained no identity
        information or the information was incorrect.
        '''
        cookies = cherrypy.request.simple_cookie
        if self.remember_me_cookie_name in cookies:
            value = cookies[self.remember_me_cookie_name].value.split('\n')
            if len(value)!=2:
                return None
            identity= self.provider.validate_identity( 
                    user_name=value[0], 
                    password = value[1], 
                    visit_key = visit_key )
            
            if identity is None:
                log.warning( "The credentials specified weren't valid" )
                return None

            return identity
        else:
            return None

    def identity_from_form( self, visit_key ):
        identity = super(IdentityVisitPlugin, self).identity_from_form(visit_key)
        if (identity and self.remember_me_enabled and 
                        cherrypy.request.params.pop(self.remember_me_field, False)):
            self.send_remember_me_cookie(identity.user.user_name, identity.user.password)
        return identity

    def send_remember_me_cookie(self, user_name, password):
        '''
        Sends a remember me cookie back to the browser
        '''
        cookies = cherrypy.response.simple_cookie
        password = self.provider.encrypt_password(password)

        cookies[self.remember_me_cookie_name] = user_name+'\n'+password
        cookies[self.remember_me_cookie_name]['path'] = self.remember_me_cookie_path
        gmt_expiration_time = time.gmtime(time.time() +
                (365 * 24 * 60 * 60))        #  1 year, in seconds
        cookies[self.remember_me_cookie_name]['expires'] = time.strftime(
                "%a, %d-%b-%Y %H:%M:%S GMT", gmt_expiration_time)
        if self.remember_me_cookie_domain:
            cookies[self.remember_me_cookie_name]['domain'] = self.remember_me_cookie_domain

        log.debug("Sending remember_me cookie")

    def identity_from_request(self, visit_key):
        '''
        Retrieve identity information from the HTTP request. Checks first for
        form fields defining the identity then for a cookie. If no identity
        is found, returns an anonymous identity.
        '''
        identity= None
        log.debug( "Retrieving identity for visit: %s", visit_key )
        for source in self.identity_sources:
            identity= source(visit_key)
            if identity and not identity.anonymous:
                return identity

        log.debug( "No identity found" )
        # No source reported an identity
        identity= self.provider.anonymous_identity()
        return identity
        

# We now replace the framework class with our derived class.
identity.visitor.IdentityVisitPlugin = IdentityVisitPlugin

def clear_remember_me_cookie():
    '''
    Clears any remember me cookie.
    '''
    cookies= cherrypy.response.simple_cookie
    remember_me_cookie_name = get( 'identity.remember_me.cookie.name', 'tg_remember_me')
    remember_me_cookie_path = get( 'identity.remember_me.cookie.path', '/')

    # clear the cookie
    log.debug( "Clearing remember_me cookie" )
    cookies[remember_me_cookie_name]= ''
    cookies[remember_me_cookie_name]['path']= remember_me_cookie_path
    cookies[remember_me_cookie_name]['expires']= 0

Reply via email to