summaryrefslogtreecommitdiff
path: root/packages/google-compute-engine-oslogin/src/authorized_keys/authorized_keys.cc
blob: 3eda59c7d1f7f6356fa43f668fc985954b040c26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// 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.

#include <iostream>
#include <sstream>
#include <string>

#include <oslogin_utils.h>

using std::cout;
using std::endl;
using std::string;

using oslogin_utils::HttpGet;
using oslogin_utils::ParseJsonToSuccess;
using oslogin_utils::ParseJsonToKey;
using oslogin_utils::ParseJsonToEmail;
using oslogin_utils::ParseJsonToSshKeys;
using oslogin_utils::UrlEncode;
using oslogin_utils::kMetadataServerUrl;

int main(int argc, char* argv[]) {
  if (argc != 2) {
    cout << "usage: authorized_keys [username]" << endl;
    return 1;
  }
  std::stringstream url;
  url << kMetadataServerUrl << "users?username=" << UrlEncode(argv[1]);
  string user_response;
  long http_code = 0;
  if (!HttpGet(url.str(), &user_response, &http_code) ||
      user_response.empty() || http_code != 200) {
    if (http_code == 404) {
      // Return 0 if the user is not an oslogin user. If we returned a failure
      // code, we would populate auth.log with useless error messages.
      return 0;
    }
    return 1;
  }
  string email;
  if (!ParseJsonToEmail(user_response, &email) || email.empty()) {
    return 1;
  }
  // Redundantly verify that this user has permission to log in to this VM.
  // Normally the PAM module determines this, but in the off chance a transient
  // error causes the PAM module to permit a user without login permissions,
  // perform the same check here. If this fails, we can guarantee that we won't
  // accidentally allow a user to log in without permissions.
  url.str("");
  url << kMetadataServerUrl << "authorize?email=" << UrlEncode(email)
      << "&policy=login";
  string auth_response;
  if (!HttpGet(url.str(), &auth_response, &http_code) || http_code != 200 ||
      auth_response.empty()) {
    return 1;
  }
  if (!ParseJsonToSuccess(auth_response)) {
    return 1;
  }
  // At this point, we've verified the user can log in. Grab the ssh keys from
  // the user response.
  std::vector<string> ssh_keys = ParseJsonToSshKeys(user_response);
  for (int i = 0; i < ssh_keys.size(); i++) {
    cout << ssh_keys[i] << endl;
  }
  return 0;
}