1515#include " auth/src/desktop/secure/user_secure_fake_internal.h"
1616
1717#if defined(_WIN32)
18+ #include < direct.h>
1819#include < windows.h>
1920#else
2021#include < dirent.h>
2122#include < sys/stat.h>
2223#include < sys/types.h>
2324#endif // defined(_WIN32)
2425
26+ #include < errno.h>
27+
2528#include < cstdio>
2629#include < fstream>
30+ #include < string>
2731
2832namespace firebase {
2933namespace auth {
3034namespace secure {
3135
36+ #if defined(_WIN32)
37+ static const char kDirectorySeparator [] = " \\ " ;
38+ #define unlink _unlink
39+ #define mkdir (x, y ) _mkdir(x)
40+ #define rmdir _rmdir
41+ #else
42+ static const char kDirectorySeparator [] = " /" ;
43+ #endif // defined(_WIN32)
44+
45+ static const char kFileExtension [] = " .authbin" ;
46+
3247UserSecureFakeInternal::UserSecureFakeInternal (const char * secure_path)
3348 : secure_path_(secure_path) {}
3449
@@ -41,11 +56,12 @@ std::string UserSecureFakeInternal::LoadUserData(const std::string& app_name) {
4156 std::ifstream infile;
4257 infile.open (filename, std::ios::binary);
4358 if (infile.fail ()) {
59+ LogDebug (" LoadUserData: Failed to read %s" , filename.c_str ());
4460 return " " ;
4561 }
4662
4763 infile.seekg (0 , std::ios::end);
48- int64_t length = infile.tellg ();
64+ size_t length = infile.tellg ();
4965 infile.seekg (0 , std::ios::beg);
5066 output.resize (length);
5167 infile.read (&*output.begin (), length);
@@ -59,11 +75,13 @@ std::string UserSecureFakeInternal::LoadUserData(const std::string& app_name) {
5975void UserSecureFakeInternal::SaveUserData (const std::string& app_name,
6076 const std::string& user_data) {
6177 // Make the directory in case it doesn't already exist, ignoring errors.
62- #if defined(_WIN32)
63- CreateDirectory (secure_path_.c_str (), NULL );
64- #else
65- mkdir (secure_path_.c_str (), 0700 );
66- #endif
78+ if (mkdir (secure_path_.c_str (), 0700 ) < 0 ) {
79+ int error = errno;
80+ if (error != 0 && error != EEXIST) {
81+ LogWarning (" SaveUserData: Couldn't create directory %s: %d" ,
82+ secure_path_.c_str (), error);
83+ }
84+ }
6785
6886 std::string filename = GetFilePath (app_name);
6987
@@ -88,41 +106,68 @@ void UserSecureFakeInternal::DeleteUserData(const std::string& app_name) {
88106}
89107
90108void UserSecureFakeInternal::DeleteAllData () {
109+ std::vector<std::string> files_to_delete;
91110#if defined(_WIN32)
111+ std::string file_spec =
112+ secure_path_ + kDirectorySeparator + " *" + kFileExtension ;
92113 WIN32_FIND_DATA file_data;
93- HANDLE handle = FindFirstFile (secure_path_ .c_str (), &file_data);
114+ HANDLE handle = FindFirstFile (file_spec .c_str (), &file_data);
94115 if (INVALID_HANDLE_VALUE == handle) {
116+ DWORD error = GetLastError ();
117+ if (error != ERROR_FILE_NOT_FOUND) {
118+ LogWarning (" DeleteAllData: Couldn't find file list matching %s: %d" ,
119+ file_spec.c_str (), error);
120+ }
95121 return ;
96122 }
97- DeleteFile (file_data.cFileName );
98- while (FindNextFile (handle, &file_data)) {
99- DeleteFile (file_data.cFileName );
100- }
123+ do {
124+ std::string file_path =
125+ secure_path_ + kDirectorySeparator + file_data.cFileName ;
126+ files_to_delete.push_back (file_path);
127+ } while (FindNextFile (handle, &file_data));
101128 FindClose (handle);
102- RemoveDirectory (secure_path_.c_str ());
103129#else
104130 // These are data types defined in the "dirent" header
105- DIR* theFolder = opendir (secure_path_.c_str ());
106- if (!theFolder ) {
131+ DIR* the_folder = opendir (secure_path_.c_str ());
132+ if (!the_folder ) {
107133 return ;
108134 }
109135 struct dirent * next_file;
110136
111- while ((next_file = readdir (theFolder)) != nullptr ) {
112- // build the path for each file in the folder
113- std::string filepath = secure_path_ + " /" ;
114- filepath.append (next_file->d_name );
115- unlink (filepath.c_str ());
137+ while ((next_file = readdir (the_folder)) != nullptr ) {
138+ // Only delete files matching the file extension.
139+ if (strcasestr (next_file->d_name , kFileExtension ) !=
140+ next_file->d_name + strlen (next_file->d_name ) -
141+ strlen (kFileExtension )) {
142+ continue ;
143+ }
144+ // Build the path for each file in the folder
145+ std::string file_path =
146+ secure_path_ + kDirectorySeparator + next_file->d_name ;
147+ files_to_delete.push_back (file_path);
116148 }
117- closedir (theFolder);
118-
119- // Remove the directory if it's empty, ignoring errors.
120- rmdir (secure_path_.c_str ());
149+ closedir (the_folder);
121150#endif
151+ for (int i = 0 ; i < files_to_delete.size (); ++i) {
152+ if (unlink (files_to_delete[i].c_str ()) == -1 ) {
153+ int error = errno;
154+ if (error != 0 ) {
155+ LogWarning (" DeleteAllData: Couldn't remove file %s: %d" ,
156+ files_to_delete[i].c_str (), error);
157+ }
158+ }
159+ }
160+ // Remove the directory if it's empty, ignoring errors.
161+ if (rmdir (secure_path_.c_str ()) == -1 ) {
162+ int error = errno;
163+ LogDebug (" DeleteAllData: Couldn't remove directory %s: %d" ,
164+ secure_path_.c_str (), error);
165+ }
122166}
123167
124168std::string UserSecureFakeInternal::GetFilePath (const std::string& app_name) {
125- std::string filepath = secure_path_ + " /" + app_name + " _bin" ;
169+ std::string filepath =
170+ secure_path_ + kDirectorySeparator + app_name + kFileExtension ;
126171 return filepath;
127172}
128173
0 commit comments