From 84fcd8289fa70cb0a5bbd36126cb7b645d493e7f Mon Sep 17 00:00:00 2001 From: jsteube Date: Fri, 27 Jan 2017 14:50:39 +0100 Subject: [PATCH] Files: Do several file and folder checks on startup rather than when they are actually used to avoid related error after eventual intense operations --- docs/changes.txt | 1 + include/outfile.h | 1 - include/user_options.h | 2 + src/dictstat.c | 11 -- src/hashcat.c | 18 +-- src/logfile.c | 11 -- src/outfile.c | 75 ---------- src/outfile_check.c | 15 +- src/potfile.c | 10 +- src/user_options.c | 314 +++++++++++++++++++++++++++++++++++++++++ 10 files changed, 333 insertions(+), 125 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index dfd899036..cfc3b6441 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -38,6 +38,7 @@ - Building: Add SHARED variable to Makefile to choose if hashcat is build as static or shared binary (using libhashcat.so/hashcat.dll) - Building: Removed the use of RPATH on linker level - Events: Improved the maximum event message handling. event_log () will now also internally make sure that the message is properly terminated +- Files: Do several file and folder checks on startup rather than when they are actually used to avoid related error after eventual intense operations - Helper: Added functions to check existence, type, read- and write-permissions and rewrite sources to use them instead of stat() * changes v3.20 -> v3.30: diff --git a/include/outfile.h b/include/outfile.h index ef4b6b267..f364b4429 100644 --- a/include/outfile.h +++ b/include/outfile.h @@ -19,6 +19,5 @@ void outfile_destroy (hashcat_ctx_t *hashcat_ctx); int outfile_write_open (hashcat_ctx_t *hashcat_ctx); void outfile_write_close (hashcat_ctx_t *hashcat_ctx); int outfile_write (hashcat_ctx_t *hashcat_ctx, const char *out_buf, const unsigned char *plain_ptr, const u32 plain_len, const u64 crackpos, const unsigned char *username, const u32 user_len, char tmp_buf[HCBUFSIZ_LARGE]); -int outfile_and_hashfile (hashcat_ctx_t *hashcat_ctx); #endif // _OUTFILE_H diff --git a/include/user_options.h b/include/user_options.h index 8f050f255..3821f609a 100644 --- a/include/user_options.h +++ b/include/user_options.h @@ -28,4 +28,6 @@ u64 user_options_extra_amplifier (hashcat_ctx_t *hashcat_ctx); void user_options_logger (hashcat_ctx_t *hashcat_ctx); +int user_options_check_files (hashcat_ctx_t *hashcat_ctx); + #endif // _USER_OPTIONS_H diff --git a/src/dictstat.c b/src/dictstat.c index a39bc74aa..ee05e4740 100644 --- a/src/dictstat.c +++ b/src/dictstat.c @@ -49,17 +49,6 @@ int dictstat_init (hashcat_ctx_t *hashcat_ctx) hc_asprintf (&dictstat_ctx->filename, "%s/hashcat.dictstat", folder_config->profile_dir); - FILE *fp = fopen (dictstat_ctx->filename, "ab"); - - if (fp == NULL) - { - event_log_error (hashcat_ctx, "%s: %m", dictstat_ctx->filename); - - return -1; - } - - fclose (fp); - return 0; } diff --git a/src/hashcat.c b/src/hashcat.c index 3bd809485..3e48900c0 100644 --- a/src/hashcat.c +++ b/src/hashcat.c @@ -960,14 +960,6 @@ int hashcat_session_init (hashcat_ctx_t *hashcat_ctx, char *install_folder, char if (rc_outfile_init == -1) return -1; - /** - * Sanity check for hashfile vs outfile (should not point to the same physical file) - */ - - const int rc_outfile_and_hashfile = outfile_and_hashfile (hashcat_ctx); - - if (rc_outfile_and_hashfile == -1) return -1; - /** * potfile init * this is only setting path because potfile can be used in read and write mode depending on user options @@ -1002,6 +994,14 @@ int hashcat_session_init (hashcat_ctx_t *hashcat_ctx, char *install_folder, char if (rc_debugfile_init == -1) return -1; + /** + * Try to detect if all the files we're going to use are accessible in the mode we want them + */ + + const int rc_user_options_check_files = user_options_check_files (hashcat_ctx); + + if (rc_user_options_check_files == -1) return -1; + /** * Init OpenCL library loader */ @@ -1026,6 +1026,8 @@ int hashcat_session_init (hashcat_ctx_t *hashcat_ctx, char *install_folder, char if (rc_hwmon_init == -1) return -1; + // done + return 0; } diff --git a/src/logfile.c b/src/logfile.c index 6ba1aef1a..b35fefd3e 100644 --- a/src/logfile.c +++ b/src/logfile.c @@ -91,17 +91,6 @@ int logfile_init (hashcat_ctx_t *hashcat_ctx) logfile_ctx->enabled = true; - FILE *fp = fopen (logfile_ctx->logfile, "ab"); - - if (fp == NULL) - { - event_log_error (hashcat_ctx, "%s: %m", logfile_ctx->logfile); - - return -1; - } - - fclose (fp); - return 0; } diff --git a/src/outfile.c b/src/outfile.c index 52258de55..392f66096 100644 --- a/src/outfile.c +++ b/src/outfile.c @@ -295,12 +295,6 @@ int outfile_init (hashcat_ctx_t *hashcat_ctx) outfile_ctx->outfile_format = user_options->outfile_format; outfile_ctx->outfile_autohex = user_options->outfile_autohex; - const int rc = outfile_write_open (hashcat_ctx); - - if (rc == -1) return -1; - - outfile_write_close (hashcat_ctx); - return 0; } @@ -452,72 +446,3 @@ int outfile_write (hashcat_ctx_t *hashcat_ctx, const char *out_buf, const unsign return tmp_len; } - -int outfile_and_hashfile (hashcat_ctx_t *hashcat_ctx) -{ - outfile_ctx_t *outfile_ctx = hashcat_ctx->outfile_ctx; - user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; - - char *hashfile = user_options_extra->hc_hash; - - if (hashfile == NULL) return 0; - - char *outfile = outfile_ctx->filename; - - if (outfile == NULL) return 0; - - hc_stat_t tmpstat_outfile; - hc_stat_t tmpstat_hashfile; - - FILE *tmp_outfile_fp = fopen (outfile, "r"); - - if (tmp_outfile_fp) - { - hc_fstat (fileno (tmp_outfile_fp), &tmpstat_outfile); - - fclose (tmp_outfile_fp); - } - - FILE *tmp_hashfile_fp = fopen (hashfile, "r"); - - if (tmp_hashfile_fp) - { - hc_fstat (fileno (tmp_hashfile_fp), &tmpstat_hashfile); - - fclose (tmp_hashfile_fp); - } - - if (tmp_outfile_fp) - { - tmpstat_outfile.st_mode = 0; - tmpstat_outfile.st_nlink = 0; - tmpstat_outfile.st_uid = 0; - tmpstat_outfile.st_gid = 0; - tmpstat_outfile.st_rdev = 0; - tmpstat_outfile.st_atime = 0; - - tmpstat_hashfile.st_mode = 0; - tmpstat_hashfile.st_nlink = 0; - tmpstat_hashfile.st_uid = 0; - tmpstat_hashfile.st_gid = 0; - tmpstat_hashfile.st_rdev = 0; - tmpstat_hashfile.st_atime = 0; - - #if defined (_POSIX) - tmpstat_outfile.st_blksize = 0; - tmpstat_outfile.st_blocks = 0; - - tmpstat_hashfile.st_blksize = 0; - tmpstat_hashfile.st_blocks = 0; - #endif - - if (memcmp (&tmpstat_outfile, &tmpstat_hashfile, sizeof (hc_stat_t)) == 0) - { - event_log_error (hashcat_ctx, "Hashfile and Outfile are not allowed to point to the same file"); - - return -1; - } - } - - return 0; -} diff --git a/src/outfile_check.c b/src/outfile_check.c index 0a8715072..27957442c 100644 --- a/src/outfile_check.c +++ b/src/outfile_check.c @@ -356,18 +356,9 @@ int outcheck_ctx_init (hashcat_ctx_t *hashcat_ctx) outcheck_ctx->root_directory = user_options->outfile_check_dir; } - if (hc_path_exist (outcheck_ctx->root_directory) == true) - { - const bool is_dir = hc_path_is_directory (outcheck_ctx->root_directory); - - if (is_dir == false) - { - event_log_error (hashcat_ctx, "Directory specified in outfile-check '%s' is not a directory", outcheck_ctx->root_directory); + outcheck_ctx->enabled = true; - return -1; - } - } - else + if (hc_path_exist (outcheck_ctx->root_directory) == false) { if (hc_mkdir (outcheck_ctx->root_directory, 0700) == -1) { @@ -377,8 +368,6 @@ int outcheck_ctx_init (hashcat_ctx_t *hashcat_ctx) } } - outcheck_ctx->enabled = true; - return 0; } diff --git a/src/potfile.c b/src/potfile.c index ea172ac4e..9d4a03575 100644 --- a/src/potfile.c +++ b/src/potfile.c @@ -90,12 +90,6 @@ int potfile_init (hashcat_ctx_t *hashcat_ctx) potfile_ctx->fp = NULL; } - const int rc = potfile_write_open (hashcat_ctx); - - if (rc == -1) return -1; - - potfile_write_close (hashcat_ctx); - // starting from here, we should allocate some scratch buffer for later use u8 *out_buf = (u8 *) hcmalloc (HCBUFSIZ_LARGE); @@ -270,6 +264,10 @@ int potfile_remove_parse (hashcat_ctx_t *hashcat_ctx) if (potfile_ctx->enabled == false) return 0; + // if no potfile exists yet we don't need to do anything here + + if (hc_path_exist (potfile_ctx->filename) == false) return 0; + hash_t *hashes_buf = hashes->hashes_buf; u32 hashes_cnt = hashes->hashes_cnt; diff --git a/src/user_options.c b/src/user_options.c index d42e0a4a9..b8adf1ade 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -1261,6 +1261,320 @@ u64 user_options_extra_amplifier (hashcat_ctx_t *hashcat_ctx) return 1; } +int user_options_check_files (hashcat_ctx_t *hashcat_ctx) +{ + dictstat_ctx_t *dictstat_ctx = hashcat_ctx->dictstat_ctx; + folder_config_t *folder_config = hashcat_ctx->folder_config; + logfile_ctx_t *logfile_ctx = hashcat_ctx->logfile_ctx; + outcheck_ctx_t *outcheck_ctx = hashcat_ctx->outcheck_ctx; + outfile_ctx_t *outfile_ctx = hashcat_ctx->outfile_ctx; + potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; + user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; + user_options_t *user_options = hashcat_ctx->user_options; + + // common folders + + if (hc_path_read (folder_config->cwd) == false) + { + event_log_error (hashcat_ctx, "%s: %m", folder_config->cwd); + + return -1; + } + + if (hc_path_read (folder_config->install_dir) == false) + { + event_log_error (hashcat_ctx, "%s: %m", folder_config->install_dir); + + return -1; + } + + if (hc_path_read (folder_config->profile_dir) == false) + { + event_log_error (hashcat_ctx, "%s: %m", folder_config->profile_dir); + + return -1; + } + + if (hc_path_write (folder_config->session_dir) == false) + { + event_log_error (hashcat_ctx, "%s: %m", folder_config->session_dir); + + return -1; + } + + if (hc_path_read (folder_config->shared_dir) == false) + { + event_log_error (hashcat_ctx, "%s: %m", folder_config->shared_dir); + + return -1; + } + + if (hc_path_read (folder_config->cpath_real) == false) + { + event_log_error (hashcat_ctx, "%s: %m", folder_config->cpath_real); + + return -1; + } + + // hashfile - can be NULL + + if (user_options_extra->hc_hash != NULL) + { + if (hc_path_read (user_options_extra->hc_hash) == false) + { + event_log_error (hashcat_ctx, "%s: %m", user_options_extra->hc_hash); + + return -1; + } + } + + // arguments - checks must depend on attack_mode + + if (user_options->attack_mode == ATTACK_MODE_STRAIGHT) + { + for (int i = 0; i < user_options_extra->hc_workc; i++) + { + char *wlfile = user_options_extra->hc_workv[i]; + + if (hc_path_exist (wlfile) == false) + { + event_log_error (hashcat_ctx, "%s: %m", wlfile); + + return -1; + } + } + } + else if (user_options->attack_mode == ATTACK_MODE_COMBI) + { + // mode easy mode here because both files must exist and readable + + char *dictfile1 = user_options_extra->hc_workv[0]; + char *dictfile2 = user_options_extra->hc_workv[1]; + + if (hc_path_read (dictfile1) == false) + { + event_log_error (hashcat_ctx, "%s: %m", dictfile1); + + return -1; + } + + if (hc_path_read (dictfile2) == false) + { + event_log_error (hashcat_ctx, "%s: %m", dictfile2); + + return -1; + } + } + else if (user_options->attack_mode == ATTACK_MODE_BF) + { + // if the file exist it's a maskfile and then it must be readable + + char *maskfile = user_options_extra->hc_workv[0]; + + if (hc_path_exist (maskfile) == true) + { + if (hc_path_read (maskfile) == false) + { + event_log_error (hashcat_ctx, "%s: %m", maskfile); + + return -1; + } + } + } + else if (user_options->attack_mode == ATTACK_MODE_HYBRID1) + { + char *wlfile = user_options_extra->hc_workv[0]; + + char *maskfile = user_options_extra->hc_workv[1]; + + // for wordlist: can be folder + + if (hc_path_exist (wlfile) == false) + { + event_log_error (hashcat_ctx, "%s: %m", wlfile); + + return -1; + } + + // for mask: if the file exist it's a maskfile and then it must be readable + + if (hc_path_exist (maskfile) == true) + { + if (hc_path_read (maskfile) == false) + { + event_log_error (hashcat_ctx, "%s: %m", maskfile); + + return -1; + } + } + } + else if (user_options->attack_mode == ATTACK_MODE_HYBRID2) + { + char *wlfile = user_options_extra->hc_workv[1]; + + char *maskfile = user_options_extra->hc_workv[0]; + + // for wordlist: can be folder + + if (hc_path_exist (wlfile) == false) + { + event_log_error (hashcat_ctx, "%s: %m", wlfile); + + return -1; + } + + // for mask: if the file exist it's a maskfile and then it must be readable + + if (hc_path_exist (maskfile) == true) + { + if (hc_path_read (maskfile) == false) + { + event_log_error (hashcat_ctx, "%s: %m", maskfile); + + return -1; + } + } + } + + // logfile + + if (logfile_ctx->enabled == true) + { + if (hc_path_exist (logfile_ctx->logfile) == true) + { + if (hc_path_write (logfile_ctx->logfile) == false) + { + event_log_error (hashcat_ctx, "%s: %m", logfile_ctx->logfile); + + return -1; + } + } + } + + // outfile_check + + if (outcheck_ctx->enabled == true) + { + if (hc_path_exist (outcheck_ctx->root_directory) == true) + { + const bool is_dir = hc_path_is_directory (outcheck_ctx->root_directory); + + if (is_dir == false) + { + event_log_error (hashcat_ctx, "Directory specified in outfile-check '%s' is not a directory", outcheck_ctx->root_directory); + + return -1; + } + } + } + + // outfile - can be NULL + + if (outfile_ctx->filename != NULL) + { + if (hc_path_write (outfile_ctx->filename) == false) + { + event_log_error (hashcat_ctx, "%s: %m", outfile_ctx->filename); + + return -1; + } + + // check for hashfile vs outfile (should not point to the same physical file) + + char *hashfile = user_options_extra->hc_hash; + + char *outfile = outfile_ctx->filename; + + hc_stat_t tmpstat_outfile; + hc_stat_t tmpstat_hashfile; + + FILE *tmp_outfile_fp = fopen (outfile, "r"); + + if (tmp_outfile_fp) + { + hc_fstat (fileno (tmp_outfile_fp), &tmpstat_outfile); + + fclose (tmp_outfile_fp); + } + + FILE *tmp_hashfile_fp = fopen (hashfile, "r"); + + if (tmp_hashfile_fp) + { + hc_fstat (fileno (tmp_hashfile_fp), &tmpstat_hashfile); + + fclose (tmp_hashfile_fp); + } + + if (tmp_outfile_fp) + { + tmpstat_outfile.st_mode = 0; + tmpstat_outfile.st_nlink = 0; + tmpstat_outfile.st_uid = 0; + tmpstat_outfile.st_gid = 0; + tmpstat_outfile.st_rdev = 0; + tmpstat_outfile.st_atime = 0; + + tmpstat_hashfile.st_mode = 0; + tmpstat_hashfile.st_nlink = 0; + tmpstat_hashfile.st_uid = 0; + tmpstat_hashfile.st_gid = 0; + tmpstat_hashfile.st_rdev = 0; + tmpstat_hashfile.st_atime = 0; + + #if defined (_POSIX) + tmpstat_outfile.st_blksize = 0; + tmpstat_outfile.st_blocks = 0; + + tmpstat_hashfile.st_blksize = 0; + tmpstat_hashfile.st_blocks = 0; + #endif + + if (memcmp (&tmpstat_outfile, &tmpstat_hashfile, sizeof (hc_stat_t)) == 0) + { + event_log_error (hashcat_ctx, "Hashfile and Outfile are not allowed to point to the same file"); + + return -1; + } + } + } + + // potfile + + if (potfile_ctx->enabled == true) + { + if (hc_path_exist (potfile_ctx->filename) == true) + { + if (hc_path_write (potfile_ctx->filename) == false) + { + event_log_error (hashcat_ctx, "%s: %m", potfile_ctx->filename); + + return -1; + } + } + } + + // dictstat + + if (dictstat_ctx->enabled == true) + { + if (hc_path_write (dictstat_ctx->filename) == false) + { + event_log_error (hashcat_ctx, "%s: %m", dictstat_ctx->filename); + + return -1; + } + } + + // loopback - can't check at this point + + // tuning file check already done + + // debugfile check already done + + return 0; +} + void user_options_logger (hashcat_ctx_t *hashcat_ctx) { user_options_t *user_options = hashcat_ctx->user_options;