예제 #1
0
    def check(fn, self, *a, **kw):
        is_api = util.is_api()
        request = cherrypy.request
        if not handle_api and is_api:
            raise RequestRefused(404)
        if handle_api is ONLY_API and not is_api:
            raise RequestRefused(404)
        _methods = methods
        if _methods:
            if isinstance(_methods, basestring):
                _methods = [ _methods ]
            if request.method not in _methods:
                raise RequestRefused(405)
        
        # verify that version info is good; do it here so that any URI access
        # will trigger the check
        startup.initVersionInfo()

        # add a convenience property to all request objects to get at the
        # current relative URI
        request.relative_uri = request.path_info + (('?' + request.query_string) if request.query_string else '')
        if cherrypy.config.get('root_endpoint') not in ['/', None, '']:
            request.relative_uri = cherrypy.config.get('root_endpoint') + request.relative_uri

        # CSRF protection
        # Disable in tests by setting cherrypy.config.update({'environment': 'test_suite'})
        if verify_session and request.method == 'POST' and not cherrypy.config.get('environment') == 'test_suite':
            is_xhr = util.is_xhr()
            form_key = request.headers.get('X-Splunk-Form-Key') if is_xhr else request.params.get('splunk_form_key')
            # verify that the incoming form key matches server's version
            if not util.isValidFormKey(form_key):
                if is_xhr:
                    logger.warn('CSRF: validation failed because client XHR did not include proper header')
                else:
                    logger.warn('CSRF: validation failed because HTTP POST did not include expected parameter')
                if must_login:
                    if is_xhr:
                        raise cherrypy.HTTPError(401, _('Splunk cannot authenticate the request. CSRF validation failed.'))
                    else:
                        return self.redirect_to_url('/account/login', _qs=[ ('return_to', util.current_url_path()) ] )
                logger.warn('CSRF: skipping 401 redirect response because endpoint did not request protection')

        # basic input cleansing
        if trim_spaces:
            for key, value in kw.iteritems():
                if isinstance(value, basestring):
                    kw[key] = value.strip()
                    if kw[key] != value:
                        logger.debug('Leading/trailing whitespaces were trimmed in "%s" argument' % key)
                
        return fn(self, *a, **kw)
예제 #2
0
파일: account.py 프로젝트: DRArpitha/splunk
 def passwordchange(self, newpassword=None, confirmpassword=None, return_to=None, **kw):
     '''
     Suggest admin to change the password on first time run
     '''
     # We set must_login to False in the expose_page decoator so we can perform the checks here instead
     # and give the user a more useful message if the session has expired leaving the password unchanged
     if not cherrypy.session.get('sessionKey', None) or not util.isValidFormKey(kw['splunk_form_key']):
         # The user intended to change the password; reset the flag so this page will be shown again
         cherrypy.session.delete()
         self.setLoginFlag(False) 
         templateArgs = self.getLoginTemplateArgs(return_to=return_to, session_expired_pw_change=True)
         return self.render_template('account/login.html', templateArgs)
         
     err = None
     templateArgs = {
         'err' : err,
         'return_to' : return_to,
         'cpSessionKey' : cherrypy.session.id
     }        
     
     if newpassword != confirmpassword:
         templateArgs['err'] = _("Passwords didn't match, please try again.")
         return self.render_template('account/passwordchange.html', templateArgs)
     
     if newpassword == 'changeme':
         templateArgs['err'] = _("For security reasons, the new password must be different from the default one.")
         return self.render_template('account/passwordchange.html', templateArgs)
     
     try:
         user = User.get('admin')
         user.password = newpassword
         if not user.save():
             logger.error('Unable to save new admin password.')
             
     except splunk.AuthenticationFailed:
         cherrypy.session.delete()
         self.setLoginFlag(False) 
         templateArgs = self.getLoginTemplateArgs(return_to=return_to, session_expired_pw_change=True)
         return self.render_template('account/login.html', templateArgs)
         
     except splunk.RESTException, e:
         err = e.get_message_text()
         if ':' in err:
             err = err[err.find(':')+2:]
             
         logger.error("Failed to change the password: %s." % err)       
         templateArgs['err'] = err
         return self.render_template('account/passwordchange.html', templateArgs)
    def passwordchange(self, newpassword=None, confirmpassword=None, return_to=None, cval=None, **kw):
        '''
        Suggest admin to change the password on first time run 
        And force flagged users to change their passwords before they continue
        '''
        # We set must_login to False in the expose_page decoator so we can perform the checks here instead
        # and give the user a more useful message if the session has expired leaving the password unchanged
        # but first we check if the passwords pass
        
        err = None
        templateArgs = {
            'err' : err,
            'return_to' : return_to,
            'cpSessionKey' : cherrypy.session.id
        }

        if 'fpc' in cherrypy.session:
            templateArgs['fpc'] = True

        if not newpassword or len(newpassword) == 0:
            templateArgs['err'] = _("Empty passwords are not allowed.")
            return self.render_template('account/passwordchange.html', templateArgs)

        if newpassword != confirmpassword:
            templateArgs['err'] = _("Passwords didn't match, please try again.")
            return self.render_template('account/passwordchange.html', templateArgs)

        if newpassword == 'changeme':
            templateArgs['err'] = _("For security reasons, the new password must be different from the default one.")
            return self.render_template('account/passwordchange.html', templateArgs)

        # Forced Password Change workflow is checked before the session check b/c user isn't authenticated yet
        if 'fpc' in cherrypy.session:        
            try:
                # Fetch the user's verified cached credentials from when they originally attempted to login
                with AccountController.credential_lock:
                    # Will raise a KeyError if the credentials have expired from the LRU or CP was restarted
                    credentials = AccountController.credential_cache[cherrypy.session.id]

                if newpassword == credentials['password']:
                    templateArgs['err'] = _("For security reasons, the new password must be different from the previous one.")
                    return self.render_template('account/passwordchange.html', templateArgs)

                # Will be resetup, if required, by self.login()
                del cherrypy.session['fpc']
                with AccountController.credential_lock:
                    try:
                        del AccountController.credential_cache[cherrypy.session.id]
                    except KeyError:
                        pass

                # Fake a login form submission; this call must return as soon as the call to login() completes!
                return self.login(username=credentials['username'], password=credentials['password'],
                                  newpassword=newpassword, return_to=return_to, cval=cherrypy.session['cval'])

            except (splunk.AuthenticationFailed, KeyError):
                cherrypy.session.delete()
                self.setLoginFlag(False)
                templateArgs = self.getLoginTemplateArgs(return_to=return_to, session_expired_pw_change=True)
                return self.render_template('account/login.html', templateArgs)

        if not cherrypy.session.get('sessionKey', None) or not util.isValidFormKey(kw['splunk_form_key']):
            # The user intended to change the password; reset the flag so this page will be shown again
            cherrypy.session.delete()
            self.setLoginFlag(False)
            templateArgs = self.getLoginTemplateArgs(return_to=return_to, session_expired_pw_change=True)
            return self.render_template('account/login.html', templateArgs)

        try:
            user = User.get(cherrypy.session['user']['name'])
            user.password = newpassword
            if not user.save():
                logger.error('Unable to save new admin password.')

        except splunk.AuthenticationFailed:
            cherrypy.session.delete()
            self.setLoginFlag(False)
            templateArgs = self.getLoginTemplateArgs(return_to=return_to, session_expired_pw_change=True)
            return self.render_template('account/login.html', templateArgs)

        except splunk.RESTException, e:
            err = e.get_message_text()
            if ':' in err:
                err = err[err.find(':')+2:]

            logger.error("Failed to change the password: %s." % err)
            templateArgs['err'] = err
            return self.render_template('account/passwordchange.html', templateArgs)
예제 #4
0
    def passwordchange(self,
                       newpassword=None,
                       confirmpassword=None,
                       return_to=None,
                       **kw):
        '''
        Suggest admin to change the password on first time run
        '''
        # We set must_login to False in the expose_page decoator so we can perform the checks here instead
        # and give the user a more useful message if the session has expired leaving the password unchanged
        if not cherrypy.session.get('sessionKey',
                                    None) or not util.isValidFormKey(
                                        kw['splunk_form_key']):
            # The user intended to change the password; reset the flag so this page will be shown again
            cherrypy.session.delete()
            self.setLoginFlag(False)
            templateArgs = self.getLoginTemplateArgs(
                return_to=return_to, session_expired_pw_change=True)
            return self.render_template('account/login.html', templateArgs)

        err = None
        templateArgs = {
            'err': err,
            'return_to': return_to,
            'cpSessionKey': cherrypy.session.id
        }

        if newpassword != confirmpassword:
            templateArgs['err'] = _(
                "Passwords didn't match, please try again.")
            return self.render_template('account/passwordchange.html',
                                        templateArgs)

        if newpassword == 'changeme':
            templateArgs['err'] = _(
                "For security reasons, the new password must be different from the default one."
            )
            return self.render_template('account/passwordchange.html',
                                        templateArgs)

        try:
            user = User.get('admin')
            user.password = newpassword
            if not user.save():
                logger.error('Unable to save new admin password.')

        except splunk.AuthenticationFailed:
            cherrypy.session.delete()
            self.setLoginFlag(False)
            templateArgs = self.getLoginTemplateArgs(
                return_to=return_to, session_expired_pw_change=True)
            return self.render_template('account/login.html', templateArgs)

        except splunk.RESTException, e:
            err = e.get_message_text()
            if ':' in err:
                err = err[err.find(':') + 2:]

            logger.error("Failed to change the password: %s." % err)
            templateArgs['err'] = err
            return self.render_template('account/passwordchange.html',
                                        templateArgs)
예제 #5
0
    def check(fn, self, *a, **kw):
        is_api = util.is_api()
        request = cherrypy.request
        if not handle_api and is_api:
            raise RequestRefused(404)
        if handle_api is ONLY_API and not is_api:
            raise RequestRefused(404)
        _methods = methods
        if _methods:
            if isinstance(_methods, basestring):
                _methods = [_methods]
            if request.method not in _methods:
                raise RequestRefused(405)

        # verify that version info is good; do it here so that any URI access
        # will trigger the check
        startup.initVersionInfo()

        # add a convenience property to all request objects to get at the
        # current relative URI
        request.relative_uri = request.path_info + (
            ('?' + request.query_string) if request.query_string else '')
        if cherrypy.config.get('root_endpoint') not in ['/', None, '']:
            request.relative_uri = cherrypy.config.get(
                'root_endpoint') + request.relative_uri

        # CSRF protection
        # Disable in tests by setting cherrypy.config.update({'environment': 'test_suite'})
        if verify_session and request.method == 'POST' and not cherrypy.config.get(
                'environment') == 'test_suite':
            is_xhr = util.is_xhr()
            form_key = request.headers.get(
                'X-Splunk-Form-Key') if is_xhr else request.params.get(
                    'splunk_form_key')
            # verify that the incoming form key matches server's version
            if not util.isValidFormKey(form_key):
                if is_xhr:
                    logger.warn(
                        'CSRF: validation failed because client XHR did not include proper header'
                    )
                else:
                    logger.warn(
                        'CSRF: validation failed because HTTP POST did not include expected parameter'
                    )
                if must_login:
                    if is_xhr:
                        raise cherrypy.HTTPError(
                            401,
                            _('Splunk cannot authenticate the request. CSRF validation failed.'
                              ))
                    else:
                        return self.redirect_to_url(
                            '/account/login',
                            _qs=[('return_to', util.current_url_path())])
                logger.warn(
                    'CSRF: skipping 401 redirect response because endpoint did not request protection'
                )

        # basic input cleansing
        if trim_spaces:
            for key, value in kw.iteritems():
                if isinstance(value, basestring):
                    kw[key] = value.strip()
                    if kw[key] != value:
                        logger.debug(
                            'Leading/trailing whitespaces were trimmed in "%s" argument'
                            % key)

        return fn(self, *a, **kw)
    def passwordchange(self,
                       newpassword=None,
                       confirmpassword=None,
                       return_to=None,
                       cval=None,
                       **kw):
        '''
        Suggest admin to change the password on first time run 
        And force flagged users to change their passwords before they continue
        '''
        # We set must_login to False in the expose_page decoator so we can perform the checks here instead
        # and give the user a more useful message if the session has expired leaving the password unchanged
        # but first we check if the passwords pass

        err = None
        templateArgs = {
            'err': err,
            'return_to': return_to,
            'cpSessionKey': cherrypy.session.id
        }

        if 'fpc' in cherrypy.session:
            templateArgs['fpc'] = True

        if not newpassword or len(newpassword) == 0:
            templateArgs['err'] = _("Empty passwords are not allowed.")
            return self.render_template('account/passwordchange.html',
                                        templateArgs)

        if newpassword != confirmpassword:
            templateArgs['err'] = _(
                "Passwords didn't match, please try again.")
            return self.render_template('account/passwordchange.html',
                                        templateArgs)

        if newpassword == 'changeme':
            templateArgs['err'] = _(
                "For security reasons, the new password must be different from the default one."
            )
            return self.render_template('account/passwordchange.html',
                                        templateArgs)

        # Forced Password Change workflow is checked before the session check b/c user isn't authenticated yet
        if 'fpc' in cherrypy.session:
            try:
                # Fetch the user's verified cached credentials from when they originally attempted to login
                with AccountController.credential_lock:
                    # Will raise a KeyError if the credentials have expired from the LRU or CP was restarted
                    credentials = AccountController.credential_cache[
                        cherrypy.session.id]

                if newpassword == credentials['password']:
                    templateArgs['err'] = _(
                        "For security reasons, the new password must be different from the previous one."
                    )
                    return self.render_template('account/passwordchange.html',
                                                templateArgs)

                # Will be resetup, if required, by self.login()
                del cherrypy.session['fpc']
                with AccountController.credential_lock:
                    try:
                        del AccountController.credential_cache[
                            cherrypy.session.id]
                    except KeyError:
                        pass

                # Fake a login form submission; this call must return as soon as the call to login() completes!
                return self.login(username=credentials['username'],
                                  password=credentials['password'],
                                  newpassword=newpassword,
                                  return_to=return_to,
                                  cval=cherrypy.session['cval'])

            except (splunk.AuthenticationFailed, KeyError):
                cherrypy.session.delete()
                self.setLoginFlag(False)
                templateArgs = self.getLoginTemplateArgs(
                    return_to=return_to, session_expired_pw_change=True)
                return self.render_template('account/login.html', templateArgs)

        if not cherrypy.session.get('sessionKey',
                                    None) or not util.isValidFormKey(
                                        kw['splunk_form_key']):
            # The user intended to change the password; reset the flag so this page will be shown again
            cherrypy.session.delete()
            self.setLoginFlag(False)
            templateArgs = self.getLoginTemplateArgs(
                return_to=return_to, session_expired_pw_change=True)
            return self.render_template('account/login.html', templateArgs)

        try:
            user = User.get(cherrypy.session['user']['name'])
            user.password = newpassword
            if not user.save():
                logger.error('Unable to save new admin password.')

        except splunk.AuthenticationFailed:
            cherrypy.session.delete()
            self.setLoginFlag(False)
            templateArgs = self.getLoginTemplateArgs(
                return_to=return_to, session_expired_pw_change=True)
            return self.render_template('account/login.html', templateArgs)

        except splunk.RESTException, e:
            err = e.get_message_text()
            if ':' in err:
                err = err[err.find(':') + 2:]

            logger.error("Failed to change the password: %s." % err)
            templateArgs['err'] = err
            return self.render_template('account/passwordchange.html',
                                        templateArgs)