blob: 36f7eeda8feae5a94e9ebd0e57fdc7bbe97ce7a5 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "smbprovider/credential_store.h"
#include <libpasswordprovider/password.h>
namespace smbprovider {
namespace {
// Returns true if |buffer_length| is large enough to contain |str|.
bool CanBufferHoldString(const std::string& str, int32_t buffer_length) {
return static_cast<int32_t>(str.size()) + 1 <= buffer_length;
}
// Returns true if |buffer_length| is large enough to contain |password|.
bool CanBufferHoldPassword(
const std::unique_ptr<password_provider::Password>& password,
int32_t buffer_length) {
DCHECK(password);
return static_cast<int32_t>(password->size()) + 1 <= buffer_length;
}
// Copies |str| to |buffer| and adds a null terminator at the end.
void CopyStringToBuffer(const std::string& str, char* buffer) {
DCHECK(buffer);
strncpy(buffer, str.c_str(), str.size());
buffer[str.size()] = '\0';
}
// Copies |password| to |buffer| and adds a null terminator at the end.
void CopyPasswordToBuffer(
const std::unique_ptr<password_provider::Password>& password,
char* buffer) {
DCHECK(password);
DCHECK(buffer);
strncpy(buffer, password->GetRaw(), password->size());
buffer[password->size()] = '\0';
}
// Checks that the credentials can be inputted given the buffer sizes. Returns
// false if the buffers are too small or if the credentials are empty.
bool CanInputCredentials(int32_t workgroup_length,
int32_t username_length,
int32_t password_length,
const SmbCredentials& credentials) {
const std::string& workgroup = credentials.workgroup;
const std::string& username = credentials.username;
const bool empty_password = !credentials.password;
if (workgroup.empty() && username.empty() && empty_password) {
return false;
}
if (!CanBufferHoldString(workgroup, workgroup_length) ||
!CanBufferHoldString(username, username_length)) {
LOG(ERROR) << "Credential buffers are too small for input.";
return false;
}
if (!empty_password &&
!CanBufferHoldPassword(credentials.password, password_length)) {
LOG(ERROR) << "Password buffer is too small for input.";
return false;
}
return true;
}
// Sets the |credentials| into the specified buffers. CanInputCredentials()
// should be called first in order to verify the buffers can contain the
// credentials.
void SetCredentials(const SmbCredentials& credentials,
char* workgroup_buffer,
char* username_buffer,
char* password_buffer) {
DCHECK(workgroup_buffer);
DCHECK(username_buffer);
DCHECK(password_buffer);
CopyStringToBuffer(credentials.workgroup, workgroup_buffer);
CopyStringToBuffer(credentials.username, username_buffer);
if (credentials.password) {
CopyPasswordToBuffer(credentials.password, password_buffer);
}
}
} // namespace
CredentialStore::CredentialStore() = default;
CredentialStore::~CredentialStore() = default;
void CredentialStore::GetAuthentication(const std::string& share_path,
char* workgroup,
int32_t workgroup_length,
char* username,
int32_t username_length,
char* password,
int32_t password_length) const {
if (!HasCredentials(share_path)) {
return;
}
const SmbCredentials& credentials = GetCredentials(share_path);
if (!CanInputCredentials(workgroup_length, username_length, password_length,
credentials)) {
return;
}
SetCredentials(credentials, workgroup, username, password);
}
} // namespace smbprovider