def _assign_consessionid(consolesession): sessid = util.randomstring(32) while sessid in consolesessions: sessid = util.randomstring(32) consolesessions[sessid] = {'session': consolesession, 'expiry': time.time() + 60} return sessid
def _assign_consessionid(consolesession): sessid = util.randomstring(32) while sessid in consolesessions: sessid = util.randomstring(32) consolesessions[sessid] = { 'session': consolesession, 'expiry': time.time() + 60 } return sessid
def _csrf_valid(env, session): # This could be simplified into a statement, but this is more readable # to have it broken out if env['REQUEST_METHOD'] == 'GET' and _csrf_exempt(env['PATH_INFO']): # Provide a web client a safe hook to request the CSRF token # This means that we consider GET of /sessions/current/info to be # a safe thing to inflict via CSRF, since CORS should prevent # hypothetical attacker from reading the data and it has no # side effects to speak of return True if 'csrftoken' not in session: # The client has not (yet) requested CSRF protection # so we return true if 'HTTP_CONFLUENTAUTHTOKEN' in env: # The client has requested CSRF countermeasures, # oblige the request and apply a new token to the # session session['csrftoken'] = util.randomstring(32) elif 'HTTP_REFERER' in env: # If there is a referrer, make sure it stays consistent # across the session. A change in referer is a bad thing try: referer = env['HTTP_REFERER'].split('/')[2] except IndexError: return False if 'validreferer' not in session: session['validreferer'] = referer elif session['validreferer'] != referer: return False return True # The session has CSRF protection enabled, only mark valid if # the client has provided an auth token and that token matches the # value protecting the session return ('HTTP_CONFLUENTAUTHTOKEN' in env and env['HTTP_CONFLUENTAUTHTOKEN'] == session['csrftoken'])
def _csrf_valid(env, session): # This could be simplified into a statement, but this is more readable # to have it broken out if (env['REQUEST_METHOD'] == 'GET' and env['PATH_INFO'] == '/sessions/current/info'): # Provide a web client a safe hook to request the CSRF token # This means that we consider GET of /sessions/current/info to be # a safe thing to inflict via CSRF, since CORS should prevent # hypothetical attacker from reading the data and it has no # side effects to speak of return True if 'csrftoken' not in session: # The client has not (yet) requested CSRF protection # so we return true if 'HTTP_CONFLUENTAUTHTOKEN' in env: # The client has requested CSRF countermeasures, # oblige the request and apply a new token to the # session session['csrftoken'] = util.randomstring(32) return True # The session has CSRF protection enabled, only mark valid if # the client has provided an auth token and that token matches the # value protecting the session return ('HTTP_CONFLUENTAUTHTOKEN' in env and env['HTTP_CONFLUENTAUTHTOKEN'] == session['csrftoken'])
def _authorize_request(env, operation): """Grant/Deny access based on data from wsgi env """ authdata = None name = '' sessionid = None cookie = Cookie.SimpleCookie() if 'HTTP_COOKIE' in env: #attempt to use the cookie. If it matches cc = RobustCookie() cc.load(env['HTTP_COOKIE']) if 'confluentsessionid' in cc: sessionid = cc['confluentsessionid'].value sessid = sessionid if sessionid in httpsessions: if _csrf_valid(env, httpsessions[sessionid]): if env['PATH_INFO'] == '/sessions/current/logout': targets = [] for mythread in httpsessions[sessionid]['inflight']: targets.append(mythread) for mythread in targets: eventlet.greenthread.kill(mythread) forwarder.close_session(sessionid) del httpsessions[sessionid] return ('logout', ) httpsessions[sessionid]['expiry'] = time.time() + 90 name = httpsessions[sessionid]['name'] authdata = auth.authorize( name, element=None, skipuserobj=httpsessions[sessionid]['skipuserobject']) if (not authdata) and 'HTTP_AUTHORIZATION' in env: if env['PATH_INFO'] == '/sessions/current/logout': if 'HTTP_REFERER' in env: # note that this doesn't actually do harm # otherwise, but this way do not give appearance # of something having a side effect if it has the smell # of a CSRF return {'code': 401} return ('logout', ) name, passphrase = base64.b64decode(env['HTTP_AUTHORIZATION'].replace( 'Basic ', '')).split(':', 1) authdata = auth.check_user_passphrase(name, passphrase, element=None) if not authdata: return {'code': 401} sessid = util.randomstring(32) while sessid in httpsessions: sessid = util.randomstring(32) httpsessions[sessid] = { 'name': name, 'expiry': time.time() + 90, 'skipuserobject': authdata[4], 'inflight': set([]) } if 'HTTP_CONFLUENTAUTHTOKEN' in env: httpsessions[sessid]['csrftoken'] = util.randomstring(32) cookie['confluentsessionid'] = sessid cookie['confluentsessionid']['secure'] = 1 cookie['confluentsessionid']['httponly'] = 1 cookie['confluentsessionid']['path'] = '/' skiplog = _should_skip_authlog(env) if authdata: auditmsg = { 'user': name, 'operation': operation, 'target': env['PATH_INFO'], } authinfo = { 'code': 200, 'cookie': cookie, 'cfgmgr': authdata[1], 'username': authdata[2], 'userdata': authdata[0] } if authdata[3] is not None: auditmsg['tenant'] = authdata[3] authinfo['tenant'] = authdata[3] auditmsg['user'] = authdata[2] if sessid is not None: authinfo['sessionid'] = sessid if not skiplog: auditlog.log(auditmsg) if 'csrftoken' in httpsessions[sessid]: authinfo['authtoken'] = httpsessions[sessid]['csrftoken'] return authinfo else: return {'code': 401}
def _authorize_request(env, operation): """Grant/Deny access based on data from wsgi env """ authdata = None name = '' sessionid = None cookie = Cookie.SimpleCookie() if 'HTTP_COOKIE' in env: #attempt to use the cookie. If it matches cc = RobustCookie() cc.load(env['HTTP_COOKIE']) if 'confluentsessionid' in cc: sessionid = cc['confluentsessionid'].value sessid = sessionid if sessionid in httpsessions: if _csrf_valid(env, httpsessions[sessionid]): if env['PATH_INFO'] == '/sessions/current/logout': targets = [] for mythread in httpsessions[sessionid]['inflight']: targets.append(mythread) for mythread in targets: eventlet.greenthread.kill(mythread) del httpsessions[sessionid] return ('logout',) httpsessions[sessionid]['expiry'] = time.time() + 90 name = httpsessions[sessionid]['name'] authdata = auth.authorize( name, element=None, skipuserobj=httpsessions[sessionid]['skipuserobject']) if (not authdata) and 'HTTP_AUTHORIZATION' in env: if env['PATH_INFO'] == '/sessions/current/logout': if 'HTTP_REFERER' in env: # note that this doesn't actually do harm # otherwise, but this way do not give appearance # of something having a side effect if it has the smell # of a CSRF return {'code': 401} return ('logout',) name, passphrase = base64.b64decode( env['HTTP_AUTHORIZATION'].replace('Basic ', '')).split(':', 1) authdata = auth.check_user_passphrase(name, passphrase, element=None) if not authdata: return {'code': 401} sessid = util.randomstring(32) while sessid in httpsessions: sessid = util.randomstring(32) httpsessions[sessid] = {'name': name, 'expiry': time.time() + 90, 'skipuserobject': authdata[4], 'inflight': set([])} if 'HTTP_CONFLUENTAUTHTOKEN' in env: httpsessions[sessid]['csrftoken'] = util.randomstring(32) cookie['confluentsessionid'] = sessid cookie['confluentsessionid']['secure'] = 1 cookie['confluentsessionid']['httponly'] = 1 cookie['confluentsessionid']['path'] = '/' skiplog = _should_skip_authlog(env) if authdata: auditmsg = { 'user': name, 'operation': operation, 'target': env['PATH_INFO'], } authinfo = {'code': 200, 'cookie': cookie, 'cfgmgr': authdata[1], 'username': authdata[2], 'userdata': authdata[0]} if authdata[3] is not None: auditmsg['tenant'] = authdata[3] authinfo['tenant'] = authdata[3] auditmsg['user'] = authdata[2] if sessid is not None: authinfo['sessionid'] = sessid if not skiplog: auditlog.log(auditmsg) if 'csrftoken' in httpsessions[sessid]: authinfo['authtoken'] = httpsessions[sessid]['csrftoken'] return authinfo else: return {'code': 401}
def _assign_asyncid(asyncsession): sessid = util.randomstring(32) while sessid in _asyncsessions: sessid = util.randomstring(32) _asyncsessions[sessid] = {'asyncsession': asyncsession} return sessid
def _authorize_request(env, operation): """Grant/Deny access based on data from wsgi env """ authdata = None name = '' sessionid = None cookie = Cookie.SimpleCookie() element = env['PATH_INFO'] if element.startswith('/sessions/current/'): element = None if 'HTTP_COOKIE' in env: cidx = (env['HTTP_COOKIE']).find('confluentsessionid=') if cidx >= 0: sessionid = env['HTTP_COOKIE'][cidx + 19:cidx + 51] sessid = sessionid sessid = sessionid if sessionid in httpsessions: if _csrf_valid(env, httpsessions[sessionid]): if env['PATH_INFO'] == '/sessions/current/logout': targets = [] for mythread in httpsessions[sessionid]['inflight']: targets.append(mythread) for mythread in targets: eventlet.greenthread.kill(mythread) forwarder.close_session(sessionid) del httpsessions[sessionid] return ('logout', ) httpsessions[sessionid]['expiry'] = time.time() + 90 name = httpsessions[sessionid]['name'] authdata = auth.authorize( name, element=element, operation=operation, skipuserobj=httpsessions[sessionid]['skipuserobject']) if (not authdata) and 'HTTP_AUTHORIZATION' in env: if env['PATH_INFO'] == '/sessions/current/logout': if 'HTTP_REFERER' in env: # note that this doesn't actually do harm # otherwise, but this way do not give appearance # of something having a side effect if it has the smell # of a CSRF return {'code': 401} return ('logout', ) if env['HTTP_AUTHORIZATION'].startswith('MultiBasic '): name, passphrase = base64.b64decode( env['HTTP_AUTHORIZATION'].replace('MultiBasic ', '')).split(b':', 1) passphrase = json.loads(passphrase) else: name, passphrase = base64.b64decode( env['HTTP_AUTHORIZATION'].replace('Basic ', '')).split(b':', 1) try: authdata = auth.check_user_passphrase(name, passphrase, operation=operation, element=element) except Exception as e: if hasattr(e, 'prompts'): return {'code': 403, 'prompts': e.prompts} raise if authdata is False: return {'code': 403} elif not authdata: return {'code': 401} sessid = util.randomstring(32) while sessid in httpsessions: sessid = util.randomstring(32) httpsessions[sessid] = { 'name': name, 'expiry': time.time() + 90, 'skipuserobject': authdata[4], 'inflight': set([]) } if 'HTTP_CONFLUENTAUTHTOKEN' in env: httpsessions[sessid]['csrftoken'] = util.randomstring(32) cookie['confluentsessionid'] = util.stringify(sessid) cookie['confluentsessionid']['secure'] = 1 cookie['confluentsessionid']['httponly'] = 1 cookie['confluentsessionid']['path'] = '/' skiplog = _should_skip_authlog(env) if authdata: auditmsg = { 'user': util.stringify(name), 'operation': operation, 'target': env['PATH_INFO'], } authinfo = { 'code': 200, 'cookie': cookie, 'cfgmgr': authdata[1], 'username': authdata[2], 'userdata': authdata[0] } if authdata[3] is not None: auditmsg['tenant'] = authdata[3] authinfo['tenant'] = authdata[3] auditmsg['user'] = util.stringify(authdata[2]) if sessid is not None: authinfo['sessionid'] = sessid if not skiplog: auditlog.log(auditmsg) if 'csrftoken' in httpsessions[sessid]: authinfo['authtoken'] = httpsessions[sessid]['csrftoken'] httpsessions[sessid]['cfgmgr'] = authdata[1] return authinfo elif authdata is None: return {'code': 401} else: return {'code': 403}