summaryrefslogtreecommitdiff
path: root/packages/google-compute-engine-oslogin/src/pam/pam_oslogin_login.cc
diff options
context:
space:
mode:
Diffstat (limited to 'packages/google-compute-engine-oslogin/src/pam/pam_oslogin_login.cc')
-rw-r--r--packages/google-compute-engine-oslogin/src/pam/pam_oslogin_login.cc273
1 files changed, 0 insertions, 273 deletions
diff --git a/packages/google-compute-engine-oslogin/src/pam/pam_oslogin_login.cc b/packages/google-compute-engine-oslogin/src/pam/pam_oslogin_login.cc
deleted file mode 100644
index 8ddec7b..0000000
--- a/packages/google-compute-engine-oslogin/src/pam/pam_oslogin_login.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2017 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#define PAM_SM_ACCOUNT
-#include <security/pam_appl.h>
-#include <security/pam_modules.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <string>
-#include <map>
-
-#include <compat.h>
-#include <oslogin_utils.h>
-
-using oslogin_utils::ContinueSession;
-using oslogin_utils::GetUser;
-using oslogin_utils::HttpGet;
-using oslogin_utils::HttpPost;
-using oslogin_utils::kMetadataServerUrl;
-using oslogin_utils::ParseJsonToChallenges;
-using oslogin_utils::ParseJsonToKey;
-using oslogin_utils::ParseJsonToEmail;
-using oslogin_utils::ParseJsonToSuccess;
-using oslogin_utils::StartSession;
-using oslogin_utils::UrlEncode;
-using oslogin_utils::ValidateUserName;
-
-static const char kUsersDir[] = "/var/google-users.d/";
-
-extern "C" {
-PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc,
- const char **argv) {
- const char *user_name;
- if (pam_get_user(pamh, &user_name, NULL) != PAM_SUCCESS) {
- PAM_SYSLOG(pamh, LOG_INFO, "Could not get pam user.");
- return PAM_AUTH_ERR;
- }
-
- if (!ValidateUserName(user_name)) {
- // Not a valid OS Login username.
- return PAM_IGNORE;
- }
-
- std::string users_filename = kUsersDir;
- users_filename.append(user_name);
- struct stat buffer;
- bool file_exists = !stat(users_filename.c_str(), &buffer);
-
- std::string str_user_name(user_name);
- std::stringstream url;
- url << kMetadataServerUrl << "users?username=" << UrlEncode(str_user_name);
-
- std::string response;
- long http_code = 0;
- if (!HttpGet(url.str(), &response, &http_code) || response.empty() ||
- http_code != 200) {
- if (http_code == 404) {
- // This module is only consulted for OS Login users.
- return PAM_IGNORE;
- }
-
- // Check local file for that user as a last resort.
- if (file_exists) {
- return PAM_PERM_DENIED;
- }
-
- // We can't confirm this is an OS Login user, ignore module.
- return PAM_IGNORE;
- }
-
- std::string email;
- if (!ParseJsonToEmail(response, &email) || email.empty()) {
- return PAM_AUTH_ERR;
- }
-
- url.str("");
- url << kMetadataServerUrl << "authorize?email=" << UrlEncode(email)
- << "&policy=login";
- if (HttpGet(url.str(), &response, &http_code) && http_code == 200 &&
- ParseJsonToSuccess(response)) {
- if (!file_exists) {
- std::ofstream users_file(users_filename.c_str());
- chown(users_filename.c_str(), 0, 0);
- chmod(users_filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP);
- }
- PAM_SYSLOG(pamh, LOG_INFO,
- "Organization user %s has login permission.",
- user_name);
- return PAM_SUCCESS;
- } else {
- if (file_exists) {
- remove(users_filename.c_str());
- }
- PAM_SYSLOG(pamh, LOG_INFO,
- "Organization user %s does not have login permission.",
- user_name);
-
- return PAM_PERM_DENIED;
- }
-}
-
-PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags, int argc,
- const char **argv) {
- return PAM_SUCCESS;
-}
-
-PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags,
- int argc, const char **argv)
-{
- const char* user_name;
- if (pam_get_user(pamh, &user_name, NULL) != PAM_SUCCESS) {
- PAM_SYSLOG(pamh, LOG_INFO, "Could not get pam user.");
- return PAM_PERM_DENIED;
- }
-
- std::string str_user_name(user_name);
- if (!ValidateUserName(user_name)) {
- return PAM_PERM_DENIED;
- }
-
- std::string response;
- if (!(GetUser(str_user_name, &response))) {
- return PAM_PERM_DENIED;
- }
-
- // System accounts begin with the prefix `sa_`.
- std::string sa_prefix = "sa_";
- if (str_user_name.compare(0, sa_prefix.size(), sa_prefix) == 0) {
- return PAM_SUCCESS;
- }
-
- std::string email;
- if (!ParseJsonToEmail(response, &email) || email.empty()) {
- return PAM_PERM_DENIED;
- }
-
- response = "";
- if (!StartSession(email, &response)) {
- PAM_SYSLOG(pamh, LOG_ERR,
- "Bad response from the two-factor start session request: %s",
- response.empty() ? "empty response" : response.c_str());
- return PAM_PERM_DENIED;
- }
-
- std::string status;
- if (!ParseJsonToKey(response, "status", &status)) {
- PAM_SYSLOG(pamh, LOG_ERR,
- "Failed to parse status from start session response");
- return PAM_PERM_DENIED;
- }
-
- if (status == "NO_AVAILABLE_CHALLENGES") {
- return PAM_SUCCESS; // User is not two-factor enabled.
- }
-
- std::string session_id;
- if (!ParseJsonToKey(response, "sessionId", &session_id)) {
- return PAM_PERM_DENIED;
- }
-
- std::vector<oslogin_utils::Challenge> challenges;
- if (!ParseJsonToChallenges(response, &challenges)) {
- PAM_SYSLOG(pamh, LOG_ERR,
- "Failed to parse challenge values from JSON response");
- return PAM_PERM_DENIED;
- }
-
- std::map<std::string,std::string> user_prompts;
- user_prompts[AUTHZEN] = "Google phone prompt";
- user_prompts[TOTP] = "Security code from Google Authenticator application";
- user_prompts[INTERNAL_TWO_FACTOR] = "Security code from security key";
- user_prompts[IDV_PREREGISTERED_PHONE] =
- "Voice or text message verification code";
-
- oslogin_utils::Challenge challenge;
- if (challenges.size() > 1) {
- std::stringstream prompt;
- prompt << "Available authentication methods: ";
- for(vector<oslogin_utils::Challenge>::size_type i = 0;
- i != challenges.size(); ++i)
- prompt << "\n" << i+1 << ": " << user_prompts[challenges[i].type];
- prompt << "\n\nEnter a number: ";
-
- char *choice = NULL;
- if (pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &choice, "%s",
- prompt.str().c_str()) != PAM_SUCCESS) {
- pam_error(pamh, "Unable to get user input");
- }
-
- int choicei;
- if (sscanf(choice, "%d", &choicei) == EOF) {
- pam_error(pamh, "Unable to get user input");
- }
- if (choicei > challenges.size()) {
- pam_error(pamh, "Invalid option");
- }
- challenge = challenges[choicei - 1];
- } else {
- challenge = challenges[0];
- }
-
- if (challenge.status != "READY") {
- // Call continueSession with the START_ALTERNATE flag.
- if (!ContinueSession(true, email, "", session_id, challenge, &response)) {
- PAM_SYSLOG(pamh, LOG_ERR,
- "Bad response from two-factor continue session request: %s",
- response.empty() ? "empty response" : response.c_str());
- return PAM_PERM_DENIED;
- }
- }
-
- char* user_token = NULL;
- if (challenge.type == INTERNAL_TWO_FACTOR) {
- if (pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &user_token,
- "Enter your security code: ") != PAM_SUCCESS) {
- pam_error(pamh, "Unable to get user input");
- }
- } else if (challenge.type == TOTP) {
- if (pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &user_token,
- "Enter your one-time password: ") != PAM_SUCCESS) {
- pam_error(pamh, "Unable to get user input");
- }
- } else if (challenge.type == AUTHZEN) {
- if (pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &user_token,
- "A login prompt has been sent to your enrolled device. "
- "Press enter to continue") != PAM_SUCCESS) {
- pam_error(pamh, "Unable to get user input");
- }
- } else if (challenge.type == IDV_PREREGISTERED_PHONE) {
- if (pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &user_token,
- "A security code has been sent to your phone. "
- "Enter code to continue: ") != PAM_SUCCESS) {
- pam_error(pamh, "Unable to get user input");
- }
- } else {
- PAM_SYSLOG(pamh, LOG_ERR, "Unsupported challenge type %s",
- challenge.type.c_str());
- return PAM_PERM_DENIED;
- }
-
- if (!ContinueSession(false, email, user_token, session_id, challenge,
- &response)) {
- PAM_SYSLOG(pamh, LOG_ERR,
- "Bad response from two-factor continue session request: %s",
- response.empty() ? "empty response" : response.c_str());
- return PAM_PERM_DENIED;
- }
-
- if (!ParseJsonToKey(response, "status", &status)
- || status != "AUTHENTICATED") {
- return PAM_PERM_DENIED;
- }
-
- return PAM_SUCCESS;
-}
-}