Added support for password encrypted zip archives

This commit is contained in:
TheFloW 2018-01-03 17:09:22 +01:00
parent ff7b185051
commit ad4f3020ce
15 changed files with 158 additions and 63 deletions

View File

@ -14,7 +14,7 @@ project(VitaShell)
include("${VITASDK}/share/vita.cmake" REQUIRED)
set(VITA_APP_NAME "VitaShell")
set(VITA_TITLEID "VITASHELL")
set(VITA_VERSION "01.78")
set(VITA_VERSION "01.79")
# Flags and includes
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-format-truncation -fno-lto")

View File

@ -99,6 +99,10 @@ The english language file is provided in **'VitaShellCustomization.rar'** and av
* sakya for Lightmp3
* Everybody who contributed on vitasdk
### Changelog 1.79 ###
- Added support for multi volume rar archives.
- Added support for password encrypted zip archives.
### Changelog 1.78 ###
- Fixed bug where archives > 2GB couldn't be opened.

View File

@ -25,6 +25,8 @@
static char archive_file[MAX_PATH_LENGTH];
static int archive_path_start = 0;
struct archive *archive_fd = NULL;
static int need_password = 0;
static char password[128];
int checkForUnsafeImports(void *buffer);
char *uncompressBuffer(const Elf32_Ehdr *ehdr, const Elf32_Phdr *phdr, const segment_info *segment,
@ -40,11 +42,11 @@ struct archive_data {
void *buffer;
int block_size;
};
/*
static const char *file_passphrase(struct archive *a, void *client_data) {
return "TODO";
return password;
}
*/
static int file_open(struct archive *a, void *client_data) {
struct archive_data *archive_data = client_data;
@ -136,7 +138,7 @@ struct archive *open_archive(const char *filename) {
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
// archive_read_set_passphrase_callback(a, file_passphrase);
archive_read_set_passphrase_callback(a, NULL, file_passphrase);
archive_read_set_open_callback(a, file_open);
archive_read_set_read_callback(a, file_read);
archive_read_set_skip_callback(a, file_skip);
@ -811,6 +813,19 @@ int ReadArchiveFile(const char *file, void *buf, int size) {
return read;
}
int archiveNeedPassword() {
return need_password;
}
void archiveClearPassword() {
memset(password, 0, sizeof(password));
}
void archiveSetPassword(char *string) {
strncpy(password, string, sizeof(password) - 1);
password[sizeof(password) - 1] = '\0';
}
int archiveClose() {
freeArchiveNodes(archive_root);
return 0;
@ -825,7 +840,12 @@ int archiveOpen(const char *file) {
struct archive *archive = open_archive(file);
if (!archive)
return -1;
// Need password?
need_password = 0;
if (archive_read_has_encrypted_entries(archive) == 1)
need_password = 1;
// Create archive root
archive_root = createArchiveNode("/", NULL, 1);
@ -841,6 +861,10 @@ int archiveOpen(const char *file) {
return -1;
}
// // Need password?
if (archive_entry_is_encrypted(archive_entry))
need_password = 1;
// Get entry information
const char *name = archive_entry_pathname(archive_entry);
const struct stat *stat = archive_entry_stat(archive_entry);

View File

@ -37,6 +37,9 @@ int ReadArchiveFile(const char *file, void *buf, int size);
int archiveClose();
int archiveOpen(const char *file);
int archiveNeedPassword();
void archiveClearPassword();
void archiveSetPassword(char *string);
int archiveCheckFilesForUnsafeFself();

View File

@ -71,7 +71,7 @@ static void utf8_to_utf16(const uint8_t *src, uint16_t *dst) {
*dst = '\0';
}
int initImeDialog(const char *title, const char *initial_text, int max_text_length, int type, int option) {
int initImeDialog(const char *title, const char *initial_text, int max_text_length, int type, int option, int password) {
if (ime_dialog_running)
return -1;
@ -92,6 +92,7 @@ int initImeDialog(const char *title, const char *initial_text, int max_text_leng
param.option = option;
if (option == SCE_IME_OPTION_MULTILINE)
param.dialogMode = SCE_IME_DIALOG_DIALOG_MODE_WITH_CANCEL;
param.textBoxMode = password ? SCE_IME_DIALOG_TEXTBOX_MODE_PASSWORD : SCE_IME_DIALOG_TEXTBOX_MODE_DEFAULT;
param.title = ime_title_utf16;
param.maxTextLength = max_text_length;
param.initialText = ime_initial_text_utf16;

View File

@ -24,7 +24,7 @@
#define IME_DIALOG_RESULT_FINISHED 2
#define IME_DIALOG_RESULT_CANCELED 3
int initImeDialog(const char *title, const char *initial_text, int max_text_length, int type, int option);
int initImeDialog(const char *title, const char *initial_text, int max_text_length, int type, int option, int password);
uint16_t *getImeDialogInputTextUTF16();
uint8_t *getImeDialogInputTextUTF8();
const char *getImeDialogInitialText();

View File

@ -250,6 +250,7 @@ void loadLanguage(int id) {
LANGUAGE_ENTRY(UPDATE_QUESTION),
LANGUAGE_ENTRY(ARCHIVE_NAME),
LANGUAGE_ENTRY(COMPRESSION_LEVEL),
LANGUAGE_ENTRY(ENTER_PASSWORD),
};
// Load default config file

View File

@ -209,6 +209,8 @@ enum LanguageContainer {
UPDATE_QUESTION,
ARCHIVE_NAME,
COMPRESSION_LEVEL,
ENTER_PASSWORD,
LANGUAGE_CONTAINER_SIZE,
};

151
main.c
View File

@ -316,7 +316,12 @@ static int handleFile(const char *file, FileListEntry *entry) {
break;
case FILE_TYPE_ARCHIVE:
archiveClearPassword();
res = archiveOpen(file);
if (res >= 0 && archiveNeedPassword()) {
initImeDialog(language_container[ENTER_PASSWORD], "", 128, SCE_IME_TYPE_BASIC_LATIN, 0, 1);
setDialogStep(DIALOG_STEP_ENTER_PASSWORD);
}
break;
default:
@ -512,7 +517,8 @@ static int dialogSteps() {
case DIALOG_STEP_INFO:
case DIALOG_STEP_SYSTEM:
{
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
setDialogStep(DIALOG_STEP_NONE);
}
@ -526,7 +532,8 @@ static int dialogSteps() {
case DIALOG_STEP_DELETED:
{
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
FileListEntry *file_entry = fileListGetNthEntry(&file_list, base_pos + rel_pos);
if (file_entry) {
// Empty mark list if on marked entry
@ -535,8 +542,9 @@ static int dialogSteps() {
}
refresh = REFRESH_MODE_NORMAL;
setDialogStep(DIALOG_STEP_NONE);
}
setDialogStep(DIALOG_STEP_NONE);
}
break;
@ -544,7 +552,8 @@ static int dialogSteps() {
case DIALOG_STEP_COMPRESSED:
{
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
FileListEntry *file_entry = fileListGetNthEntry(&file_list, base_pos + rel_pos);
if (file_entry) {
// Empty mark list if on marked entry
@ -556,8 +565,9 @@ static int dialogSteps() {
strcpy(focus_name, compress_name);
refresh = REFRESH_MODE_SETFOCUS;
setDialogStep(DIALOG_STEP_NONE);
}
setDialogStep(DIALOG_STEP_NONE);
}
break;
@ -566,7 +576,8 @@ static int dialogSteps() {
case DIALOG_STEP_COPIED:
case DIALOG_STEP_MOVED:
{
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
// Empty mark list
fileListEmpty(&mark_list);
@ -640,9 +651,8 @@ static int dialogSteps() {
sceMsgDialogClose();
}
} else {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
setDialogStep(DIALOG_STEP_NONE);
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (checkFileExist("sdstor0:uma-lp-act-entire")) {
int res = vshIoMount(0xF00, NULL, 0, 0, 0, 0);
if (res < 0)
@ -651,6 +661,8 @@ static int dialogSteps() {
infoDialog(language_container[USB_UMA0_MOUNTED]);
refresh = REFRESH_MODE_NORMAL;
}
setDialogStep(DIALOG_STEP_NONE);
}
}
@ -670,7 +682,8 @@ static int dialogSteps() {
}
}
} else {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
setDialogStep(DIALOG_STEP_NONE);
// Dialog
@ -711,7 +724,8 @@ static int dialogSteps() {
sceMsgDialogClose();
}
} else {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
setDialogStep(DIALOG_STEP_NONE);
SceUdcdDeviceState state;
@ -833,27 +847,30 @@ static int dialogSteps() {
setDialogStep(DIALOG_STEP_NONE);
} else {
FileListEntry *file_entry = fileListGetNthEntry(&file_list, base_pos + rel_pos);
if (file_entry) {
char old_name[MAX_NAME_LENGTH];
strcpy(old_name, file_entry->name);
removeEndSlash(old_name);
if (!file_entry) {
setDialogStep(DIALOG_STEP_NONE);
break;
}
char old_name[MAX_NAME_LENGTH];
strcpy(old_name, file_entry->name);
removeEndSlash(old_name);
if (strcasecmp(old_name, name) == 0) { // No change
setDialogStep(DIALOG_STEP_NONE);
if (strcasecmp(old_name, name) == 0) { // No change
setDialogStep(DIALOG_STEP_NONE);
} else {
char old_path[MAX_PATH_LENGTH];
char new_path[MAX_PATH_LENGTH];
snprintf(old_path, MAX_PATH_LENGTH - 1, "%s%s", file_list.path, old_name);
snprintf(new_path, MAX_PATH_LENGTH - 1, "%s%s", file_list.path, name);
int res = sceIoRename(old_path, new_path);
if (res < 0) {
errorDialog(res);
} else {
char old_path[MAX_PATH_LENGTH];
char new_path[MAX_PATH_LENGTH];
snprintf(old_path, MAX_PATH_LENGTH - 1, "%s%s", file_list.path, old_name);
snprintf(new_path, MAX_PATH_LENGTH - 1, "%s%s", file_list.path, name);
int res = sceIoRename(old_path, new_path);
if (res < 0) {
errorDialog(res);
} else {
refresh = REFRESH_MODE_NORMAL;
setDialogStep(DIALOG_STEP_NONE);
}
refresh = REFRESH_MODE_NORMAL;
setDialogStep(DIALOG_STEP_NONE);
}
}
}
@ -902,7 +919,7 @@ static int dialogSteps() {
} else {
strcpy(compress_name, name);
initImeDialog(language_container[COMPRESSION_LEVEL], "6", 1, SCE_IME_TYPE_NUMBER, 0);
initImeDialog(language_container[COMPRESSION_LEVEL], "6", 1, SCE_IME_TYPE_NUMBER, 0, 0);
setDialogStep(DIALOG_STEP_COMPRESS_LEVEL);
}
} else if (ime_result == IME_DIALOG_RESULT_CANCELED) {
@ -961,20 +978,23 @@ static int dialogSteps() {
if (msg_result == MESSAGE_DIALOG_RESULT_RUNNING) {
// User has confirmed desire to hash, get requested file entry
FileListEntry *file_entry = fileListGetNthEntry(&file_list, base_pos + rel_pos);
if (file_entry) {
// Place the full file path in cur_file
snprintf(cur_file, MAX_PATH_LENGTH - 1, "%s%s", file_list.path, file_entry->name);
HashArguments args;
args.file_path = cur_file;
setDialogStep(DIALOG_STEP_HASHING);
// Create a thread to run out actual sum
SceUID thid = sceKernelCreateThread("hash_thread", (SceKernelThreadEntry)hash_thread, 0x40, 0x100000, 0, 0, NULL);
if (thid >= 0)
sceKernelStartThread(thid, sizeof(HashArguments), &args);
if (!file_entry) {
setDialogStep(DIALOG_STEP_NONE);
break;
}
// Place the full file path in cur_file
snprintf(cur_file, MAX_PATH_LENGTH - 1, "%s%s", file_list.path, file_entry->name);
HashArguments args;
args.file_path = cur_file;
setDialogStep(DIALOG_STEP_HASHING);
// Create a thread to run out actual sum
SceUID thid = sceKernelCreateThread("hash_thread", (SceKernelThreadEntry)hash_thread, 0x40, 0x100000, 0, 0, NULL);
if (thid >= 0)
sceKernelStartThread(thid, sizeof(HashArguments), &args);
}
break;
@ -1050,15 +1070,16 @@ static int dialogSteps() {
case DIALOG_STEP_INSTALLED:
{
if (msg_result == MESSAGE_DIALOG_RESULT_NONE || msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (msg_result == MESSAGE_DIALOG_RESULT_NONE ||
msg_result == MESSAGE_DIALOG_RESULT_FINISHED) {
if (install_list.length > 0) {
initMessageDialog(MESSAGE_DIALOG_PROGRESS_BAR, language_container[INSTALLING]);
setDialogStep(DIALOG_STEP_INSTALL_CONFIRMED);
break;
}
setDialogStep(DIALOG_STEP_NONE);
refresh = REFRESH_MODE_NORMAL;
setDialogStep(DIALOG_STEP_NONE);
}
break;
@ -1215,6 +1236,42 @@ static int dialogSteps() {
break;
}
case DIALOG_STEP_ENTER_PASSWORD:
{
if (ime_result == IME_DIALOG_RESULT_FINISHED) {
char *password = (char *)getImeDialogInputTextUTF8();
if (password[0] == '\0') {
setDialogStep(DIALOG_STEP_NONE);
} else {
// TODO: verify password
archiveSetPassword(password);
FileListEntry *file_entry = fileListGetNthEntry(&file_list, base_pos + rel_pos);
if (!file_entry) {
setDialogStep(DIALOG_STEP_NONE);
break;
}
is_in_archive = 1;
dir_level_archive = dir_level;
snprintf(archive_path, MAX_PATH_LENGTH - 1, "%s%s", file_list.path, file_entry->name);
strcat(file_list.path, file_entry->name);
addEndSlash(file_list.path);
dirLevelUp();
refresh = REFRESH_MODE_NORMAL;
setDialogStep(DIALOG_STEP_NONE);
}
} else if (ime_result == IME_DIALOG_RESULT_CANCELED) {
setDialogStep(DIALOG_STEP_NONE);
}
break;
}
}
return refresh;
@ -1378,7 +1435,7 @@ static int fileBrowserMenuCtrl() {
int type = handleFile(cur_file, file_entry);
// Archive mode
if (type == FILE_TYPE_ARCHIVE) {
if (type == FILE_TYPE_ARCHIVE && getDialogStep() != DIALOG_STEP_ENTER_PASSWORD) {
is_in_archive = 1;
dir_level_archive = dir_level;

4
main.h
View File

@ -53,7 +53,7 @@
// VitaShell version major.minor
#define VITASHELL_VERSION_MAJOR 0x01
#define VITASHELL_VERSION_MINOR 0x78
#define VITASHELL_VERSION_MINOR 0x79
#define VITASHELL_VERSION ((VITASHELL_VERSION_MAJOR << 0x18) | (VITASHELL_VERSION_MINOR << 0x10))
@ -225,6 +225,8 @@ enum DialogSteps {
DIALOG_STEP_QR_DOWNLOADED_VPK,
DIALOG_STEP_QR_OPEN_WEBSITE,
DIALOG_STEP_QR_SHOW_CONTENTS,
DIALOG_STEP_ENTER_PASSWORD,
};
extern FileList file_list, mark_list, copy_list, install_list;

View File

@ -680,7 +680,7 @@ static int contextMenuMainEnterCallback(int sel, void *context) {
strcpy(name, file_entry->name);
removeEndSlash(name);
initImeDialog(language_container[RENAME], name, MAX_NAME_LENGTH, SCE_IME_TYPE_BASIC_LATIN, 0);
initImeDialog(language_container[RENAME], name, MAX_NAME_LENGTH, SCE_IME_TYPE_BASIC_LATIN, 0, 0);
setDialogStep(DIALOG_STEP_RENAME);
}
@ -718,7 +718,7 @@ static int contextMenuMainEnterCallback(int sel, void *context) {
count++;
}
initImeDialog(language_container[NEW_FOLDER], path + strlen(file_list.path), MAX_NAME_LENGTH, SCE_IME_TYPE_BASIC_LATIN, 0);
initImeDialog(language_container[NEW_FOLDER], path + strlen(file_list.path), MAX_NAME_LENGTH, SCE_IME_TYPE_BASIC_LATIN, 0, 0);
setDialogStep(DIALOG_STEP_NEW_FOLDER);
break;
}
@ -801,7 +801,7 @@ static int contextMenuMoreEnterCallback(int sel, void *context) {
// Append .zip extension
strcat(path, ".zip");
initImeDialog(language_container[ARCHIVE_NAME], path, MAX_NAME_LENGTH, SCE_IME_TYPE_BASIC_LATIN, 0);
initImeDialog(language_container[ARCHIVE_NAME], path, MAX_NAME_LENGTH, SCE_IME_TYPE_BASIC_LATIN, 0, 0);
setDialogStep(DIALOG_STEP_COMPRESS_NAME);
}

View File

@ -28,7 +28,7 @@
<frame id="frame4">
<liveitem>
<text align="left" text-align="left" word-wrap="off" ellipsis="on">
<str size="18" color="#ffffff" shadow="on">v1.78</str>
<str size="18" color="#ffffff" shadow="on">v1.79</str>
</text>
</liveitem>
</frame>

View File

@ -190,3 +190,4 @@ FTP_SERVER = "FTP server is now running at\ftp://%s:%i
UPDATE_QUESTION = "VitaShell %s is now available.\\Do you want to update the application?"
ARCHIVE_NAME = "Archive name"
COMPRESSION_LEVEL = "Compression level (0-9)"
ENTER_PASSWORD = "Enter password"

View File

@ -329,7 +329,7 @@ void settingsMenuCtrl() {
break;
case SETTINGS_OPTION_TYPE_STRING:
initImeDialog(language_container[option->name], option->string, option->size_string, SCE_IME_TYPE_EXTENDED_NUMBER, 0);
initImeDialog(language_container[option->name], option->string, option->size_string, SCE_IME_TYPE_EXTENDED_NUMBER, 0, 0);
setDialogStep(DIALOG_STEP_SETTINGS_STRING);
break;

4
text.c
View File

@ -359,7 +359,7 @@ static int contextMenuEnterCallback(int sel, void *context) {
switch (sel) {
case TEXT_MENU_ENTRY_SEARCH:
initImeDialog(language_container[ENTER_SEARCH_TERM], "", MAX_LINE_CHARACTERS, SCE_IME_TYPE_DEFAULT, 0);
initImeDialog(language_container[ENTER_SEARCH_TERM], "", MAX_LINE_CHARACTERS, SCE_IME_TYPE_DEFAULT, 0, 0);
state->search_term_input = 1;
break;
@ -761,7 +761,7 @@ int textViewer(const char *file) {
char line[MAX_LINE_CHARACTERS];
textReadLine(s->buffer, line_start, s->size, line);
initImeDialog(language_container[EDIT_LINE], line, MAX_LINE_CHARACTERS, SCE_IME_TYPE_DEFAULT, SCE_IME_OPTION_MULTILINE);
initImeDialog(language_container[EDIT_LINE], line, MAX_LINE_CHARACTERS, SCE_IME_TYPE_DEFAULT, SCE_IME_OPTION_MULTILINE, 0);
s->edit_line = s->base_pos+s->rel_pos;
}