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 db_delete_client($name) { $client = db_get_client($name); if ($client) { $client->Logs->delete(); $client->delete(); } }