diff options
-rw-r--r-- | twrp-functions.cpp | 354 | ||||
-rw-r--r-- | twrp-functions.hpp | 21 |
2 files changed, 181 insertions, 194 deletions
diff --git a/twrp-functions.cpp b/twrp-functions.cpp index bbd3c4c9f..5145b2678 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -18,7 +18,7 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include <string> #include <unistd.h> #include <vector> #include <dirent.h> @@ -32,18 +32,20 @@ #include <sys/vfs.h> #include <sys/types.h> #include <sys/wait.h> -#ifdef ANDROID_RB_POWEROFF - #include "cutils/android_reboot.h" -#endif #include <iostream> #include <fstream> #include <sstream> #include "twrp-functions.hpp" -#include "partitions.hpp" #include "twcommon.h" +#ifndef BUILD_TWRPTAR_MAIN #include "data.hpp" +#include "partitions.hpp" #include "variables.h" #include "bootloader.h" +#ifdef ANDROID_RB_POWEROFF + #include "cutils/android_reboot.h" +#endif +#endif // ndef BUILD_TWRPTAR_MAIN #ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS #include "openaes/inc/oaes_lib.h" #endif @@ -115,6 +117,165 @@ string TWFunc::Get_Path(string Path) { return Path; } +int TWFunc::Wait_For_Child(pid_t pid, int *status, string Child_Name) { + pid_t rc_pid; + + rc_pid = waitpid(pid, status, 0); + if (rc_pid > 0) { + if (WEXITSTATUS(*status) == 0) + LOGINFO("%s process ended with RC=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Success + else if (WIFSIGNALED(*status)) { + LOGINFO("%s process ended with signal: %d\n", Child_Name.c_str(), WTERMSIG(*status)); // Seg fault or some other non-graceful termination + return -1; + } else if (WEXITSTATUS(*status) != 0) { + LOGINFO("%s process ended with ERROR=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Graceful exit, but there was an error + return -1; + } + } else { // no PID returned + if (errno == ECHILD) + LOGINFO("%s no child process exist\n", Child_Name.c_str()); + else { + LOGINFO("%s Unexpected error\n", Child_Name.c_str()); + return -1; + } + } + return 0; +} + +bool TWFunc::Path_Exists(string Path) { + // Check to see if the Path exists + struct stat st; + if (stat(Path.c_str(), &st) != 0) + return false; + else + return true; +} + +int TWFunc::Get_File_Type(string fn) { + string::size_type i = 0; + int firstbyte = 0, secondbyte = 0; + char header[3]; + + ifstream f; + f.open(fn.c_str(), ios::in | ios::binary); + f.get(header, 3); + f.close(); + firstbyte = header[i] & 0xff; + secondbyte = header[++i] & 0xff; + + if (firstbyte == 0x1f && secondbyte == 0x8b) + return 1; // Compressed + else if (firstbyte == 0x4f && secondbyte == 0x41) + return 2; // Encrypted + else + return 0; // Unknown + + return 0; +} + +int TWFunc::Try_Decrypting_File(string fn, string password) { +#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS + OAES_CTX * ctx = NULL; + uint8_t _key_data[32] = ""; + FILE *f; + uint8_t buffer[4096]; + uint8_t *buffer_out = NULL; + uint8_t *ptr = NULL; + size_t read_len = 0, out_len = 0; + int firstbyte = 0, secondbyte = 0, key_len; + size_t _j = 0; + size_t _key_data_len = 0; + + // mostly kanged from OpenAES oaes.c + for( _j = 0; _j < 32; _j++ ) + _key_data[_j] = _j + 1; + _key_data_len = password.size(); + if( 16 >= _key_data_len ) + _key_data_len = 16; + else if( 24 >= _key_data_len ) + _key_data_len = 24; + else + _key_data_len = 32; + memcpy(_key_data, password.c_str(), password.size()); + + ctx = oaes_alloc(); + if (ctx == NULL) { + LOGERR("Failed to allocate OAES\n"); + return -1; + } + + oaes_key_import_data(ctx, _key_data, _key_data_len); + + f = fopen(fn.c_str(), "rb"); + if (f == NULL) { + LOGERR("Failed to open '%s' to try decrypt\n", fn.c_str()); + return -1; + } + read_len = fread(buffer, sizeof(uint8_t), 4096, f); + if (read_len <= 0) { + LOGERR("Read size during try decrypt failed\n"); + fclose(f); + return -1; + } + if (oaes_decrypt(ctx, buffer, read_len, NULL, &out_len) != OAES_RET_SUCCESS) { + LOGERR("Error: Failed to retrieve required buffer size for trying decryption.\n"); + fclose(f); + return -1; + } + buffer_out = (uint8_t *) calloc(out_len, sizeof(char)); + if (buffer_out == NULL) { + LOGERR("Failed to allocate output buffer for try decrypt.\n"); + fclose(f); + return -1; + } + if (oaes_decrypt(ctx, buffer, read_len, buffer_out, &out_len) != OAES_RET_SUCCESS) { + LOGERR("Failed to decrypt file '%s'\n", fn.c_str()); + fclose(f); + free(buffer_out); + return 0; + } + fclose(f); + if (out_len < 2) { + LOGINFO("Successfully decrypted '%s' but read length %i too small.\n", fn.c_str(), out_len); + free(buffer_out); + return 1; // Decrypted successfully + } + ptr = buffer_out; + firstbyte = *ptr & 0xff; + ptr++; + secondbyte = *ptr & 0xff; + if (firstbyte == 0x1f && secondbyte == 0x8b) { + LOGINFO("Successfully decrypted '%s' and file is compressed.\n", fn.c_str()); + free(buffer_out); + return 3; // Compressed + } + if (out_len >= 262) { + ptr = buffer_out + 257; + if (strncmp((char*)ptr, "ustar", 5) == 0) { + LOGINFO("Successfully decrypted '%s' and file is tar format.\n", fn.c_str()); + free(buffer_out); + return 2; // Tar + } + } + free(buffer_out); + LOGINFO("No errors decrypting '%s' but no known file format.\n", fn.c_str()); + return 1; // Decrypted successfully +#else + LOGERR("Encrypted backup support not included.\n"); + return -1; +#endif +} + +unsigned long TWFunc::Get_File_Size(string Path) { + struct stat st; + + if (stat(Path.c_str(), &st) != 0) + return 0; + return st.st_size; +} + +#ifndef BUILD_TWRPTAR_MAIN + // Returns "/path" from a full /path/to/file.name string TWFunc::Get_Root_Path(string Path) { string Local_Path = Path; @@ -206,15 +367,6 @@ int TWFunc::Recursive_Mkdir(string Path) { return true; } -bool TWFunc::Path_Exists(string Path) { - // Check to see if the Path exists - struct stat st; - if (stat(Path.c_str(), &st) != 0) - return false; - else - return true; -} - void TWFunc::GUI_Operation_Text(string Read_Value, string Default_Text) { string Display_Text; @@ -237,14 +389,6 @@ void TWFunc::GUI_Operation_Text(string Read_Value, string Partition_Name, string DataManager::SetValue("tw_partition", Partition_Name); } -unsigned long TWFunc::Get_File_Size(string Path) { - struct stat st; - - if (stat(Path.c_str(), &st) != 0) - return 0; - return st.st_size; -} - void TWFunc::Copy_Log(string Source, string Destination) { PartitionManager.Mount_By_Path(Destination, false); FILE *destination_log = fopen(Destination.c_str(), "a"); @@ -478,30 +622,6 @@ int TWFunc::write_file(string fn, string& line) { return -1; } -vector<string> TWFunc::split_string(const string &in, char del, bool skip_empty) { - vector<string> res; - - if (in.empty() || del == '\0') - return res; - - string field; - istringstream f(in); - if (del == '\n') { - while(getline(f, field)) { - if (field.empty() && skip_empty) - continue; - res.push_back(field); - } - } else { - while(getline(f, field, del)) { - if (field.empty() && skip_empty) - continue; - res.push_back(field); - } - } - return res; -} - timespec TWFunc::timespec_diff(timespec& start, timespec& end) { timespec temp; @@ -810,121 +930,6 @@ bool TWFunc::Install_SuperSU(void) { return true; } -int TWFunc::Get_File_Type(string fn) { - string::size_type i = 0; - int firstbyte = 0, secondbyte = 0; - char header[3]; - - ifstream f; - f.open(fn.c_str(), ios::in | ios::binary); - f.get(header, 3); - f.close(); - firstbyte = header[i] & 0xff; - secondbyte = header[++i] & 0xff; - - if (firstbyte == 0x1f && secondbyte == 0x8b) - return 1; // Compressed - else if (firstbyte == 0x4f && secondbyte == 0x41) - return 2; // Encrypted - else - return 0; // Unknown - - return 0; -} - -int TWFunc::Try_Decrypting_File(string fn, string password) { -#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS - OAES_CTX * ctx = NULL; - uint8_t _key_data[32] = ""; - FILE *f; - uint8_t buffer[4096]; - uint8_t *buffer_out = NULL; - uint8_t *ptr = NULL; - size_t read_len = 0, out_len = 0; - int firstbyte = 0, secondbyte = 0, key_len; - size_t _j = 0; - size_t _key_data_len = 0; - - // mostly kanged from OpenAES oaes.c - for( _j = 0; _j < 32; _j++ ) - _key_data[_j] = _j + 1; - _key_data_len = password.size(); - if( 16 >= _key_data_len ) - _key_data_len = 16; - else if( 24 >= _key_data_len ) - _key_data_len = 24; - else - _key_data_len = 32; - memcpy(_key_data, password.c_str(), password.size()); - - ctx = oaes_alloc(); - if (ctx == NULL) { - LOGERR("Failed to allocate OAES\n"); - return -1; - } - - oaes_key_import_data(ctx, _key_data, _key_data_len); - - f = fopen(fn.c_str(), "rb"); - if (f == NULL) { - LOGERR("Failed to open '%s' to try decrypt\n", fn.c_str()); - return -1; - } - read_len = fread(buffer, sizeof(uint8_t), 4096, f); - if (read_len <= 0) { - LOGERR("Read size during try decrypt failed\n"); - fclose(f); - return -1; - } - if (oaes_decrypt(ctx, buffer, read_len, NULL, &out_len) != OAES_RET_SUCCESS) { - LOGERR("Error: Failed to retrieve required buffer size for trying decryption.\n"); - fclose(f); - return -1; - } - buffer_out = (uint8_t *) calloc(out_len, sizeof(char)); - if (buffer_out == NULL) { - LOGERR("Failed to allocate output buffer for try decrypt.\n"); - fclose(f); - return -1; - } - if (oaes_decrypt(ctx, buffer, read_len, buffer_out, &out_len) != OAES_RET_SUCCESS) { - LOGERR("Failed to decrypt file '%s'\n", fn.c_str()); - fclose(f); - free(buffer_out); - return 0; - } - fclose(f); - if (out_len < 2) { - LOGINFO("Successfully decrypted '%s' but read length %i too small.\n", fn.c_str(), out_len); - free(buffer_out); - return 1; // Decrypted successfully - } - ptr = buffer_out; - firstbyte = *ptr & 0xff; - ptr++; - secondbyte = *ptr & 0xff; - if (firstbyte == 0x1f && secondbyte == 0x8b) { - LOGINFO("Successfully decrypted '%s' and file is compressed.\n", fn.c_str()); - free(buffer_out); - return 3; // Compressed - } - if (out_len >= 262) { - ptr = buffer_out + 257; - if (strncmp((char*)ptr, "ustar", 5) == 0) { - LOGINFO("Successfully decrypted '%s' and file is tar format.\n", fn.c_str()); - free(buffer_out); - return 2; // Tar - } - } - free(buffer_out); - LOGINFO("No errors decrypting '%s' but no known file format.\n", fn.c_str()); - return 1; // Decrypted successfully -#else - LOGERR("Encrypted backup support not included.\n"); - return -1; -#endif -} - bool TWFunc::Try_Decrypting_Backup(string Restore_Path, string Password) { DIR* d; @@ -953,31 +958,6 @@ bool TWFunc::Try_Decrypting_Backup(string Restore_Path, string Password) { return true; } -int TWFunc::Wait_For_Child(pid_t pid, int *status, string Child_Name) { - pid_t rc_pid; - - rc_pid = waitpid(pid, status, 0); - if (rc_pid > 0) { - if (WEXITSTATUS(*status) == 0) - LOGINFO("%s process ended with RC=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Success - else if (WIFSIGNALED(*status)) { - LOGINFO("%s process ended with signal: %d\n", Child_Name.c_str(), WTERMSIG(*status)); // Seg fault or some other non-graceful termination - return -1; - } else if (WEXITSTATUS(*status) != 0) { - LOGINFO("%s process ended with ERROR=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Graceful exit, but there was an error - return -1; - } - } else { // no PID returned - if (errno == ECHILD) - LOGINFO("%s no child process exist\n", Child_Name.c_str()); - else { - LOGINFO("%s Unexpected error\n", Child_Name.c_str()); - return -1; - } - } - return 0; -} - string TWFunc::Get_Current_Date() { string Current_Date; time_t seconds = time(0); @@ -1132,3 +1112,5 @@ void TWFunc::Fixup_Time_On_Boot() settimeofday(&tv, NULL); #endif } + +#endif // ndef BUILD_TWRPTAR_MAIN diff --git a/twrp-functions.hpp b/twrp-functions.hpp index 50bfe2c3c..6e93805d9 100644 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -42,20 +42,26 @@ public: static string Get_Path(string Path); // Trims everything after the last / in the string static string Get_Filename(string Path); // Trims the path off of a filename + static int Exec_Cmd(const string& cmd, string &result); //execute a command and return the result as a string by reference + static int Exec_Cmd(const string& cmd); //execute a command + static int Wait_For_Child(pid_t pid, int *status, string Child_Name); // Waits for pid to exit and checks exit status + static bool Path_Exists(string Path); // Returns true if the path exists + static int Get_File_Type(string fn); // Determines file type, 0 for unknown, 1 for gzip, 2 for OAES encrypted + static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format + static unsigned long Get_File_Size(string Path); // Returns the size of a file + static vector<string> split_string(const string &in, char del, bool skip_empty); + +#ifndef BUILD_TWRPTAR_MAIN static void install_htc_dumlock(void); // Installs HTC Dumlock static void htc_dumlock_restore_original_boot(void); // Restores the backup of boot from HTC Dumlock static void htc_dumlock_reflash_recovery_to_boot(void); // Reflashes the current recovery to boot static int Recursive_Mkdir(string Path); // Recursively makes the entire path - static bool Path_Exists(string Path); // Returns true if the path exists static void GUI_Operation_Text(string Read_Value, string Default_Text); // Updates text for display in the GUI, e.g. Backing up %partition name% static void GUI_Operation_Text(string Read_Value, string Partition_Name, string Default_Text); // Same as above but includes partition name - static unsigned long Get_File_Size(string Path); // Returns the size of a file static void Update_Log_File(void); // Writes the log to last_log static void Update_Intent_File(string Intent); // Updates intent file static int tw_reboot(RebootCommand command); // Prepares the device for rebooting static void check_and_run_script(const char* script_file, const char* display_name); // checks for the existence of a script, chmods it to 755, then runs it - static int Exec_Cmd(const string& cmd, string &result); //execute a command and return the result as a string by reference - static int Exec_Cmd(const string& cmd); //execute a command static int removeDir(const string path, bool removeParent); //recursively remove a directory static int copy_file(string src, string dst, int mode); //copy file from src to dst with mode permissions static unsigned int Get_D_Type_From_Stat(string Path); // Returns a dirent dt_type value using stat instead of dirent @@ -69,11 +75,7 @@ public: static bool Fix_su_Perms(void); // sets proper permissions for su binaries and superuser apk static int tw_chmod(const string& fn, const string& mode); // chmod function that converts a 3 or 4 char string into st_mode automatically static bool Install_SuperSU(void); // Installs su binary and apk and sets proper permissions - static vector<string> split_string(const string &in, char del, bool skip_empty); - static int Get_File_Type(string fn); // Determines file type, 0 for unknown, 1 for gzip, 2 for OAES encrypted - static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format static bool Try_Decrypting_Backup(string Restore_Path, string Password); // true for success, false for failed to decrypt - static int Wait_For_Child(pid_t pid, int *status, string Child_Name); // Waits for pid to exit and checks exit status static string System_Property_Get(string Prop_Name); // Returns value of Prop_Name from reading /system/build.prop static string Get_Current_Date(void); // Returns the current date in ccyy-m-dd--hh-nn-ss format static void Auto_Generate_Backup_Name(); // Populates TW_BACKUP_NAME with a backup name based on current date and ro.build.display.id from /system/build.prop @@ -85,5 +87,8 @@ private: }; extern int Log_Offset; +#else +}; +#endif // ndef BUILD_TWRPTAR_MAIN #endif // _TWRPFUNCTIONS_HPP |