<?php require_once 'pusher_config.php'; require_once 'Pusher.php'; require_once 'functions.php'; $pusher = get_pusher(); $channel_name = try_get_param('channel_name'); $socket_id = try_get_param('socket_id'); $user_id = get_user_id(); $presence_data = get_user_info(); $auth = $pusher->presence_auth($channel_name, $socket_id, $user_id, $presence_data); send_auth_response($auth);
function send_response($username, $authorize = false) { $GET = $_SESSION['get']; $rpfA = $_SESSION['rpfA']; $rpep = $GET['redirect_uri']; $state = isset($GET['state']) ? $GET['state'] : NULL; $error_page = isset($GET['redirect_uri']) ? $GET['redirect_uri'] : OP_INDEX_PAGE; $response_mode = get_response_mode($GET); try { $client_id = $GET['client_id']; $response_types = explode(' ', $GET['response_type']); $scopes = explode(' ', $GET['scope']); $prompts = explode(' ', $GET['prompt']); $is_code_flow = in_array('code', $response_types); $is_token_flow = in_array('token', $response_types); $is_id_token = in_array('id_token', $response_types); $offline_access = $is_code_flow && !$is_token_flow && in_array('consent', $prompts) && in_array('offline_access', $scopes); $issue_at = strftime('%G-%m-%d %T'); $expiration_at = strftime('%G-%m-%d %T', time() + 2 * 60); $response_params = array(); if (!$authorize) { throw new OidcException('access_denied', 'User denied access'); } $rpfA['session_id'] = session_id(); $rpfA['auth_time'] = $_SESSION['auth_time']; $confirmed_attribute_list = get_all_requested_claims($rpfA, $GET['scope']); if ($is_code_flow) { $code_info = create_token_info($username, $confirmed_attribute_list, $GET, $rpfA); $code = $code_info['name']; unset($code_info['name']); $fields = array('client' => $GET['client_id'], 'issued_at' => $issue_at, 'expiration_at' => $expiration_at, 'token' => $code, 'details' => '', 'token_type' => TOKEN_TYPE_AUTH_CODE, 'info' => json_encode($code_info)); db_save_user_token($username, $code, $fields); } if ($is_token_flow) { $code_info = create_token_info($username, $confirmed_attribute_list, $GET, $rpfA); $token = $code_info['name']; unset($code_info['name']); $issue_at = strftime('%G-%m-%d %T'); $expiration_at = strftime('%G-%m-%d %T', time() + 2 * 60); $fields = array('client' => $GET['client_id'], 'issued_at' => $issue_at, 'expiration_at' => $expiration_at, 'token' => $token, 'details' => '', 'token_type' => TOKEN_TYPE_ACCESS, 'info' => json_encode($code_info)); db_save_user_token($username, $token, $fields); } if ($offline_access) { while (true) { $refresh_token_name = base64url_encode(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); if (!db_find_token($refresh_token_name)) { break; } } $fields = array('client' => $GET['client_id'], 'issued_at' => $issue_at, 'expiration_at' => $expiration_at, 'token' => $refresh_token_name, 'details' => '', 'token_type' => TOKEN_TYPE_REFRESH, 'info' => json_encode($code_info)); $fields['expiration_at'] = strftime('%G-%m-%d %T', time() + 24 * 60 * 60); db_save_user_token($username, $refresh_token_name, $fields); } // Handle response_type for code or token if (isset($GET['state'])) { $response_params['state'] = $GET['state']; } if ($is_token_flow || $is_id_token) { if (isset($token)) { $response_params['access_token'] = $token; $response_params['token_type'] = 'Bearer'; if ($offline_access) { $response_params['refresh_token'] = $refresh_token_name; } $response_params['expires_in'] = '3600'; } } if ($is_id_token) { $client_secret = null; $nonce = isset($GET['nonce']) ? $GET['nonce'] : null; $c_hash = null; $at_hash = null; $ops = null; $auth_time = null; $acr = null; $idt_claims = array(); $sig = null; $alg = null; $enc = null; $client_secret = null; $jwk_uri = null; $db_client = db_get_client($client_id); if ($db_client) { $sig = $db_client['id_token_signed_response_alg']; if (!isset($sig)) { $sig = 'RS256'; } $alg = $db_client['id_token_encrypted_response_alg']; $enc = $db_client['id_token_encrypted_response_enc']; $client_secret = $db_client['client_secret']; $jwk_uri = $db_client['jwks_uri']; $jwks = $db_client['jwks']; } if (isset($rpfA['claims']) && isset($rpfA['claims']['id_token'])) { if (array_key_exists('auth_time', $rpfA['claims']['id_token'])) { $auth_time = (int) $_SESSION['auth_time']; } if (array_key_exists('acr', $rpfA['claims']['id_token'])) { if (array_key_exists('values', $rpfA['claims']['id_token']['acr'])) { if (is_array($rpfA['claims']['id_token']['acr']['values']) && count($rpfA['claims']['id_token']['acr']['values'])) { $acr = $rpfA['claims']['id_token']['acr']['values'][0]; } } else { $acr = '0'; } } } if ($sig) { $bit_length = substr($sig, 2); switch ($bit_length) { case '384': $hash_alg = 'sha384'; break; case '512': $hash_alg = 'sha512'; break; case '256': default: $hash_alg = 'sha256'; break; } $hash_length = (int) ((int) $bit_length / 2) / 8; if ($code) { $c_hash = base64url_encode(substr(hash($hash_alg, $code, true), 0, $hash_length)); } if ($token) { $at_hash = base64url_encode(substr(hash($hash_alg, $token, true), 0, $hash_length)); } } $requested_id_token_claims = get_id_token_claims($rpfA); if ($requested_id_token_claims) { $db_user = db_get_user($username); if ($db_user) { $idt_claims = get_account_claims($db_user, $requested_id_token_claims); } else { throw new OidcException('access_denied', 'no such user'); } } $id_token_obj = make_id_token(wrap_userid($db_client, $username), SERVER_ID, $client_id, $idt_claims, $nonce, $c_hash, $at_hash, $auth_time, $ops, $acr); log_debug('sen_response id_token_obj = %s', print_r($id_token_obj, true)); $cryptoError = null; $id_token = sign_encrypt($id_token_obj, $sig, $alg, $enc, $jwk_uri, $jwks, $client_secret, $cryptoError); if (!$id_token) { log_error("Unable to sign encrypt response for ID Token %s", $cryptoError); throw new OidcException('invalid_request', "idtoken crypto error {$cryptoError}"); } $response_params['id_token'] = $id_token; } $url_parts = parse_url($rpep); $origin = sprintf("%s://%s%s", $url_parts['scheme'], $url_parts['host'], isset($url_parts['port']) ? ':' . $url_parts['port'] : ''); $salt = bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)); log_debug("ss = sha256(%s%s%s%s).%s", $client_id, $origin, $_SESSION['ops'], $salt, $salt); $session_state = hash('sha256', "{$client_id}{$origin}{$_SESSION['ops']}{$salt}") . '.' . $salt; $response_params['session_state'] = $session_state; if ($is_code_flow) { $response_params['code'] = $code; } if ($_SESSION['persist'] == 'on') { $username = $_SESSION['username']; $auth_time = $_SESSION['auth_time']; $ops = $_SESSION['ops']; $login = $_SESSION['login']; clean_session(); $_SESSION['lastlogin'] = time(); $_SESSION['username'] = $username; $_SESSION['auth_time'] = $auth_time; $_SESSION['ops'] = $ops; $_SESSION['login'] = $login; $_SESSION['persist'] = 'on'; } else { session_destroy(); } send_auth_response($rpep, $response_params, $response_mode); } catch (OidcException $e) { log_error("handle_auth exception : %s", $e->getTraceAsString()); send_error($error_page, $e->error_code, $e->desc, NULL, $state, $response_mode); } catch (Exception $e) { log_error("handle_auth exception : %s", $e->getTraceAsString()); send_error($error_page, 'invalid_request', $e->getMessage(), NULL, $state, $response_mode); } }
function webrtc_handle_auth() { $state = isset($_REQUEST['state']) ? $_REQUEST['state'] : NULL; $error_page = OP_INDEX_PAGE; $response_mode = 'query'; try { if (!isset($_REQUEST['client_id'])) { throw new OidcException('invalid_request', 'no client'); } // check client id $client = db_get_client($_REQUEST['client_id']); if (!$client) { throw new OidcException('unauthorized_client', 'Client ID not found'); } /* if(isset($_REQUEST['redirect_uri'])) { if(!is_valid_registered_redirect_uri($client['redirect_uris'], $_REQUEST['redirect_uri'])) throw new OidcException('invalid_request', 'no matching redirect_uri'); } else throw new OidcException('invalid_request', 'no redirect_uri in request'); $error_page = $_REQUEST['redirect_uri']; */ $response_mode = get_response_mode($_REQUEST); if (!isset($_REQUEST['response_type'])) { throw new OidcException('invalid_request', 'no response_type'); } $response_types = explode(' ', $_REQUEST['response_type']); $known_response_types = array('code', 'token', 'id_token'); if (count(array_diff($response_types, $known_response_types))) { throw new OidcException('invalid_response_type', "Unknown response_type {$_REQUEST['response_type']}"); } if (ENABLE_PKCE) { if (in_array('code', $response_types)) { if (!isset($_REQUEST['code_challenge'])) { throw new OidcException('invalid_request', 'code challenge required'); } if (isset($_REQUEST['code_challenge_method'])) { if (!in_array($_REQUEST['code_challenge_method'], array('plain', 'S256'))) { throw new OidcException('invalid_request', "unsupported code challenge method {$_REQUEST['code_challenge_method']}"); } } } } if (!isset($_REQUEST['scope'])) { throw new OidcException('invalid_request', 'no scope'); } $scopes = explode(' ', $_REQUEST['scope']); if (!in_array('openid', $scopes)) { throw new OidcException('invalid_scope', 'no openid scope'); } if (in_array('token', $response_types) || in_array('id_token', $response_types)) { if (!isset($_REQUEST['nonce'])) { throw new OidcException('invalid_request', 'no nonce'); } } $_SESSION['get'] = $_GET; $request_uri = isset($_REQUEST['request_uri']) ? $_REQUEST['request_uri'] : NULL; $requested_userid = NULL; $requested_userid_display = NULL; $request_object = NULL; if ($request_uri) { $request_object = get_url($request_uri); if (!$request_object) { throw new OidcException('invalid_request', "Unable to fetch request file {$request_uri}"); } } elseif (isset($_REQUEST['request'])) { $request_object = $_REQUEST['request']; } if (isset($_GET['claims'])) { $_GET['claims'] = json_decode($_GET['claims'], true); $_REQUEST['claims'] = $_GET['claims']; } if (isset($request_object)) { $cryptoError = ''; $payload = decrypt_verify_jwt($request_object, $client, $cryptoError); if (!isset($payload)) { if ($cryptoError == 'error_decrypt') { throw new OidcException('invalid_request', 'Unable to decrypt request object'); } elseif ($cryptoError == 'error_sig') { throw new OidcException('invalid_request', 'Unable to verify request object signature'); } } else { if (isset($payload['claims']['id_token'])) { if (array_key_exists('sub', $payload['claims']['id_token']) && isset($payload['claims']['id_token']['sub']['value'])) { $requested_userid_display = $payload['claims']['id_token']['sub']['value']; $requested_userid = unwrap_userid($payload['claims']['id_token']['sub']['value']); if (!db_get_user($requested_userid)) { throw new OidcException('invalid_request', 'Unrecognized userid in request'); } } } $merged_req = array_merge($_GET, $payload); if (!array_key_exists('max_age', $merged_req) && $client['default_max_age']) { $merged_req['max_age'] = $client['default_max_age']; } if ($merged_req['max_age']) { $merged_req['claims']['id_token']['auth_time'] = array('essential' => true); } if ((!$merged_req['claims']['id_token'] || !array_key_exists('auth_time', $merged_req['claims']['id_token'])) && $client['require_auth_time']) { $merged_req['claims']['id_token']['auth_time'] = array('essential' => true); } if (!$merged_req['claims']['id_token'] || !array_key_exists('acr', $merged_req['claims']['id_token'])) { if ($merged_req['acr_values']) { $merged_req['claims']['id_token']['acr'] = array('essential' => true, 'values' => explode(' ', $merged_req['acr_values'])); } elseif ($client['default_acr_values']) { $merged_req['claims']['id_token']['acr'] = array('essential' => true, 'values' => explode('|', $client['default_acr_values'])); } } $_SESSION['rpfA'] = $merged_req; log_debug("rpfA = %s", print_r($_SESSION['rpfA'], true)); foreach (array('client_id', 'response_type', 'scope', 'nonce', 'redirect_uri') as $key) { if (!isset($payload[$key])) { log_error("missing %s in payload => %s", $key, print_r($payload, true)); } // throw new OidcException('invalid_request', 'Request Object missing required parameters'); } log_debug("payload => %s", print_r($payload, true)); foreach ($payload as $key => $value) { if (isset($_REQUEST[$key]) && strcmp($_REQUEST[$key], $value)) { log_debug("key : %s value:%s", $key, print_r($value, true)); throw new OidcException('invalid_request', "Request Object Param Values do not match request '{$key}' '{$_REQUEST[$key]}' != '{$value}'"); } } } } else { if (isset($_GET['id_token_hint'])) { $cryptoError = ''; $payload = decrypt_verify_jwt($_REQUEST['id_token_hint'], $client, $cryptoError); if (!isset($payload)) { if ($cryptoError == 'error_decrypt') { throw new OidcException('invalid_request', 'Unable to decrypt request object'); } elseif ($cryptoError == 'error_sig') { throw new OidcException('invalid_request', 'Unable to verify request object signature'); } } else { $requested_userid_display = $payload['sub']; $requested_userid = unwrap_userid($payload['sub']); if (!db_get_user($requested_userid)) { throw new OidcException('invalid_request', 'Unrecognized userid in ID Token'); } } } else { if (isset($_GET['claims']['id_token']['sub']['value'])) { $requested_userid_display = $_GET['claims']['id_token']['sub']['value']; $requested_userid = unwrap_userid($_GET['claims']['id_token']['sub']['value']); if (!db_get_user($requested_userid)) { throw new OidcException('invalid_request', "Unrecognized userid in ID Token"); } } else { if (isset($_GET['login_hint'])) { $principal = $_GET['login_hint']; $at = strpos($principal, '@'); if ($at !== false) { error_log("EMAIL\n"); if ($at != 0) { // XRI // process email address list($principal, $domain) = explode('@', $principal); error_log("==> principal = {$principal} domain = {$domain}"); $port_pos = strpos($domain, ':'); if ($port_pos !== false) { $domain = substr($domain, 0, $port_pos); } $domain_parts = explode('.', $domain); $server_parts = explode('.', OP_SERVER_NAME); // check to see domain matches $domain_start = count($domain_parts) - 1; $server_start = count($server_parts) - 1; $domain_match = true; for ($i = $domain_start, $j = $server_start; $i >= 0 && $j >= 0; $i--, $j--) { if (strcasecmp($domain_parts[$i], $server_parts[$j]) != 0) { $domain_match = false; } } if ($domain_match) { $requested_userid_display = $principal; $requested_userid = unwrap_userid($requested_userid_display); if (!db_get_user($requested_userid)) { $requested_userid_display = NULL; $requested_userid = NULL; } } else { throw new OidcException('invalid_request', 'Unrecognized email domain'); } } } else { // name only $requested_userid_display = $_GET['login_hint']; $requested_userid = unwrap_userid($requested_userid_display); if (!db_get_user($requested_userid)) { $requested_userid_display = NULL; $requested_userid = NULL; } } } } } if (!array_key_exists('max_age', $_REQUEST) && $client['default_max_age']) { $_REQUEST['max_age'] = $client['default_max_age']; } if ($_REQUEST['max_age']) { $_REQUEST['claims']['id_token']['auth_time'] = array('essential' => true); } if ((!$_REQUEST['claims']['id_token'] || !array_key_exists('auth_time', $_REQUEST['claims']['id_token'])) && $client['require_auth_time']) { $_REQUEST['claims']['id_token']['auth_time'] = array('essential' => true); } if (!$_REQUEST['claims']['id_token'] || !array_key_exists('acr', $_REQUEST['claims']['id_token'])) { if ($_REQUEST['acr_values']) { $_REQUEST['claims']['id_token']['acr'] = array('essential' => true, 'values' => explode(' ', $_REQUEST['acr_values'])); } elseif ($client['default_acr_values']) { $_REQUEST['claims']['id_token']['acr'] = array('essential' => true, 'values' => explode('|', $client['default_acr_values'])); } } $_SESSION['rpfA'] = $_REQUEST; } log_debug("prompt = %s", $_SESSION['rpfA']['prompt']); $prompt = $_SESSION['rpfA']['prompt'] ? explode(' ', $_SESSION['rpfA']['prompt']) : array(); $num_prompts = count($prompt); if ($num_prompts > 1 && in_array('none', $prompt)) { throw new OidcException('interaction_required', "conflicting prompt parameters {$_SESSION['rpfA']['prompt']}"); } if (in_array('none', $prompt)) { $showUI = false; } else { $showUI = true; } log_debug("num prompt = %d %s", $num_prompts, print_r($prompt, true)); if ($_SESSION['username']) { if (in_array('login', $prompt)) { echo loginform($requested_userid_display, $requested_userid, $client); exit; } if (isset($_SESSION['rpfA']['max_age'])) { if (time() - $_SESSION['auth_time'] > $_SESSION['rpfA']['max_age']) { if (!$showUI) { throw new OidcException('interaction_required', 'max_age exceeded and prompt set to none'); } echo loginform($requested_userid_display, $requested_userid, $client); exit; } } if ($requested_userid) { if ($_SESSION['username'] != $requested_userid) { if (!$showUI) { // throw new OidcException('interaction_required', 'requested account is different from logged in account, no UI requested'); } else { // echo loginform($requested_userid_display, $requested_userid, $client); exit; } } } // if(in_array('consent', $prompt)){ // echo confirm_userinfo(); // exit(); // } if (!db_get_user_trusted_client($_SESSION['username'], $_REQUEST['client_id'])) { if (!$showUI) { throw new OidcException('interaction_required', 'consent needed and prompt set to none'); } echo confirm_userinfo(); } else { send_response_noRedirect($_SESSION['username'], true); } } else { // SBE Redirect to auth_time send_auth_response($request_uri, array(), $response_mode); // header("Location: /auth?client_id=$client_id&response_type=$_REQUEST['response_type']&scope=$_REQUEST['scope']&nonce=$_REQUEST['nonce']"); // if(!$showUI) // throw new OidcException('interaction_required', 'unauthenticated and prompt set to none'); // echo custom_loginform($requested_userid_display, $requested_userid, $client); } } catch (OidcException $e) { log_debug("handle_auth exception : %s", $e->getTraceAsString()); send_error($error_page, $e->error_code, $e->desc, NULL, $state, $response_mode); } catch (Exception $e) { log_debug("handle_auth exception : %s", $e->getTraceAsString()); send_error($error_page, 'invalid_request', $e->getMessage(), NULL, $state, $response_mode); } }