1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-12-24 23:48:39 +00:00
hashcat/src/folder.c

586 lines
12 KiB
C
Raw Normal View History

2016-09-07 10:45:08 +00:00
/**
* Author......: See docs/credits.txt
2016-09-07 10:45:08 +00:00
* License.....: MIT
*/
#include "common.h"
2016-09-16 15:01:18 +00:00
#include "types.h"
2016-09-07 10:45:08 +00:00
#include "memory.h"
#include "event.h"
2016-09-21 21:06:11 +00:00
#include "shared.h"
2016-09-07 10:45:08 +00:00
#include "folder.h"
#include <libgen.h>
2016-09-07 10:45:08 +00:00
#if defined (__APPLE__)
#include "event.h"
2016-09-07 10:45:08 +00:00
#endif
static int get_exec_path (char *exec_path, const size_t exec_path_sz)
2016-09-07 10:45:08 +00:00
{
2016-11-29 21:39:22 +00:00
#if defined (__linux__) || defined (__CYGWIN__)
2016-09-07 10:45:08 +00:00
char *tmp;
2016-09-07 10:45:08 +00:00
2016-12-23 23:40:40 +00:00
hc_asprintf (&tmp, "/proc/%d/exe", getpid ());
2016-09-07 10:45:08 +00:00
2016-11-17 05:17:28 +00:00
const ssize_t len = readlink (tmp, exec_path, exec_path_sz - 1);
2016-09-07 10:45:08 +00:00
hcfree (tmp);
if (len == -1) return -1;
#elif defined (_WIN)
2016-09-07 10:45:08 +00:00
memset (exec_path, 0, exec_path_sz);
2016-09-07 10:45:08 +00:00
const int len = 0;
#elif defined (__APPLE__)
2016-09-07 10:45:08 +00:00
u32 size = (u32) exec_path_sz;
2016-09-07 10:45:08 +00:00
if (_NSGetExecutablePath (exec_path, &size) != 0) return -1;
2016-09-07 10:45:08 +00:00
2016-09-30 16:09:29 +00:00
const size_t len = strlen (exec_path);
2016-09-07 10:45:08 +00:00
#elif defined (__FreeBSD__)
2016-09-07 10:45:08 +00:00
#include <sys/sysctl.h>
2016-09-07 10:45:08 +00:00
int mib[4];
2016-09-30 16:09:29 +00:00
2016-09-07 10:45:08 +00:00
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
size_t size = exec_path_sz;
2016-09-30 16:09:29 +00:00
sysctl (mib, 4, exec_path, &size, NULL, 0);
2016-09-07 10:45:08 +00:00
const size_t len = strlen (exec_path);
2016-09-07 10:45:08 +00:00
#else
#error Your Operating System is not supported or detected
#endif
exec_path[len] = 0;
return 0;
2016-09-07 10:45:08 +00:00
}
2016-10-30 17:55:27 +00:00
static void get_install_dir (char *install_dir, const char *exec_path)
2016-09-07 10:45:08 +00:00
{
strncpy (install_dir, exec_path, HCBUFSIZ_TINY - 1);
char *last_slash = NULL;
2016-09-07 10:45:08 +00:00
if ((last_slash = strrchr (install_dir, '/')) != NULL)
{
*last_slash = 0;
}
else if ((last_slash = strrchr (install_dir, '\\')) != NULL)
{
*last_slash = 0;
}
else
{
install_dir[0] = '.';
install_dir[1] = 0;
}
}
#if defined (_POSIX)
2016-10-30 17:55:27 +00:00
static void get_profile_dir (char *profile_dir, const char *home_dir)
2016-09-07 10:45:08 +00:00
{
snprintf (profile_dir, HCBUFSIZ_TINY, "%s/%s", home_dir, DOT_HASHCAT);
2020-06-16 18:05:29 +00:00
2021-06-05 18:41:24 +00:00
if (hc_path_is_directory (profile_dir)) return;
char *xdg_data_home = getenv ("XDG_DATA_HOME");
if (xdg_data_home)
2020-07-05 11:59:03 +00:00
{
2021-06-05 18:41:24 +00:00
snprintf (profile_dir, HCBUFSIZ_TINY, "%s/hashcat", xdg_data_home);
2020-07-05 11:59:03 +00:00
}
else
{
2021-06-05 18:41:24 +00:00
snprintf (profile_dir, HCBUFSIZ_TINY, "%s/.local/share/hashcat", home_dir);
}
2016-09-07 10:45:08 +00:00
}
2021-06-04 22:17:13 +00:00
static void get_cache_dir (char *cache_dir, const char *home_dir)
{
snprintf (cache_dir, HCBUFSIZ_TINY, "%s/%s", home_dir, DOT_HASHCAT);
2021-06-05 18:41:24 +00:00
if (hc_path_is_directory (cache_dir)) return;
char *xdg_cache_home = getenv ("XDG_CACHE_HOME");
if (xdg_cache_home)
2021-06-04 22:17:13 +00:00
{
2021-06-05 18:41:24 +00:00
snprintf (cache_dir, HCBUFSIZ_TINY, "%s/hashcat", xdg_cache_home);
2021-06-04 22:17:13 +00:00
}
else
{
2021-06-05 18:41:24 +00:00
snprintf (cache_dir, HCBUFSIZ_TINY, "%s/.cache/hashcat", home_dir);
2021-06-04 22:17:13 +00:00
}
}
2016-10-30 17:55:27 +00:00
static void get_session_dir (char *session_dir, const char *profile_dir)
2016-09-07 10:45:08 +00:00
{
snprintf (session_dir, HCBUFSIZ_TINY, "%s/%s", profile_dir, SESSIONS_FOLDER);
2016-09-07 10:45:08 +00:00
}
#endif
2016-09-07 10:45:08 +00:00
int count_dictionaries (char **dictionary_files)
{
if (dictionary_files == NULL) return 0;
int cnt = 0;
for (int d = 0; dictionary_files[d] != NULL; d++)
{
cnt++;
}
return (cnt);
}
char *first_file_in_directory (const char *path)
{
DIR *d;
if ((d = opendir (path)) != NULL)
{
char *first_file = NULL;
#if 0
struct dirent e;
for (;;)
{
memset (&e, 0, sizeof (e));
struct dirent *de = NULL;
if (readdir_r (d, &e, &de) != 0) break;
if (de == NULL) break;
#else
struct dirent *de;
while ((de = readdir (d)) != NULL)
{
#endif
if (de->d_name[0] == '.') continue;
first_file = strdup (de->d_name);
break;
}
closedir (d);
return first_file;
}
return NULL;
}
char **scan_directory (const char *path)
2016-09-07 10:45:08 +00:00
{
char *tmp_path = hcstrdup (path);
2016-09-07 10:45:08 +00:00
size_t tmp_path_len = strlen (tmp_path);
while (tmp_path[tmp_path_len - 1] == '/' || tmp_path[tmp_path_len - 1] == '\\')
{
tmp_path[tmp_path_len - 1] = 0;
tmp_path_len = strlen (tmp_path);
}
char **files = NULL;
size_t num_files = 0;
2016-09-07 10:45:08 +00:00
DIR *d = NULL;
if ((d = opendir (tmp_path)) != NULL)
{
#if 0
2016-09-07 10:45:08 +00:00
struct dirent e;
for (;;)
{
memset (&e, 0, sizeof (e));
struct dirent *de = NULL;
if (readdir_r (d, &e, &de) != 0) break;
2016-09-07 10:45:08 +00:00
if (de == NULL) break;
#else
struct dirent *de;
while ((de = readdir (d)) != NULL)
{
#endif
if (de->d_name[0] == '.') continue;
2016-09-07 10:45:08 +00:00
char *path_file;
2016-09-07 10:45:08 +00:00
2016-12-23 23:40:40 +00:00
hc_asprintf (&path_file, "%s/%s", tmp_path, de->d_name);
2016-09-07 10:45:08 +00:00
DIR *d_test;
if ((d_test = opendir (path_file)) != NULL)
{
closedir (d_test);
hcfree (path_file);
2016-09-07 10:45:08 +00:00
}
else
{
files = (char **) hcrealloc (files, (num_files + 1) * sizeof (char *), sizeof (char *));
2016-09-07 10:45:08 +00:00
files[num_files] = path_file;
2016-09-07 10:45:08 +00:00
num_files++;
2016-09-07 10:45:08 +00:00
}
}
closedir (d);
}
else if (errno == ENOTDIR)
{
files = (char **) hcrealloc (files, (num_files + 1) * sizeof (char *), sizeof (char *));
2016-09-07 10:45:08 +00:00
files[num_files] = hcstrdup (path);
2016-09-07 10:45:08 +00:00
num_files++;
2016-09-07 10:45:08 +00:00
}
files = (char **) hcrealloc (files, (num_files + 1) * sizeof (char *), sizeof (char *));
2016-09-07 10:45:08 +00:00
files[num_files] = NULL;
2016-09-07 10:45:08 +00:00
hcfree (tmp_path);
2016-09-07 10:45:08 +00:00
return (files);
}
2016-09-21 21:06:11 +00:00
int folder_config_init (hashcat_ctx_t *hashcat_ctx, MAYBE_UNUSED const char *install_folder, MAYBE_UNUSED const char *shared_folder)
2016-09-21 21:06:11 +00:00
{
2016-10-06 14:17:29 +00:00
folder_config_t *folder_config = hashcat_ctx->folder_config;
2016-09-21 21:06:11 +00:00
/**
* There's some buggy OpenCL runtime that do not support -I.
* A workaround is to chdir() to the OpenCL folder,
* then compile the kernels,
* then chdir() back to where we came from so we need to save it first
* - temporary disabled due to https://github.com/hashcat/hashcat/issues/2379
2016-09-21 21:06:11 +00:00
*/
char *cwd = (char *) hcmalloc (HCBUFSIZ_TINY);
2016-09-21 21:06:11 +00:00
if (getcwd (cwd, HCBUFSIZ_TINY - 1) == NULL)
{
event_log_error (hashcat_ctx, "getcwd(): %s", strerror (errno));
2016-09-21 21:06:11 +00:00
hcfree (cwd);
2016-09-21 21:06:11 +00:00
return -1;
}
/**
* folders, as discussed on https://github.com/hashcat/hashcat/issues/20
*/
const size_t exec_path_sz = 1024;
char *exec_path = (char *) hcmalloc (exec_path_sz);
const int rc = get_exec_path (exec_path, exec_path_sz);
2016-09-21 21:06:11 +00:00
if (rc == -1)
{
2017-04-02 07:50:06 +00:00
event_log_error (hashcat_ctx, "get_exec_path() failed.");
hcfree (cwd);
hcfree (exec_path);
return -1;
}
#if defined (_POSIX)
2016-09-21 21:06:11 +00:00
2016-10-30 17:55:27 +00:00
static const char SLASH[] = "/";
if (install_folder == NULL) install_folder = SLASH; // makes library use easier
2016-10-02 23:27:55 +00:00
2016-09-21 21:06:11 +00:00
char *resolved_install_folder = realpath (install_folder, NULL);
char *resolved_exec_path = realpath (exec_path, NULL);
if (resolved_install_folder == NULL) resolved_install_folder = hcstrdup (SLASH);
/*
This causes invalid error out if install_folder (/usr/local/bin) does not exist
2016-09-21 21:06:11 +00:00
if (resolved_install_folder == NULL)
{
event_log_error (hashcat_ctx, "%s: %s", resolved_install_folder, strerror (errno));
2016-09-21 21:06:11 +00:00
hcfree (cwd);
hcfree (exec_path);
hcfree (resolved_install_folder);
2016-09-21 21:06:11 +00:00
return -1;
}
*/
2016-09-21 21:06:11 +00:00
if (resolved_exec_path == NULL)
{
2019-06-26 13:52:11 +00:00
event_log_error (hashcat_ctx, "%s: %s", exec_path, strerror (errno));
2016-09-21 21:06:11 +00:00
hcfree (cwd);
hcfree (exec_path);
hcfree (resolved_install_folder);
2016-09-21 21:06:11 +00:00
return -1;
}
char *install_dir = (char *) hcmalloc (HCBUFSIZ_TINY);
get_install_dir (install_dir, resolved_exec_path);
2016-09-21 21:06:11 +00:00
char *profile_dir = NULL;
char *cache_dir = NULL;
2016-09-21 21:06:11 +00:00
char *session_dir = NULL;
char *shared_dir = NULL;
if (strcmp (install_dir, resolved_install_folder) == 0)
{
struct passwd pw;
struct passwd *pwp;
2016-09-21 21:06:11 +00:00
char buf[HCBUFSIZ_TINY];
getpwuid_r (getuid (), &pw, buf, HCBUFSIZ_TINY, &pwp);
const char *home_dir = pwp->pw_dir;
profile_dir = (char *) hcmalloc (HCBUFSIZ_TINY);
cache_dir = (char *) hcmalloc (HCBUFSIZ_TINY);
session_dir = (char *) hcmalloc (HCBUFSIZ_TINY);
2016-09-21 21:06:11 +00:00
get_profile_dir (profile_dir, home_dir);
get_cache_dir (cache_dir, home_dir);
get_session_dir (session_dir, profile_dir);
shared_dir = hcstrdup (shared_folder);
2016-09-21 21:06:11 +00:00
hc_mkdir_rec (profile_dir, 0700);
hc_mkdir_rec (cache_dir, 0700);
hc_mkdir (session_dir, 0700);
2016-09-21 21:06:11 +00:00
}
else
{
profile_dir = install_dir;
cache_dir = install_dir;
2016-09-21 21:06:11 +00:00
session_dir = install_dir;
shared_dir = install_dir;
}
hcfree (resolved_install_folder);
hcfree (resolved_exec_path);
2016-09-21 21:06:11 +00:00
#else
char *install_dir = hcmalloc (HCBUFSIZ_TINY);
get_install_dir (install_dir, exec_path);
2016-09-21 21:06:11 +00:00
char *profile_dir = install_dir;
char *cache_dir = install_dir;
2016-09-21 21:06:11 +00:00
char *session_dir = install_dir;
char *shared_dir = install_dir;
#endif
hcfree (exec_path);
2016-09-21 21:06:11 +00:00
/**
2017-04-02 07:50:06 +00:00
* There are a lot of problems related to bad support of -I parameters when building the kernel.
* Each OpenCL runtime handles it slightly differently.
* The most problematic is with new AMD drivers on Windows, which cannot handle quote characters!
* The best workaround found so far is to modify the TMP variable (only inside hashcat process) before the runtime is loaded.
2016-09-21 21:06:11 +00:00
*/
char *cpath;
2016-09-21 21:06:11 +00:00
#if defined (_WIN)
2016-12-23 23:40:40 +00:00
hc_asprintf (&cpath, "%s\\OpenCL\\", shared_dir);
2016-09-21 21:06:11 +00:00
char *cpath_real;
2016-09-21 21:06:11 +00:00
hc_asprintf (&cpath_real, "%s\\OpenCL\\", shared_dir);
2016-09-21 21:06:11 +00:00
#else
2016-12-23 23:40:40 +00:00
hc_asprintf (&cpath, "%s/OpenCL/", shared_dir);
2016-09-21 21:06:11 +00:00
char *cpath_real = (char *) hcmalloc (PATH_MAX);
2016-09-21 21:06:11 +00:00
if (realpath (cpath, cpath_real) == NULL)
{
event_log_error (hashcat_ctx, "%s: %s", cpath, strerror (errno));
2016-09-21 21:06:11 +00:00
hcfree (cwd);
hcfree (shared_dir);
// Attention: since hcfree () doesn't set the pointer to NULL, we need to do it externally such that
// we prevent double-freeing the same memory address (this happens if e.g. profile_dir == session_dir)
if (profile_dir == shared_dir) profile_dir = NULL;
if (cache_dir == shared_dir) cache_dir = NULL;
if (session_dir == shared_dir) session_dir = NULL;
shared_dir = NULL;
hcfree (profile_dir);
if (session_dir == profile_dir) session_dir = NULL;
if (cache_dir == profile_dir) cache_dir = NULL;
profile_dir = NULL;
2021-06-04 22:17:13 +00:00
hcfree (cache_dir);
if (session_dir == cache_dir) session_dir = NULL;
cache_dir = NULL;
hcfree (session_dir);
session_dir = NULL;
hcfree (cpath_real);
cpath_real = NULL;
2016-09-21 21:06:11 +00:00
return -1;
}
#endif
hcfree (cpath);
2016-09-21 21:06:11 +00:00
//if (getenv ("TMP") == NULL)
/* temporary disabled due to https://github.com/hashcat/hashcat/issues/2379
if (true)
2016-09-21 21:06:11 +00:00
{
char *tmp;
2016-09-21 21:06:11 +00:00
2016-12-23 23:40:40 +00:00
hc_asprintf (&tmp, "TMP=%s", cpath_real);
2016-09-21 21:06:11 +00:00
putenv (tmp);
}
*/
2016-09-21 21:06:11 +00:00
// not escaping here, using quotes later
2016-09-21 21:06:11 +00:00
// naive_escape (cpath_real, PATH_MAX, ' ', '\\');
#if defined (_WIN)
2016-09-21 21:06:11 +00:00
naive_replace (cpath_real, '\\', '/');
2016-09-21 21:06:11 +00:00
#endif
/**
* kernel cache, we need to make sure folder exist
*/
char *kernels_folder;
2016-09-21 21:06:11 +00:00
2021-06-04 22:17:13 +00:00
hc_asprintf (&kernels_folder, "%s/kernels", cache_dir);
2016-09-21 21:06:11 +00:00
2016-10-01 11:51:06 +00:00
hc_mkdir (kernels_folder, 0700);
2016-09-21 21:06:11 +00:00
hcfree (kernels_folder);
2016-09-21 21:06:11 +00:00
/**
* store for later use
*/
folder_config->cwd = cwd;
folder_config->install_dir = install_dir;
folder_config->profile_dir = profile_dir;
2021-06-04 22:17:13 +00:00
folder_config->cache_dir = cache_dir;
2016-09-21 21:06:11 +00:00
folder_config->session_dir = session_dir;
folder_config->shared_dir = shared_dir;
folder_config->cpath_real = cpath_real;
return 0;
}
2016-10-06 14:17:29 +00:00
void folder_config_destroy (hashcat_ctx_t *hashcat_ctx)
2016-09-21 21:06:11 +00:00
{
2016-10-06 14:17:29 +00:00
folder_config_t *folder_config = hashcat_ctx->folder_config;
hcfree (folder_config->cpath_real);
hcfree (folder_config->cwd);
hcfree (folder_config->install_dir);
2016-09-21 21:06:11 +00:00
memset (folder_config, 0, sizeof (folder_config_t));
2016-09-21 21:06:11 +00:00
}
2016-10-01 11:51:06 +00:00
int hc_mkdir (const char *name, MAYBE_UNUSED const int mode)
2016-10-01 11:51:06 +00:00
{
#if defined (_WIN)
return _mkdir (name);
#else
return mkdir (name, mode);
#endif
}
int hc_mkdir_rec (const char *path, MAYBE_UNUSED const int mode)
{
char *fullpath = hcstrdup (path);
char *subpath = dirname (fullpath);
if (strlen (subpath) > 1)
{
if (hc_mkdir_rec (subpath, mode) == -1) return -1;
}
if (hc_mkdir (path, mode) == -1)
{
if (errno != EEXIST) return -1;
}
hcfree (fullpath);
return 0;
}