Skip to content

Commit 205bb8e

Browse files
cynthiajianga-maurice
authored andcommitted
[Auth] Add linux secure internal impl
+ Add linux implementation + Add kokoro support for libsecret + Add secure integration test + Modify the key_namespace to pass in empty if neither package name nor project id. + early out linux impl if empty key_namespace (that means from auth integration test, which we don't want to trigger auth persistence) PiperOrigin-RevId: 246212139
1 parent f5eadba commit 205bb8e

File tree

5 files changed

+190
-6
lines changed

5 files changed

+190
-6
lines changed

auth/src/desktop/auth_desktop.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -422,11 +422,22 @@ void ResetTokenRefreshCounter(AuthData* auth_data) {
422422
void InitializeUserDataPersist(AuthData* auth_data) {
423423
auto auth_impl = static_cast<AuthImpl*>(auth_data->auth_impl);
424424
// Combine bundle ID with project ID to create an app identifier.
425-
std::string app_identifier = auth_data->app->options().package_name();
426-
app_identifier += ".";
427-
app_identifier += auth_data->app->options().project_id();
425+
std::string package_name = auth_data->app->options().package_name();
426+
std::string project_id = auth_data->app->options().project_id();
427+
std::string app_identifier;
428+
429+
if (package_name.length() > 0) {
430+
app_identifier += package_name;
431+
if (project_id.length() > 0) {
432+
app_identifier += ".";
433+
app_identifier += project_id;
434+
}
435+
} else if (project_id.length() > 0) {
436+
app_identifier += project_id;
437+
}
428438
auth_impl->user_data_persist =
429439
MakeUnique<UserDataPersist>(app_identifier.c_str());
440+
430441
auth_data->auth->AddAuthStateListener(auth_impl->user_data_persist.get());
431442
auth_impl->user_data_persist->LoadUserData(auth_data);
432443
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "auth/src/desktop/secure/user_secure_linux_internal.h"
16+
17+
#include <dlfcn.h>
18+
19+
#include <iostream>
20+
21+
#include "auth/src/desktop/secure/user_secure_data_handle.h"
22+
23+
namespace firebase {
24+
namespace auth {
25+
namespace secure {
26+
27+
namespace {
28+
// key entry for the app name in the schema. When save the user data with a
29+
// given app name, the app name is the attribute of this key inside schema.
30+
const char kAppNameKey[] = "auth_app_name";
31+
// A common attribute-value pair is added to all the device keys. This makes it
32+
// possible to match all the keys easily (and remove them all at once).
33+
const char kCommonKeyId[] = "common_key_id";
34+
const char kCommonKeyValue[] = "common_key_value";
35+
36+
SecretSchema BuildSchema(const char key_namespace[]) {
37+
SecretSchema schema = {key_namespace,
38+
SECRET_SCHEMA_NONE,
39+
{
40+
{kAppNameKey, SECRET_SCHEMA_ATTRIBUTE_STRING},
41+
{kCommonKeyId, SECRET_SCHEMA_ATTRIBUTE_STRING},
42+
}};
43+
return schema;
44+
}
45+
} // namespace
46+
47+
UserSecureLinuxInternal::UserSecureLinuxInternal(const char* key_namespace)
48+
: key_namespace_(key_namespace),
49+
storage_schema_(BuildSchema(key_namespace)) {}
50+
51+
UserSecureLinuxInternal::~UserSecureLinuxInternal() {}
52+
53+
std::string UserSecureLinuxInternal::LoadUserData(const std::string& app_name) {
54+
std::string empty_str("");
55+
56+
if (key_namespace_.length() <= 0) {
57+
return empty_str;
58+
}
59+
60+
GError* error = nullptr;
61+
char* result =
62+
secret_password_lookup_sync(&storage_schema_,
63+
/* cancellable= */ nullptr,
64+
/* error= */ &error,
65+
/* key1= */ kAppNameKey,
66+
/* value1= */ app_name.c_str(), nullptr);
67+
if (error) {
68+
g_error_free(error);
69+
return empty_str;
70+
}
71+
72+
if (result == nullptr) {
73+
return empty_str;
74+
}
75+
std::string str_result(result);
76+
secret_password_free(result);
77+
78+
return str_result;
79+
}
80+
81+
void UserSecureLinuxInternal::SaveUserData(const std::string& app_name,
82+
const std::string& user_data) {
83+
if (key_namespace_.length() <= 0) {
84+
return;
85+
}
86+
secret_password_store_sync(
87+
&storage_schema_, SECRET_COLLECTION_DEFAULT, /* label= */ "UserSecure",
88+
/* password= */ user_data.c_str(), /* cancellable= */ nullptr,
89+
/* error= */ nullptr, /* key1= */ kAppNameKey,
90+
/* value1= */ app_name.c_str(),
91+
/* key2= */ kCommonKeyId, /* value2= */ kCommonKeyValue, nullptr);
92+
}
93+
94+
void UserSecureLinuxInternal::DeleteUserData(const std::string& app_name) {
95+
if (key_namespace_.length() <= 0) {
96+
return;
97+
}
98+
secret_password_clear_sync(&storage_schema_,
99+
/* cancellable= */ nullptr, /* error= */ nullptr,
100+
/* key1= */ kAppNameKey,
101+
/* value1= */ app_name.c_str(), nullptr);
102+
}
103+
104+
void UserSecureLinuxInternal::DeleteAllData() {
105+
if (key_namespace_.length() <= 0) {
106+
return;
107+
}
108+
secret_password_clear_sync(&storage_schema_, /* cancellable= */ nullptr,
109+
/* error= */ nullptr, /* key2= */ kCommonKeyId,
110+
/* value2= */ kCommonKeyValue, nullptr);
111+
}
112+
113+
} // namespace secure
114+
} // namespace auth
115+
} // namespace firebase
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef FIREBASE_AUTH_CLIENT_CPP_SRC_DESKTOP_SECURE_USER_SECURE_LINUX_INTERNAL_H_
16+
#define FIREBASE_AUTH_CLIENT_CPP_SRC_DESKTOP_SECURE_USER_SECURE_LINUX_INTERNAL_H_
17+
18+
#include <string>
19+
20+
#include "auth/src/desktop/secure/user_secure_data_handle.h"
21+
#include "auth/src/desktop/secure/user_secure_internal.h"
22+
#include "libsecret/secret.h"
23+
24+
namespace firebase {
25+
namespace auth {
26+
namespace secure {
27+
28+
// Linux specific implementation for the secure manager of user data.
29+
class UserSecureLinuxInternal : public UserSecureInternal {
30+
public:
31+
~UserSecureLinuxInternal() override;
32+
33+
// Overloaded constructor to set the storage schema for keys.
34+
explicit UserSecureLinuxInternal(const char* key_namespace);
35+
36+
std::string LoadUserData(const std::string& app_name) override;
37+
38+
void SaveUserData(const std::string& app_name,
39+
const std::string& user_data) override;
40+
41+
void DeleteUserData(const std::string& app_name) override;
42+
43+
void DeleteAllData() override;
44+
45+
private:
46+
const std::string key_namespace_;
47+
const SecretSchema storage_schema_;
48+
};
49+
50+
} // namespace secure
51+
} // namespace auth
52+
} // namespace firebase
53+
54+
#endif // FIREBASE_AUTH_CLIENT_CPP_SRC_DESKTOP_SECURE_USER_SECURE_LINUX_INTERNAL_H_

auth/src/desktop/secure/user_secure_manager.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
#define USER_SECURE_TYPE UserSecureDarwinInternal
3131

3232
#elif defined(__linux__)
33-
#include "auth/src/desktop/secure/user_secure_fake_internal.h"
34-
#define USER_SECURE_TYPE UserSecureFakeInternal
33+
#include "auth/src/desktop/secure/user_secure_linux_internal.h"
34+
#define USER_SECURE_TYPE UserSecureLinuxInternal
3535

3636
#else // Unknown platform, use fake version.
3737
#warning "No secure storage for Auth persistence is available on this platform."

auth/src/desktop/user_desktop.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,11 @@ UserDataPersist::UserDataPersist(
405405
: user_secure_manager_(std::move(user_secure_manager)) {}
406406

407407
void UserDataPersist::OnAuthStateChanged(Auth* auth) { // NOLINT
408-
SaveUserData(auth->auth_data_);
408+
if (auth->current_user() != nullptr) {
409+
SaveUserData(auth->auth_data_);
410+
} else {
411+
DeleteUserData(auth->auth_data_);
412+
}
409413
}
410414

411415
void AssignLoadedData(const Future<std::string>& future, void* auth_data) {

0 commit comments

Comments
 (0)