diff options
Diffstat (limited to 'packages/google-compute-engine-oslogin/src/include/oslogin_utils.h')
-rw-r--r-- | packages/google-compute-engine-oslogin/src/include/oslogin_utils.h | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/packages/google-compute-engine-oslogin/src/include/oslogin_utils.h b/packages/google-compute-engine-oslogin/src/include/oslogin_utils.h new file mode 100644 index 0000000..6cd2024 --- /dev/null +++ b/packages/google-compute-engine-oslogin/src/include/oslogin_utils.h @@ -0,0 +1,202 @@ +// 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 <pthread.h> +#include <pwd.h> +#include <string> +#include <vector> + +#define TOTP "TOTP" +#define AUTHZEN "AUTHZEN" +#define INTERNAL_TWO_FACTOR "INTERNAL_TWO_FACTOR" +#define IDV_PREREGISTERED_PHONE "IDV_PREREGISTERED_PHONE" + +using std::string; +using std::vector; + +namespace oslogin_utils { + +// Metadata server URL. +static const char kMetadataServerUrl[] = + "http://metadata.google.internal/computeMetadata/v1/oslogin/"; + +// BufferManager encapsulates and manages a buffer and length. This class is not +// thread safe. +class BufferManager { + public: + // Create a BufferManager that will dole out chunks of buf as requested. + BufferManager(char* buf, size_t buflen); + + // Copies a string to the buffer and sets the buffer to point to that + // string. Copied string is guaranteed to be null-terminated. + // Returns false and sets errnop if there is not enough space left in the + // buffer for the string. + bool AppendString(const string& value, char** buffer, int* errnop); + + private: + // Return a pointer to a buffer of size bytes. + void* Reserve(size_t bytes); + // Whether there is space available in the buffer. + bool CheckSpaceAvailable(size_t bytes_to_write) const; + + char* buf_; + size_t buflen_; + + // Not copyable or assignable. + BufferManager& operator=(const BufferManager&); + BufferManager(const BufferManager&); +}; + +// Challenge represents a security challenge available to the user. +class Challenge { + public: + int id; + string type; + string status; +}; + +// NssCache caches passwd entries for getpwent_r. This is used to prevent making +// an HTTP call on every getpwent_r invocation. Stores up to cache_size entries +// at a time. This class is not thread safe. +class NssCache { + public: + explicit NssCache(int cache_size); + + // Clears and resets the NssCache. + void Reset(); + + // Whether the cache has a next passwd entry. + bool HasNextPasswd(); + + // Whether the cache has reached the last page of the database. + bool OnLastPage() { return on_last_page_; } + + // Grabs the next passwd entry. Returns true on success. Sets errnop on + // failure. + bool GetNextPasswd(BufferManager* buf, passwd* result, int* errnop); + + // Loads a json array of passwd entries in the cache, starting at the + // beginning of the cache. This will remove all previous entries in the cache. + // response is expected to be a JSON array of passwd entries. Returns + // true on success. + bool LoadJsonArrayToCache(string response); + + // Helper method that effectively implements the getpwent_r nss method. Each + // call will iterate through the OsLogin database and return the next entry. + // Internally, the cache will keep track of pages of passwd entries, and will + // make an http call to the server if necessary to retrieve additional + // entries. Returns whether passwd retrieval was successful. If true, the + // passwd result will contain valid data. + bool NssGetpwentHelper(BufferManager* buf, struct passwd* result, int* errnop); + + // Returns the page token for requesting the next page of passwd entries. + string GetPageToken() { return page_token_; } + + private: + // The maximum size of the cache. + int cache_size_; + + // Vector of passwds. These are represented as stringified json object. + std::vector<std::string> passwd_cache_; + + // The page token for requesting the next page of passwds. + std::string page_token_; + + // Index for requesting the next passwd from the cache. + int index_; + + // Whether the NssCache has reached the last page of the database. + bool on_last_page_; + + // Not copyable or assignable. + NssCache& operator=(const NssCache&); + NssCache(const NssCache&); +}; + +// Auto locks and unlocks a given mutex on construction/destruction. Does NOT +// take ownership of the mutex. +class MutexLock { + public: + explicit MutexLock(pthread_mutex_t* mutex) : mutex_(mutex) { + pthread_mutex_lock(mutex_); + } + + ~MutexLock() { pthread_mutex_unlock(mutex_); } + + private: + // The mutex to lock/unlock + pthread_mutex_t* const mutex_; + + // Not copyable or assignable. + MutexLock& operator=(const MutexLock); + MutexLock(const MutexLock&); +}; + +// Callback invoked when Curl completes a request. +size_t +OnCurlWrite(void* buf, size_t size, size_t nmemb, void* userp); + +// Uses Curl to issue a GET request to the given url. Returns whether the +// request was successful. If successful, the result from the server will be +// stored in response, and the HTTP response code will be stored in http_code. +bool HttpGet(const string& url, string* response, long* http_code); +bool HttpPost(const string& url, const string& data, string* response, + long* http_code); + +// Returns whether user_name is a valid OsLogin user name. +bool ValidateUserName(const string& user_name); + +// URL encodes the given parameter. Returns the encoded parameter. +std::string UrlEncode(const string& param); + +// Returns true if the given passwd contains valid fields. If pw_dir, pw_shell, +// or pw_passwd are not set, this will populate these entries with default +// values. +bool ValidatePasswd(struct passwd* result, BufferManager* buf, + int* errnop); + +// Parses a JSON LoginProfiles response for SSH keys. Returns a vector of valid +// ssh_keys. A key is considered valid if it's expiration date is greater than +// current unix time. +std::vector<string> ParseJsonToSshKeys(const string& json); + +// Parses a JSON LoginProfiles response and returns the email under the "name" +// field. +bool ParseJsonToKey(const string& json, const string& key, string* email); +bool ParseJsonToEmail(const string& json, string* email); + +// Parses a JSON LoginProfiles response and populates the passwd struct with the +// corresponding values set in the JSON object. Returns whether the parse was +// successful or not. If unsuccessful, errnop will also be set. +bool ParseJsonToPasswd(const string& response, struct passwd* result, + BufferManager* buf, int* errnop); + +// Parses a JSON adminLogin or login response and returns whether the user has +// the requested privilege. +bool ParseJsonToSuccess(const string& json); + +// Parses a JSON startSession response into a vector of Challenge objects. +bool ParseJsonToChallenges(const string& json, vector<Challenge> *challenges); + +// Calls the startSession API. +bool StartSession(const string& email, string* response); + +// Calls the continueSession API. +bool ContinueSession(bool alt, const string& email, const string& user_token, + const string& session_id, const Challenge& challenge, + string* response); + +// Returns user information from the metadata server. +bool GetUser(const string& username, string* response); +} // namespace oslogin_utils |