2016-06-27 10:13:46 +00:00
/**
2016-09-11 20:20:15 +00:00
* Author . . . . . . : See docs / credits . txt
2015-12-04 14:47:52 +00:00
* License . . . . . : MIT
*/
2016-09-07 20:29:57 +00:00
# if defined (__APPLE__)
2016-09-07 10:34:59 +00:00
# include <stdio.h>
2016-09-13 08:38:59 +00:00
# endif // __APPLE__
2016-09-07 10:34:59 +00:00
2016-09-07 09:16:31 +00:00
# include "common.h"
2016-09-28 21:33:44 +00:00
// basic tools
2016-09-06 20:25:54 +00:00
2016-09-06 17:44:27 +00:00
# include "types.h"
2016-09-28 22:23:24 +00:00
# include "folder.h"
# include "locking.h"
2016-09-28 21:33:44 +00:00
# include "logging.h"
2016-09-28 22:23:24 +00:00
# include "memory.h"
# include "shared.h"
# include "thread.h"
# include "timer.h"
2016-09-28 21:33:44 +00:00
// features
2016-09-24 19:44:43 +00:00
# include "affinity.h"
# include "autotune.h"
# include "bitmap.h"
2016-09-28 21:33:44 +00:00
# include "combinator.h"
2016-09-24 19:44:43 +00:00
# include "debugfile.h"
# include "dictstat.h"
# include "dispatch.h"
2016-09-16 15:01:18 +00:00
# include "hash_management.h"
2016-09-24 19:44:43 +00:00
# include "hwmon.h"
# include "induct.h"
# include "interface.h"
# include "logfile.h"
# include "loopback.h"
# include "monitor.h"
2016-09-06 11:52:26 +00:00
# include "mpsp.h"
2016-09-24 19:44:43 +00:00
# include "opencl.h"
# include "outfile_check.h"
2016-09-10 15:35:58 +00:00
# include "outfile.h"
2016-09-09 21:17:43 +00:00
# include "potfile.h"
2016-09-24 19:44:43 +00:00
# include "restore.h"
# include "rp.h"
# include "status.h"
2016-09-28 21:33:44 +00:00
# include "straight.h"
2016-09-24 19:44:43 +00:00
# include "terminal.h"
# include "tuningdb.h"
# include "usage.h"
2016-09-20 14:04:22 +00:00
# include "user_options.h"
2016-09-24 19:44:43 +00:00
# include "weak_hash.h"
# include "wordlist.h"
2016-09-06 09:49:26 +00:00
extern hc_global_data_t data ;
2015-12-04 14:47:52 +00:00
2016-09-06 09:52:02 +00:00
extern int SUPPRESS_OUTPUT ;
2016-09-08 07:21:25 +00:00
extern hc_thread_mutex_t mux_hwmon ;
extern hc_thread_mutex_t mux_display ;
2016-08-31 01:13:41 +00:00
2016-09-27 09:09:17 +00:00
extern const int DEFAULT_BENCHMARK_ALGORITHMS_CNT ;
2016-09-12 08:16:42 +00:00
extern const int DEFAULT_BENCHMARK_ALGORITHMS_BUF [ ] ;
2016-09-28 21:53:46 +00:00
const int comptime = COMPTIME ;
const char * version_tag = VERSION_TAG ;
2016-09-24 10:29:07 +00:00
2016-09-28 20:28:44 +00:00
static int inner1_loop ( user_options_t * user_options , user_options_extra_t * user_options_extra , restore_ctx_t * restore_ctx , logfile_ctx_t * logfile_ctx , induct_ctx_t * induct_ctx , dictstat_ctx_t * dictstat_ctx , loopback_ctx_t * loopback_ctx , opencl_ctx_t * opencl_ctx , hwmon_ctx_t * hwmon_ctx , hashconfig_t * hashconfig , hashes_t * hashes , wl_data_t * wl_data , straight_ctx_t * straight_ctx , combinator_ctx_t * combinator_ctx , mask_ctx_t * mask_ctx )
2016-09-23 20:51:42 +00:00
{
//opencl_ctx->run_main_level1 = true;
2016-09-26 15:15:07 +00:00
//opencl_ctx->run_main_level2 = true;
2016-09-23 20:51:42 +00:00
opencl_ctx - > run_main_level3 = true ;
opencl_ctx - > run_thread_level1 = true ;
opencl_ctx - > run_thread_level2 = true ;
2016-09-22 20:40:47 +00:00
/**
2016-09-23 20:51:42 +00:00
* word len
2016-09-22 20:40:47 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
uint pw_min = hashconfig_general_pw_min ( hashconfig ) ;
uint pw_max = hashconfig_general_pw_max ( hashconfig ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
/**
* If we have a NOOP rule then we can process words from wordlists > length 32 for slow hashes
*/
2016-09-27 11:13:07 +00:00
const bool has_noop = kernel_rules_has_noop ( straight_ctx - > kernel_rules_buf , straight_ctx - > kernel_rules_cnt ) ;
2016-09-23 20:51:42 +00:00
2016-09-25 12:53:57 +00:00
if ( has_noop = = false )
2016-09-23 20:51:42 +00:00
{
switch ( user_options_extra - > attack_kern )
{
case ATTACK_KERN_STRAIGHT : if ( pw_max > PW_DICTMAX ) pw_max = PW_DICTMAX1 ;
break ;
case ATTACK_KERN_COMBI : if ( pw_max > PW_DICTMAX ) pw_max = PW_DICTMAX1 ;
break ;
}
}
else
{
if ( hashconfig - > attack_exec = = ATTACK_EXEC_INSIDE_KERNEL )
{
switch ( user_options_extra - > attack_kern )
{
case ATTACK_KERN_STRAIGHT : if ( pw_max > PW_DICTMAX ) pw_max = PW_DICTMAX1 ;
break ;
case ATTACK_KERN_COMBI : if ( pw_max > PW_DICTMAX ) pw_max = PW_DICTMAX1 ;
break ;
}
}
else
{
// in this case we can process > 32
2015-12-04 14:47:52 +00:00
}
2016-09-23 20:51:42 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-24 10:05:56 +00:00
/**
2016-09-27 16:32:09 +00:00
* Update attack - mode specific stuff
2016-09-24 10:05:56 +00:00
*/
2016-09-27 16:32:09 +00:00
if ( user_options_extra - > attack_kern = = ATTACK_KERN_COMBI )
2016-09-26 15:15:07 +00:00
{
2016-09-27 16:32:09 +00:00
if ( user_options - > attack_mode = = ATTACK_MODE_COMBI )
2016-09-26 15:15:07 +00:00
{
2016-09-27 16:32:09 +00:00
// nothing yet
2016-09-23 20:51:42 +00:00
}
2016-09-27 18:02:12 +00:00
else if ( ( user_options - > attack_mode = = ATTACK_MODE_HYBRID1 ) | | ( user_options - > attack_mode = = ATTACK_MODE_HYBRID2 ) )
2016-09-23 20:51:42 +00:00
{
2016-09-27 16:32:09 +00:00
mask_ctx - > mask = mask_ctx - > masks [ mask_ctx - > masks_pos ] ;
2016-09-27 18:02:12 +00:00
const int rc_mask_file = mask_ctx_parse_maskfile ( mask_ctx , user_options , hashconfig ) ;
if ( rc_mask_file = = - 1 ) return - 1 ;
2016-09-27 16:32:09 +00:00
2016-09-26 15:15:07 +00:00
mask_ctx - > css_buf = mp_gen_css ( mask_ctx - > mask , strlen ( mask_ctx - > mask ) , mask_ctx - > mp_sys , mask_ctx - > mp_usr , & mask_ctx - > css_cnt , hashconfig , user_options ) ;
2016-09-16 15:31:31 +00:00
2016-09-26 15:15:07 +00:00
uint uniq_tbls [ SP_PW_MAX ] [ CHARSIZ ] = { { 0 } } ;
2016-09-16 15:31:31 +00:00
2016-09-26 15:15:07 +00:00
mp_css_to_uniq_tbl ( mask_ctx - > css_cnt , mask_ctx - > css_buf , uniq_tbls ) ;
2016-09-16 15:31:31 +00:00
2016-09-26 15:15:07 +00:00
sp_tbl_to_css ( mask_ctx - > root_table_buf , mask_ctx - > markov_table_buf , mask_ctx - > root_css_buf , mask_ctx - > markov_css_buf , user_options - > markov_threshold , uniq_tbls ) ;
2016-09-16 15:31:31 +00:00
2016-09-27 16:32:09 +00:00
combinator_ctx - > combs_cnt = sp_get_sum ( 0 , mask_ctx - > css_cnt , mask_ctx - > root_css_buf ) ;
2016-09-16 15:31:31 +00:00
2016-09-27 09:43:05 +00:00
const int rc_update_mp = opencl_session_update_mp ( opencl_ctx , mask_ctx ) ;
2016-09-16 15:31:31 +00:00
2016-09-27 09:43:05 +00:00
if ( rc_update_mp = = - 1 ) return - 1 ;
2016-09-23 20:51:42 +00:00
}
2016-09-27 16:32:09 +00:00
//const int rc_update_combinator = opencl_session_update_combinator (opencl_ctx, hashconfig, combinator_ctx);
//if (rc_update_combinator == -1) return -1;
}
else if ( user_options_extra - > attack_kern = = ATTACK_KERN_BF )
{
mask_ctx - > mask = mask_ctx - > masks [ mask_ctx - > masks_pos ] ;
2016-09-27 18:02:12 +00:00
const int rc_mask_file = mask_ctx_parse_maskfile ( mask_ctx , user_options , hashconfig ) ;
if ( rc_mask_file = = - 1 ) return - 1 ;
2016-09-27 16:32:09 +00:00
if ( user_options - > attack_mode = = ATTACK_MODE_BF ) // always true
2015-12-07 20:37:12 +00:00
{
2016-09-26 15:15:07 +00:00
mask_ctx - > css_buf = mp_gen_css ( mask_ctx - > mask , strlen ( mask_ctx - > mask ) , mask_ctx - > mp_sys , mask_ctx - > mp_usr , & mask_ctx - > css_cnt , hashconfig , user_options ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
if ( hashconfig - > opts_type & OPTS_TYPE_PT_UNICODE )
{
u32 css_cnt_unicode = mask_ctx - > css_cnt * 2 ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
cs_t * css_buf_unicode = ( cs_t * ) mycalloc ( css_cnt_unicode , sizeof ( cs_t ) ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
for ( uint i = 0 , j = 0 ; i < mask_ctx - > css_cnt ; i + = 1 , j + = 2 )
{
memcpy ( & css_buf_unicode [ j + 0 ] , & mask_ctx - > css_buf [ i ] , sizeof ( cs_t ) ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
css_buf_unicode [ j + 1 ] . cs_buf [ 0 ] = 0 ;
css_buf_unicode [ j + 1 ] . cs_len = 1 ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
myfree ( mask_ctx - > css_buf ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
mask_ctx - > css_buf = css_buf_unicode ;
mask_ctx - > css_cnt = css_cnt_unicode ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
// check if mask is not too large or too small for pw_min/pw_max (*2 if unicode)
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
uint mask_min = pw_min ;
uint mask_max = pw_max ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
if ( hashconfig - > opts_type & OPTS_TYPE_PT_UNICODE )
{
mask_min * = 2 ;
mask_max * = 2 ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
if ( ( mask_ctx - > css_cnt < mask_min ) | | ( mask_ctx - > css_cnt > mask_max ) )
{
if ( mask_ctx - > css_cnt < mask_min )
{
log_info ( " WARNING: Skipping mask '%s' because it is smaller than the minimum password length " , mask_ctx - > mask ) ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
if ( mask_ctx - > css_cnt > mask_max )
{
log_info ( " WARNING: Skipping mask '%s' because it is larger than the maximum password length " , mask_ctx - > mask ) ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
// skip to next mask
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_msg ( " STOP " ) ;
2016-09-24 12:00:59 +00:00
2016-09-26 15:15:07 +00:00
return 0 ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
u32 css_cnt_orig = mask_ctx - > css_cnt ;
if ( hashconfig - > opti_type & OPTI_TYPE_SINGLE_HASH )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
if ( hashconfig - > opti_type & OPTI_TYPE_APPENDED_SALT )
{
uint salt_len = ( uint ) hashes - > salts_buf [ 0 ] . salt_len ;
char * salt_buf = ( char * ) hashes - > salts_buf [ 0 ] . salt_buf ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
uint css_cnt_salt = mask_ctx - > css_cnt + salt_len ;
2015-12-07 20:37:12 +00:00
2016-09-26 15:15:07 +00:00
cs_t * css_buf_salt = ( cs_t * ) mycalloc ( css_cnt_salt , sizeof ( cs_t ) ) ;
2016-09-24 12:00:59 +00:00
2016-09-26 15:15:07 +00:00
memcpy ( css_buf_salt , mask_ctx - > css_buf , mask_ctx - > css_cnt * sizeof ( cs_t ) ) ;
2016-09-23 18:08:47 +00:00
2016-09-26 15:15:07 +00:00
for ( uint i = 0 , j = mask_ctx - > css_cnt ; i < salt_len ; i + + , j + + )
{
css_buf_salt [ j ] . cs_buf [ 0 ] = salt_buf [ i ] ;
css_buf_salt [ j ] . cs_len = 1 ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
myfree ( mask_ctx - > css_buf ) ;
2016-09-23 18:08:47 +00:00
2016-09-26 15:15:07 +00:00
mask_ctx - > css_buf = css_buf_salt ;
mask_ctx - > css_cnt = css_cnt_salt ;
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
uint uniq_tbls [ SP_PW_MAX ] [ CHARSIZ ] = { { 0 } } ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
mp_css_to_uniq_tbl ( mask_ctx - > css_cnt , mask_ctx - > css_buf , uniq_tbls ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
sp_tbl_to_css ( mask_ctx - > root_table_buf , mask_ctx - > markov_table_buf , mask_ctx - > root_css_buf , mask_ctx - > markov_css_buf , user_options - > markov_threshold , uniq_tbls ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
data . words_cnt = sp_get_sum ( 0 , mask_ctx - > css_cnt , mask_ctx - > root_css_buf ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
// copy + args
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
uint css_cnt_l = mask_ctx - > css_cnt ;
uint css_cnt_r ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
if ( hashconfig - > attack_exec = = ATTACK_EXEC_INSIDE_KERNEL )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
if ( css_cnt_orig < 6 )
{
css_cnt_r = 1 ;
}
else if ( css_cnt_orig = = 6 )
{
css_cnt_r = 2 ;
}
else
{
if ( hashconfig - > opts_type & OPTS_TYPE_PT_UNICODE )
{
if ( css_cnt_orig = = 8 | | css_cnt_orig = = 10 )
{
css_cnt_r = 2 ;
}
else
{
css_cnt_r = 4 ;
}
}
else
{
if ( ( mask_ctx - > css_buf [ 0 ] . cs_len * mask_ctx - > css_buf [ 1 ] . cs_len * mask_ctx - > css_buf [ 2 ] . cs_len ) > 256 )
{
css_cnt_r = 3 ;
}
else
{
css_cnt_r = 4 ;
}
}
}
2016-09-23 20:51:42 +00:00
}
2016-09-26 15:15:07 +00:00
else
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
css_cnt_r = 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/* unfinished code?
int sum = css_buf [ css_cnt_r - 1 ] . cs_len ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
for ( uint i = 1 ; i < 4 & & i < css_cnt ; i + + )
{
if ( sum > 1 ) break ; // we really don't need alot of amplifier them for slow hashes
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
css_cnt_r + + ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
sum * = css_buf [ css_cnt_r - 1 ] . cs_len ;
}
*/
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
css_cnt_l - = css_cnt_r ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
mask_ctx - > bfs_cnt = sp_get_sum ( 0 , css_cnt_r , mask_ctx - > root_css_buf ) ;
2015-12-04 14:47:52 +00:00
2016-09-27 09:43:05 +00:00
const int rc_update_mp_rl = opencl_session_update_mp_rl ( opencl_ctx , mask_ctx , css_cnt_l , css_cnt_r ) ;
2015-12-04 14:47:52 +00:00
2016-09-27 09:43:05 +00:00
if ( rc_update_mp_rl = = - 1 ) return - 1 ;
2016-09-26 15:15:07 +00:00
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* update induction directory scan
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
induct_ctx_scan ( induct_ctx ) ;
2016-01-13 16:10:40 +00:00
2016-09-24 11:01:17 +00:00
/**
2016-09-26 15:15:07 +00:00
* dictstat read
2016-09-24 11:01:17 +00:00
*/
dictstat_read ( dictstat_ctx ) ;
2016-09-23 20:51:42 +00:00
/**
* dictionary pad
*/
2016-06-18 08:59:58 +00:00
2016-09-23 20:51:42 +00:00
uint dictcnt = 0 ;
char * * dictfiles = NULL ;
2016-06-18 08:59:58 +00:00
2016-09-23 20:51:42 +00:00
if ( user_options - > attack_mode = = ATTACK_MODE_STRAIGHT )
{
if ( user_options_extra - > wordlist_mode = = WL_MODE_FILE )
{
2016-09-26 15:15:07 +00:00
int wls_left = restore_ctx - > argc - ( user_options_extra - > optind + 1 ) ;
2016-06-18 08:59:58 +00:00
2016-09-23 20:51:42 +00:00
for ( int i = 0 ; i < wls_left ; i + + )
2016-06-02 09:10:36 +00:00
{
2016-09-26 15:15:07 +00:00
char * l0_filename = restore_ctx - > argv [ user_options_extra - > optind + 1 + i ] ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
struct stat l0_stat ;
if ( stat ( l0_filename , & l0_stat ) = = - 1 )
2016-01-13 16:10:40 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s: %s " , l0_filename , strerror ( errno ) ) ;
return - 1 ;
}
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
uint is_dir = S_ISDIR ( l0_stat . st_mode ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
if ( is_dir = = 0 )
{
dictfiles = ( char * * ) myrealloc ( dictfiles , dictcnt * sizeof ( char * ) , sizeof ( char * ) ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
dictcnt + + ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
dictfiles [ dictcnt - 1 ] = l0_filename ;
}
else
{
// do not allow --keyspace w/ a directory
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
if ( user_options - > keyspace = = true )
{
log_error ( " ERROR: Keyspace parameter is not allowed together with a directory " ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
char * * dictionary_files = NULL ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
dictionary_files = scan_directory ( l0_filename ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
if ( dictionary_files ! = NULL )
2016-01-13 16:10:40 +00:00
{
2016-09-23 20:51:42 +00:00
qsort ( dictionary_files , count_dictionaries ( dictionary_files ) , sizeof ( char * ) , sort_by_stringptr ) ;
for ( int d = 0 ; dictionary_files [ d ] ! = NULL ; d + + )
{
char * l1_filename = dictionary_files [ d ] ;
struct stat l1_stat ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
if ( stat ( l1_filename , & l1_stat ) = = - 1 )
{
log_error ( " ERROR: %s: %s " , l1_filename , strerror ( errno ) ) ;
return - 1 ;
}
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
if ( S_ISREG ( l1_stat . st_mode ) )
{
dictfiles = ( char * * ) myrealloc ( dictfiles , dictcnt * sizeof ( char * ) , sizeof ( char * ) ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
dictcnt + + ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
dictfiles [ dictcnt - 1 ] = mystrdup ( l1_filename ) ;
}
}
2016-01-13 16:10:40 +00:00
}
2016-09-26 21:22:07 +00:00
myfree ( dictionary_files ) ;
2016-01-13 16:10:40 +00:00
}
}
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
if ( dictcnt < 1 )
2016-02-04 14:07:38 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: No usable dictionary file found. " ) ;
return - 1 ;
2016-02-04 14:07:38 +00:00
}
2016-01-13 16:10:40 +00:00
}
2016-09-23 20:51:42 +00:00
else if ( user_options_extra - > wordlist_mode = = WL_MODE_STDIN )
{
dictcnt = 1 ;
}
}
else if ( user_options - > attack_mode = = ATTACK_MODE_COMBI )
{
// display
2016-01-13 16:10:40 +00:00
2016-09-26 15:15:07 +00:00
char * dictfile1 = restore_ctx - > argv [ user_options_extra - > optind + 1 + 0 ] ;
char * dictfile2 = restore_ctx - > argv [ user_options_extra - > optind + 1 + 1 ] ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
// find the bigger dictionary and use as base
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
FILE * fp1 = NULL ;
FILE * fp2 = NULL ;
2016-06-01 17:01:44 +00:00
2016-09-23 20:51:42 +00:00
struct stat tmp_stat ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
if ( ( fp1 = fopen ( dictfile1 , " rb " ) ) = = NULL )
2016-02-04 14:07:38 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s: %s " , dictfile1 , strerror ( errno ) ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2016-05-30 08:29:18 +00:00
2016-09-23 20:51:42 +00:00
if ( stat ( dictfile1 , & tmp_stat ) = = - 1 )
2016-05-30 08:29:18 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s: %s " , dictfile1 , strerror ( errno ) ) ;
fclose ( fp1 ) ;
return - 1 ;
2016-05-30 08:29:18 +00:00
}
2016-09-23 20:51:42 +00:00
if ( S_ISDIR ( tmp_stat . st_mode ) )
2016-05-30 08:29:18 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s must be a regular file " , dictfile1 , strerror ( errno ) ) ;
fclose ( fp1 ) ;
return - 1 ;
2016-05-30 08:29:18 +00:00
}
2016-09-23 20:51:42 +00:00
if ( ( fp2 = fopen ( dictfile2 , " rb " ) ) = = NULL )
{
log_error ( " ERROR: %s: %s " , dictfile2 , strerror ( errno ) ) ;
fclose ( fp1 ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
if ( stat ( dictfile2 , & tmp_stat ) = = - 1 )
2016-02-04 14:07:38 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s: %s " , dictfile2 , strerror ( errno ) ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
fclose ( fp1 ) ;
fclose ( fp2 ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
if ( S_ISDIR ( tmp_stat . st_mode ) )
{
log_error ( " ERROR: %s must be a regular file " , dictfile2 , strerror ( errno ) ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
fclose ( fp1 ) ;
fclose ( fp2 ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2016-02-04 14:07:38 +00:00
2016-09-27 16:32:09 +00:00
combinator_ctx - > combs_cnt = 1 ;
2016-02-04 14:07:38 +00:00
2016-09-27 16:32:09 +00:00
const u64 words1_cnt = count_words ( wl_data , user_options , user_options_extra , straight_ctx , combinator_ctx , fp1 , dictfile1 , dictstat_ctx ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
if ( words1_cnt = = 0 )
{
log_error ( " ERROR: %s: empty file " , dictfile1 ) ;
2016-02-04 14:07:38 +00:00
2016-09-23 20:51:42 +00:00
fclose ( fp1 ) ;
fclose ( fp2 ) ;
2016-05-12 10:44:15 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
2016-02-04 14:07:38 +00:00
}
2016-09-27 16:32:09 +00:00
combinator_ctx - > combs_cnt = 1 ;
2016-09-23 20:51:42 +00:00
2016-09-27 16:32:09 +00:00
const u64 words2_cnt = count_words ( wl_data , user_options , user_options_extra , straight_ctx , combinator_ctx , fp2 , dictfile2 , dictstat_ctx ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
if ( words2_cnt = = 0 )
2016-01-13 16:10:40 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s: empty file " , dictfile2 ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
fclose ( fp1 ) ;
fclose ( fp2 ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2016-01-15 16:23:07 +00:00
2016-09-23 20:51:42 +00:00
fclose ( fp1 ) ;
fclose ( fp2 ) ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
data . dictfile = dictfile1 ;
data . dictfile2 = dictfile2 ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
if ( words1_cnt > = words2_cnt )
{
2016-09-27 16:32:09 +00:00
combinator_ctx - > combs_cnt = words2_cnt ;
combinator_ctx - > combs_mode = COMBINATOR_MODE_BASE_LEFT ;
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
dictfiles = & data . dictfile ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictcnt = 1 ;
}
else
2015-12-15 11:04:22 +00:00
{
2016-09-27 16:32:09 +00:00
combinator_ctx - > combs_cnt = words1_cnt ;
combinator_ctx - > combs_mode = COMBINATOR_MODE_BASE_RIGHT ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictfiles = & data . dictfile2 ;
2016-01-15 16:23:07 +00:00
2016-09-23 20:51:42 +00:00
dictcnt = 1 ;
2016-01-15 16:23:07 +00:00
2016-09-23 20:51:42 +00:00
// we also have to switch wordlist related rules!
2016-01-13 16:10:40 +00:00
2016-09-23 20:51:42 +00:00
char * tmpc = user_options - > rule_buf_l ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
user_options - > rule_buf_l = user_options - > rule_buf_r ;
user_options - > rule_buf_r = tmpc ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
int tmpi = user_options_extra - > rule_len_l ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
user_options_extra - > rule_len_l = user_options_extra - > rule_len_r ;
user_options_extra - > rule_len_r = tmpi ;
}
2016-09-27 16:32:09 +00:00
const int rc_update_combinator = opencl_session_update_combinator ( opencl_ctx , hashconfig , combinator_ctx ) ;
if ( rc_update_combinator = = - 1 ) return - 1 ;
2016-09-23 20:51:42 +00:00
}
else if ( user_options - > attack_mode = = ATTACK_MODE_BF )
{
2016-09-25 23:18:00 +00:00
if ( user_options - > benchmark = = true )
2016-09-23 20:51:42 +00:00
{
2016-09-25 23:18:00 +00:00
pw_min = mp_get_length ( mask_ctx - > mask ) ;
2016-09-23 20:51:42 +00:00
pw_max = pw_min ;
2015-12-04 14:47:52 +00:00
}
2016-05-29 22:05:46 +00:00
2016-09-25 23:18:00 +00:00
/* i think we can do this better
2016-09-23 20:51:42 +00:00
if ( user_options - > increment = = true )
{
if ( user_options - > increment_min > pw_min ) pw_min = user_options - > increment_min ;
if ( user_options - > increment_max < pw_max ) pw_max = user_options - > increment_max ;
}
2016-09-25 23:18:00 +00:00
*/
dictfiles = ( char * * ) mycalloc ( 1 , sizeof ( char * ) ) ;
dictfiles [ 0 ] = " DUMMY " ;
dictcnt = 1 ;
2016-09-23 20:51:42 +00:00
}
else if ( user_options - > attack_mode = = ATTACK_MODE_HYBRID1 )
{
2016-09-27 16:32:09 +00:00
combinator_ctx - > combs_mode = COMBINATOR_MODE_BASE_LEFT ;
2016-05-12 10:44:15 +00:00
2016-09-25 23:18:00 +00:00
// mod -- moved to mpsp.c
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
// base
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
int wls_left = restore_ctx - > argc - ( user_options_extra - > optind + 2 ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
for ( int i = 0 ; i < wls_left ; i + + )
2015-12-04 14:47:52 +00:00
{
2016-09-26 15:15:07 +00:00
char * filename = restore_ctx - > argv [ user_options_extra - > optind + 1 + i ] ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
struct stat file_stat ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( stat ( filename , & file_stat ) = = - 1 )
{
log_error ( " ERROR: %s: %s " , filename , strerror ( errno ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
uint is_dir = S_ISDIR ( file_stat . st_mode ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( is_dir = = 0 )
{
dictfiles = ( char * * ) myrealloc ( dictfiles , dictcnt * sizeof ( char * ) , sizeof ( char * ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictcnt + + ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictfiles [ dictcnt - 1 ] = filename ;
}
else
2015-12-04 14:47:52 +00:00
{
2016-09-23 20:51:42 +00:00
// do not allow --keyspace w/ a directory
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( user_options - > keyspace = = true )
2015-12-04 14:47:52 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: Keyspace parameter is not allowed together with a directory " ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
char * * dictionary_files = NULL ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictionary_files = scan_directory ( filename ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( dictionary_files ! = NULL )
{
qsort ( dictionary_files , count_dictionaries ( dictionary_files ) , sizeof ( char * ) , sort_by_stringptr ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
for ( int d = 0 ; dictionary_files [ d ] ! = NULL ; d + + )
2015-12-04 14:47:52 +00:00
{
2016-09-23 20:51:42 +00:00
char * l1_filename = dictionary_files [ d ] ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
struct stat l1_stat ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( stat ( l1_filename , & l1_stat ) = = - 1 )
2015-12-04 14:47:52 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s: %s " , l1_filename , strerror ( errno ) ) ;
2015-12-04 14:47:52 +00:00
2016-07-10 11:23:06 +00:00
return - 1 ;
2015-12-04 14:47:52 +00:00
}
2016-09-23 20:51:42 +00:00
if ( S_ISREG ( l1_stat . st_mode ) )
2015-12-04 14:47:52 +00:00
{
2016-09-23 20:51:42 +00:00
dictfiles = ( char * * ) myrealloc ( dictfiles , dictcnt * sizeof ( char * ) , sizeof ( char * ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictcnt + + ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictfiles [ dictcnt - 1 ] = mystrdup ( l1_filename ) ;
2015-12-04 14:47:52 +00:00
}
}
}
2016-09-26 21:22:07 +00:00
myfree ( dictionary_files ) ;
2015-12-04 14:47:52 +00:00
}
}
2016-09-23 20:51:42 +00:00
if ( dictcnt < 1 )
{
log_error ( " ERROR: No usable dictionary file found. " ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2016-09-27 16:32:09 +00:00
const int rc_update_combinator = opencl_session_update_combinator ( opencl_ctx , hashconfig , combinator_ctx ) ;
if ( rc_update_combinator = = - 1 ) return - 1 ;
2016-09-23 20:51:42 +00:00
}
else if ( user_options - > attack_mode = = ATTACK_MODE_HYBRID2 )
{
2016-09-27 16:32:09 +00:00
combinator_ctx - > combs_mode = COMBINATOR_MODE_BASE_RIGHT ;
2015-12-04 14:47:52 +00:00
2016-09-25 23:18:00 +00:00
// mod -- moved to mpsp.c
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
// base
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
int wls_left = restore_ctx - > argc - ( user_options_extra - > optind + 2 ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
for ( int i = 0 ; i < wls_left ; i + + )
2015-12-04 14:47:52 +00:00
{
2016-09-26 15:15:07 +00:00
char * filename = restore_ctx - > argv [ user_options_extra - > optind + 2 + i ] ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
struct stat file_stat ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( stat ( filename , & file_stat ) = = - 1 )
2015-12-04 14:47:52 +00:00
{
2016-09-23 20:51:42 +00:00
log_error ( " ERROR: %s: %s " , filename , strerror ( errno ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
uint is_dir = S_ISDIR ( file_stat . st_mode ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( is_dir = = 0 )
{
dictfiles = ( char * * ) myrealloc ( dictfiles , dictcnt * sizeof ( char * ) , sizeof ( char * ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictcnt + + ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictfiles [ dictcnt - 1 ] = filename ;
}
else
{
// do not allow --keyspace w/ a directory
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( user_options - > keyspace = = true )
{
log_error ( " ERROR: Keyspace parameter is not allowed together with a directory " ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
char * * dictionary_files = NULL ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictionary_files = scan_directory ( filename ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( dictionary_files ! = NULL )
{
qsort ( dictionary_files , count_dictionaries ( dictionary_files ) , sizeof ( char * ) , sort_by_stringptr ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
for ( int d = 0 ; dictionary_files [ d ] ! = NULL ; d + + )
{
char * l1_filename = dictionary_files [ d ] ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
struct stat l1_stat ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( stat ( l1_filename , & l1_stat ) = = - 1 )
{
log_error ( " ERROR: %s: %s " , l1_filename , strerror ( errno ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( S_ISREG ( l1_stat . st_mode ) )
{
dictfiles = ( char * * ) myrealloc ( dictfiles , dictcnt * sizeof ( char * ) , sizeof ( char * ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictcnt + + ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
dictfiles [ dictcnt - 1 ] = mystrdup ( l1_filename ) ;
}
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 21:22:07 +00:00
myfree ( dictionary_files ) ;
2016-09-23 20:51:42 +00:00
}
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( dictcnt < 1 )
{
log_error ( " ERROR: No usable dictionary file found. " ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
return - 1 ;
}
2016-09-27 16:32:09 +00:00
const int rc_update_combinator = opencl_session_update_combinator ( opencl_ctx , hashconfig , combinator_ctx ) ;
if ( rc_update_combinator = = - 1 ) return - 1 ;
2016-09-23 20:51:42 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-28 11:51:00 +00:00
hashconfig - > pw_min = pw_min ;
hashconfig - > pw_max = pw_max ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
/**
2016-09-26 15:15:07 +00:00
* prevent the user from using - - skip / - - limit together w / maskfile and or dictfile
2016-09-23 20:51:42 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > skip ! = 0 | | user_options - > limit ! = 0 )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
if ( ( mask_ctx - > masks_cnt > 1 ) | | ( dictcnt > 1 ) )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
log_error ( " ERROR: --skip/--limit are not supported with --increment or mask files " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
return - 1 ;
2015-12-04 14:47:52 +00:00
}
2016-09-26 15:15:07 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* prevent the user from using - - keyspace together w / maskfile and or dictfile
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > keyspace = = true )
{
if ( ( mask_ctx - > masks_cnt > 1 ) | | ( dictcnt > 1 ) )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
log_error ( " ERROR: --keyspace is not supported with --increment or mask files " ) ;
return - 1 ;
2016-09-23 20:51:42 +00:00
}
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
/**
2016-09-26 15:15:07 +00:00
* main inner loop
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
restore_data_t * rd = restore_ctx - > rd ;
for ( uint dictpos = rd - > dictpos ; dictpos < dictcnt ; dictpos + + )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
if ( opencl_ctx - > run_main_level3 = = false ) break ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
//opencl_ctx->run_main_level1 = true;
//opencl_ctx->run_main_level2 = true;
//opencl_ctx->run_main_level3 = true;
opencl_ctx - > run_thread_level1 = true ;
opencl_ctx - > run_thread_level2 = true ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
rd - > dictpos = dictpos ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
logfile_generate_subid ( logfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_msg ( " START " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
memset ( data . words_progress_done , 0 , hashes - > salts_cnt * sizeof ( u64 ) ) ;
memset ( data . words_progress_rejected , 0 , hashes - > salts_cnt * sizeof ( u64 ) ) ;
memset ( data . words_progress_restored , 0 , hashes - > salts_cnt * sizeof ( u64 ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
memset ( data . cpt_buf , 0 , CPT_BUF * sizeof ( cpt_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . cpt_pos = 0 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . cpt_start = time ( NULL ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . cpt_total = 0 ;
data . words_cur = 0 ;
if ( rd - > words_cur )
{
data . words_cur = rd - > words_cur ;
user_options - > skip = 0 ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > skip )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
data . words_cur = user_options - > skip ;
user_options - > skip = 0 ;
2016-09-23 20:51:42 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . ms_paused = 0 ;
2016-09-25 23:18:00 +00:00
2016-09-27 09:43:05 +00:00
opencl_session_reset ( opencl_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
// figure out some workload
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > attack_mode = = ATTACK_MODE_STRAIGHT )
{
if ( user_options_extra - > wordlist_mode = = WL_MODE_FILE )
{
char * dictfile = NULL ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( induct_ctx - > induction_dictionaries_cnt )
{
dictfile = induct_ctx - > induction_dictionaries [ 0 ] ;
}
else
{
dictfile = dictfiles [ dictpos ] ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . dictfile = dictfile ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_string ( dictfile ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
for ( uint i = 0 ; i < user_options - > rp_files_cnt ; i + + )
{
logfile_sub_var_string ( " rulefile " , user_options - > rp_files [ i ] ) ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
FILE * fd2 = fopen ( dictfile , " rb " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( fd2 = = NULL )
{
log_error ( " ERROR: %s: %s " , dictfile , strerror ( errno ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
return - 1 ;
}
2016-09-25 23:18:00 +00:00
2016-09-27 16:32:09 +00:00
data . words_cnt = count_words ( wl_data , user_options , user_options_extra , straight_ctx , combinator_ctx , fd2 , dictfile , dictstat_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
fclose ( fd2 ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( data . words_cnt = = 0 )
{
logfile_sub_msg ( " STOP " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
continue ;
}
}
}
else if ( user_options - > attack_mode = = ATTACK_MODE_COMBI )
{
char * dictfile = data . dictfile ;
char * dictfile2 = data . dictfile2 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_string ( dictfile ) ;
logfile_sub_string ( dictfile2 ) ;
2015-12-04 14:47:52 +00:00
2016-09-27 16:32:09 +00:00
if ( combinator_ctx - > combs_mode = = COMBINATOR_MODE_BASE_LEFT )
2016-09-26 15:15:07 +00:00
{
FILE * fd2 = fopen ( dictfile , " rb " ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( fd2 = = NULL )
{
log_error ( " ERROR: %s: %s " , dictfile , strerror ( errno ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
return - 1 ;
2016-09-23 20:51:42 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-27 16:32:09 +00:00
data . words_cnt = count_words ( wl_data , user_options , user_options_extra , straight_ctx , combinator_ctx , fd2 , dictfile , dictstat_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
fclose ( fd2 ) ;
}
2016-09-27 16:32:09 +00:00
else if ( combinator_ctx - > combs_mode = = COMBINATOR_MODE_BASE_RIGHT )
2016-09-26 15:15:07 +00:00
{
FILE * fd2 = fopen ( dictfile2 , " rb " ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
if ( fd2 = = NULL )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
log_error ( " ERROR: %s: %s " , dictfile2 , strerror ( errno ) ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
return - 1 ;
2015-12-04 14:47:52 +00:00
}
2016-09-23 20:51:42 +00:00
2016-09-27 16:32:09 +00:00
data . words_cnt = count_words ( wl_data , user_options , user_options_extra , straight_ctx , combinator_ctx , fd2 , dictfile2 , dictstat_ctx ) ;
2016-09-26 15:15:07 +00:00
fclose ( fd2 ) ;
}
if ( data . words_cnt = = 0 )
{
logfile_sub_msg ( " STOP " ) ;
continue ;
2015-12-04 14:47:52 +00:00
}
2016-09-26 15:15:07 +00:00
}
else if ( ( user_options - > attack_mode = = ATTACK_MODE_HYBRID1 ) | | ( user_options - > attack_mode = = ATTACK_MODE_HYBRID2 ) )
{
char * dictfile = NULL ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( induct_ctx - > induction_dictionaries_cnt )
{
dictfile = induct_ctx - > induction_dictionaries [ 0 ] ;
}
else
2015-12-04 14:47:52 +00:00
{
2016-09-26 15:15:07 +00:00
dictfile = dictfiles [ dictpos ] ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . dictfile = dictfile ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_string ( dictfile ) ;
logfile_sub_string ( mask_ctx - > mask ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
FILE * fd2 = fopen ( dictfile , " rb " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( fd2 = = NULL )
{
log_error ( " ERROR: %s: %s " , dictfile , strerror ( errno ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
return - 1 ;
}
2015-12-04 14:47:52 +00:00
2016-09-27 16:32:09 +00:00
data . words_cnt = count_words ( wl_data , user_options , user_options_extra , straight_ctx , combinator_ctx , fd2 , dictfile , dictstat_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
fclose ( fd2 ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( data . words_cnt = = 0 )
{
logfile_sub_msg ( " STOP " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
continue ;
}
}
else if ( user_options - > attack_mode = = ATTACK_MODE_BF )
{
logfile_sub_string ( mask_ctx - > mask ) ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
u64 words_base = data . words_cnt ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options_extra - > attack_kern = = ATTACK_KERN_STRAIGHT )
{
2016-09-27 11:13:07 +00:00
if ( straight_ctx - > kernel_rules_cnt )
2016-09-26 15:15:07 +00:00
{
2016-09-27 11:13:07 +00:00
words_base / = straight_ctx - > kernel_rules_cnt ;
2016-09-26 15:15:07 +00:00
}
}
else if ( user_options_extra - > attack_kern = = ATTACK_KERN_COMBI )
{
2016-09-27 16:32:09 +00:00
if ( combinator_ctx - > combs_cnt )
2016-09-26 15:15:07 +00:00
{
2016-09-27 16:32:09 +00:00
words_base / = combinator_ctx - > combs_cnt ;
2016-09-26 15:15:07 +00:00
}
}
else if ( user_options_extra - > attack_kern = = ATTACK_KERN_BF )
{
if ( mask_ctx - > bfs_cnt )
{
words_base / = mask_ctx - > bfs_cnt ;
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . words_base = words_base ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > keyspace = = true )
{
log_info ( " % " PRIu64 " " , words_base ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
return 0 ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( data . words_cur > data . words_base )
{
log_error ( " ERROR: Restore value greater keyspace " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
return - 1 ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( data . words_cur )
{
if ( user_options_extra - > attack_kern = = ATTACK_KERN_STRAIGHT )
{
for ( uint i = 0 ; i < hashes - > salts_cnt ; i + + )
{
2016-09-27 11:13:07 +00:00
data . words_progress_restored [ i ] = data . words_cur * straight_ctx - > kernel_rules_cnt ;
2016-09-23 20:51:42 +00:00
}
}
2016-09-26 15:15:07 +00:00
else if ( user_options_extra - > attack_kern = = ATTACK_KERN_COMBI )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
for ( uint i = 0 ; i < hashes - > salts_cnt ; i + + )
{
2016-09-27 16:32:09 +00:00
data . words_progress_restored [ i ] = data . words_cur * combinator_ctx - > combs_cnt ;
2016-09-26 15:15:07 +00:00
}
}
else if ( user_options_extra - > attack_kern = = ATTACK_KERN_BF )
{
for ( uint i = 0 ; i < hashes - > salts_cnt ; i + + )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
data . words_progress_restored [ i ] = data . words_cur * mask_ctx - > bfs_cnt ;
}
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/*
* Update dictionary statistic
*/
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
dictstat_write ( dictstat_ctx ) ;
2016-03-26 09:37:59 +00:00
2016-09-26 15:15:07 +00:00
/**
* Update loopback file
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > loopback = = true )
{
loopback_write_open ( loopback_ctx , induct_ctx - > root_directory ) ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
/**
* some algorithms have a maximum kernel - loops count
*/
for ( uint device_id = 0 ; device_id < opencl_ctx - > devices_cnt ; device_id + + )
{
hc_device_param_t * device_param = & opencl_ctx - > devices_param [ device_id ] ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( device_param - > skipped ) continue ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( device_param - > kernel_loops_min < device_param - > kernel_loops_max )
{
u32 innerloop_cnt = 0 ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( hashconfig - > attack_exec = = ATTACK_EXEC_INSIDE_KERNEL )
2016-09-25 23:18:00 +00:00
{
2016-09-27 11:13:07 +00:00
if ( user_options_extra - > attack_kern = = ATTACK_KERN_STRAIGHT ) innerloop_cnt = straight_ctx - > kernel_rules_cnt ;
2016-09-27 16:32:09 +00:00
else if ( user_options_extra - > attack_kern = = ATTACK_KERN_COMBI ) innerloop_cnt = combinator_ctx - > combs_cnt ;
2016-09-26 15:15:07 +00:00
else if ( user_options_extra - > attack_kern = = ATTACK_KERN_BF ) innerloop_cnt = mask_ctx - > bfs_cnt ;
}
else
{
innerloop_cnt = hashes - > salts_buf [ 0 ] . salt_iter ;
2015-12-04 14:47:52 +00:00
}
2016-09-26 15:15:07 +00:00
if ( ( innerloop_cnt > = device_param - > kernel_loops_min ) & &
( innerloop_cnt < = device_param - > kernel_loops_max ) )
2015-12-04 14:47:52 +00:00
{
2016-09-26 15:15:07 +00:00
device_param - > kernel_loops_max = innerloop_cnt ;
}
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* create autotune threads
*/
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
hc_thread_t * c_threads = ( hc_thread_t * ) mycalloc ( opencl_ctx - > devices_cnt , sizeof ( hc_thread_t ) ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
opencl_ctx - > devices_status = STATUS_AUTOTUNE ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
for ( uint device_id = 0 ; device_id < opencl_ctx - > devices_cnt ; device_id + + )
{
hc_device_param_t * device_param = & opencl_ctx - > devices_param [ device_id ] ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
hc_thread_create ( c_threads [ device_id ] , thread_autotune , device_param ) ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
hc_thread_wait ( opencl_ctx - > devices_cnt , c_threads ) ;
2015-12-04 14:47:52 +00:00
2016-09-28 09:49:08 +00:00
// autotune modified kernel_accel, which modifies opencl_ctx->kernel_power_all
2016-09-25 23:18:00 +00:00
2016-09-28 09:49:08 +00:00
opencl_ctx_devices_update_power ( opencl_ctx , user_options , user_options_extra ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
/**
* create cracker threads
*/
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
opencl_ctx - > devices_status = STATUS_RUNNING ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
hc_timer_set ( & data . timer_running ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( ( user_options_extra - > wordlist_mode = = WL_MODE_FILE ) | | ( user_options_extra - > wordlist_mode = = WL_MODE_MASK ) )
{
if ( ( user_options - > quiet = = false ) & & ( user_options - > status = = false ) & & ( user_options - > benchmark = = false ) )
{
if ( user_options - > quiet = = false ) send_prompt ( ) ;
}
}
else if ( user_options_extra - > wordlist_mode = = WL_MODE_STDIN )
{
if ( user_options - > quiet = = false ) log_info ( " Starting attack in stdin mode... " ) ;
if ( user_options - > quiet = = false ) log_info ( " " ) ;
}
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
time_t runtime_start ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
time ( & runtime_start ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
data . runtime_start = runtime_start ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
data . prepare_time = runtime_start - data . prepare_start ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
for ( uint device_id = 0 ; device_id < opencl_ctx - > devices_cnt ; device_id + + )
{
hc_device_param_t * device_param = & opencl_ctx - > devices_param [ device_id ] ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options_extra - > wordlist_mode = = WL_MODE_STDIN )
{
hc_thread_create ( c_threads [ device_id ] , thread_calc_stdin , device_param ) ;
}
else
{
hc_thread_create ( c_threads [ device_id ] , thread_calc , device_param ) ;
}
}
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
hc_thread_wait ( opencl_ctx - > devices_cnt , c_threads ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 21:22:07 +00:00
myfree ( c_threads ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( ( opencl_ctx - > devices_status ! = STATUS_CRACKED )
& & ( opencl_ctx - > devices_status ! = STATUS_ABORTED )
& & ( opencl_ctx - > devices_status ! = STATUS_QUIT )
& & ( opencl_ctx - > devices_status ! = STATUS_BYPASS ) )
{
opencl_ctx - > devices_status = STATUS_EXHAUSTED ;
}
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( opencl_ctx - > devices_status = = STATUS_EXHAUSTED )
{
rd - > words_cur = 0 ;
}
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_var_uint ( " status-after-work " , opencl_ctx - > devices_status ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( induct_ctx - > induction_dictionaries_cnt )
{
unlink ( induct_ctx - > induction_dictionaries [ 0 ] ) ;
}
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
myfree ( induct_ctx - > induction_dictionaries ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
induct_ctx_scan ( induct_ctx ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > benchmark = = true )
{
status_benchmark ( opencl_ctx , hashconfig , user_options ) ;
2016-09-25 23:18:00 +00:00
2016-09-28 21:53:46 +00:00
if ( user_options - > machine_readable = = false )
{
log_info ( " " ) ;
}
2016-09-26 15:15:07 +00:00
}
else
{
if ( user_options - > quiet = = false )
{
clear_prompt ( ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 21:50:16 +00:00
if ( hashes - > digests_saved ! = hashes - > digests_done ) log_info ( " " ) ;
2016-09-28 20:28:44 +00:00
status_display ( opencl_ctx , hwmon_ctx , hashconfig , hashes , restore_ctx , user_options , user_options_extra , straight_ctx , combinator_ctx , mask_ctx ) ;
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
log_info ( " " ) ;
}
else
{
if ( user_options - > status = = true )
{
2016-09-28 20:28:44 +00:00
status_display ( opencl_ctx , hwmon_ctx , hashconfig , hashes , restore_ctx , user_options , user_options_extra , straight_ctx , combinator_ctx , mask_ctx ) ;
2016-09-26 15:15:07 +00:00
log_info ( " " ) ;
2016-09-25 23:18:00 +00:00
}
}
}
2016-09-26 15:15:07 +00:00
if ( induct_ctx - > induction_dictionaries_cnt )
2016-09-25 23:18:00 +00:00
{
2016-09-26 15:15:07 +00:00
// yeah, this next statement is a little hack to make sure that --loopback runs correctly (because with it we guarantee that the loop iterates one more time)
2016-09-25 23:18:00 +00:00
2016-09-26 15:15:07 +00:00
dictpos - - ;
2016-09-25 23:18:00 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
/**
2016-09-26 15:15:07 +00:00
* Update loopback file
2016-09-23 20:51:42 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > loopback = = true )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
loopback_write_close ( loopback_ctx ) ;
2016-09-23 20:51:42 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
time_t runtime_stop ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
time ( & runtime_stop ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . runtime_stop = runtime_stop ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_uint ( runtime_start ) ;
logfile_sub_uint ( runtime_stop ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
time ( & data . prepare_start ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
logfile_sub_msg ( " STOP " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
// finalize task
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( opencl_ctx - > run_main_level3 = = false ) break ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
// free memory
2015-12-04 14:47:52 +00:00
2016-09-24 23:02:44 +00:00
2016-09-26 15:15:07 +00:00
return 0 ;
}
2016-09-24 23:02:44 +00:00
2016-09-28 20:28:44 +00:00
static int outer_loop ( user_options_t * user_options , user_options_extra_t * user_options_extra , restore_ctx_t * restore_ctx , folder_config_t * folder_config , logfile_ctx_t * logfile_ctx , tuning_db_t * tuning_db , induct_ctx_t * induct_ctx , outcheck_ctx_t * outcheck_ctx , outfile_ctx_t * outfile_ctx , potfile_ctx_t * potfile_ctx , dictstat_ctx_t * dictstat_ctx , loopback_ctx_t * loopback_ctx , opencl_ctx_t * opencl_ctx , hwmon_ctx_t * hwmon_ctx )
2016-09-26 15:15:07 +00:00
{
opencl_ctx - > devices_status = STATUS_INIT ;
2016-09-24 23:02:44 +00:00
2016-09-26 15:15:07 +00:00
//opencl_ctx->run_main_level1 = true;
opencl_ctx - > run_main_level2 = true ;
opencl_ctx - > run_main_level3 = true ;
opencl_ctx - > run_thread_level1 = true ;
opencl_ctx - > run_thread_level2 = true ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/*
* We need to reset ' rd ' in benchmark mode otherwise when the user hits ' bypass '
* the following algos are skipped entirely
* still needed ? there ' s no more bypass in benchmark mode
* also there ' s no signs of special benchmark handling in the branch
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/*
if ( algorithm_pos > 0 )
{
2016-09-26 21:22:07 +00:00
myfree ( rd ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
rd = init_restore ( argc , argv , user_options ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . rd = rd ;
}
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* setup prepare timer
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
time ( & data . prepare_start ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* setup variables and buffers depending on hash_mode
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
hashconfig_t * hashconfig = ( hashconfig_t * ) mymalloc ( sizeof ( hashconfig_t ) ) ;
2016-09-13 11:06:55 +00:00
2016-09-26 15:15:07 +00:00
data . hashconfig = hashconfig ;
2016-09-13 11:06:55 +00:00
2016-09-26 15:15:07 +00:00
const int rc_hashconfig = hashconfig_init ( hashconfig , user_options ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( rc_hashconfig = = - 1 ) return - 1 ;
2016-02-05 14:27:09 +00:00
2016-09-26 15:15:07 +00:00
/**
* potfile show / left depends on hash_mode , so it ' s called here first time
*/
2016-01-16 11:24:08 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > show = = true | | user_options - > left = = true )
{
outfile_write_open ( outfile_ctx ) ;
2016-01-16 11:24:08 +00:00
2016-09-26 15:15:07 +00:00
SUPPRESS_OUTPUT = 1 ;
2016-01-16 11:24:08 +00:00
2016-09-26 15:15:07 +00:00
potfile_read_open ( potfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
potfile_read_parse ( potfile_ctx , hashconfig ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
potfile_read_close ( potfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
SUPPRESS_OUTPUT = 0 ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* load hashes , stage 1
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
hashes_t * hashes = ( hashes_t * ) mymalloc ( sizeof ( hashes_t ) ) ;
2016-06-27 10:13:46 +00:00
2016-09-26 15:15:07 +00:00
data . hashes = hashes ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
const int rc_hashes_init_stage1 = hashes_init_stage1 ( hashes , hashconfig , potfile_ctx , outfile_ctx , user_options , restore_ctx - > argv [ user_options_extra - > optind ] ) ;
2016-06-27 10:13:46 +00:00
2016-09-26 15:15:07 +00:00
if ( rc_hashes_init_stage1 = = - 1 ) return - 1 ;
2016-06-27 10:13:46 +00:00
2016-09-26 15:15:07 +00:00
if ( ( user_options - > keyspace = = false ) & & ( user_options - > stdout_flag = = false ) & & ( user_options - > opencl_info = = false ) )
{
if ( hashes - > hashes_cnt = = 0 )
{
log_error ( " ERROR: No hashes loaded " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
return - 1 ;
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* potfile show / left final
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > show = = true | | user_options - > left = = true )
{
outfile_write_close ( outfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
potfile_hash_free ( potfile_ctx , hashconfig ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
//if (user_options->quiet == false) log_info_nn ("");
2016-06-26 07:47:02 +00:00
2016-09-26 15:15:07 +00:00
return 0 ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* Potfile removes
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
int potfile_remove_cracks = 0 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( user_options - > potfile_disable = = 0 )
{
if ( user_options - > quiet = = false ) log_info_nn ( " Comparing hashes with potfile entries... " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
potfile_remove_cracks = potfile_remove_parse ( potfile_ctx , hashconfig , hashes ) ;
}
2016-09-23 20:51:42 +00:00
2016-09-26 15:15:07 +00:00
/**
* load hashes , stage 2 , remove duplicates , build base structure
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
const u32 hashes_cnt_orig = hashes - > hashes_cnt ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
const int rc_hashes_init_stage2 = hashes_init_stage2 ( hashes , hashconfig , opencl_ctx , user_options ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( rc_hashes_init_stage2 = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* load hashes , stage 3 , automatic Optimizers
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
const int rc_hashes_init_stage3 = hashes_init_stage3 ( hashes , hashconfig , user_options ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( rc_hashes_init_stage3 = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
hashes_logger ( hashes , logfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
* bitmaps
*/
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
bitmap_ctx_t * bitmap_ctx = ( bitmap_ctx_t * ) mymalloc ( sizeof ( bitmap_ctx_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
data . bitmap_ctx = bitmap_ctx ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
bitmap_ctx_init ( bitmap_ctx , user_options , hashconfig , hashes ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
2016-09-27 11:13:07 +00:00
* Wordlist allocate buffer
2016-09-26 15:15:07 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-27 11:13:07 +00:00
wl_data_t * wl_data = ( wl_data_t * ) mymalloc ( sizeof ( wl_data_t ) ) ;
2016-09-26 15:15:07 +00:00
2016-09-27 11:13:07 +00:00
wl_data_init ( wl_data , user_options , hashconfig ) ;
2016-09-26 15:15:07 +00:00
2016-09-27 11:13:07 +00:00
/**
* straight mode init
*/
2016-09-26 15:15:07 +00:00
2016-09-27 11:13:07 +00:00
straight_ctx_t * straight_ctx = ( straight_ctx_t * ) mymalloc ( sizeof ( straight_ctx_t ) ) ;
data . straight_ctx = straight_ctx ;
const int rc_straight_init = straight_ctx_init ( straight_ctx , user_options ) ;
if ( rc_straight_init = = - 1 ) return - 1 ;
2016-09-26 15:15:07 +00:00
2016-09-27 16:32:09 +00:00
/**
* straight mode init
*/
combinator_ctx_t * combinator_ctx = ( combinator_ctx_t * ) mymalloc ( sizeof ( combinator_ctx_t ) ) ;
data . combinator_ctx = combinator_ctx ;
const int rc_combinator_init = combinator_ctx_init ( combinator_ctx , user_options ) ;
if ( rc_combinator_init = = - 1 ) return - 1 ;
2016-09-26 15:15:07 +00:00
/**
2016-09-27 11:13:07 +00:00
* charsets : keep them together for more easy maintainnce
2016-09-26 15:15:07 +00:00
*/
2016-09-27 11:13:07 +00:00
mask_ctx_t * mask_ctx = ( mask_ctx_t * ) mymalloc ( sizeof ( mask_ctx_t ) ) ;
2016-09-26 15:15:07 +00:00
2016-09-27 11:13:07 +00:00
data . mask_ctx = mask_ctx ;
const int rc_mask_init = mask_ctx_init ( mask_ctx , user_options , user_options_extra , folder_config , restore_ctx , hashconfig ) ;
if ( rc_mask_init = = - 1 ) return - 1 ;
2016-09-26 15:15:07 +00:00
/**
* enable custom signal handler ( s )
*/
if ( user_options - > benchmark = = false )
{
hc_signal ( sigHandler_default ) ;
}
else
{
hc_signal ( sigHandler_benchmark ) ;
}
/**
* inform the user
*/
if ( user_options - > quiet = = false )
{
log_info ( " Hashes: %u digests; %u unique digests, %u unique salts " , hashes_cnt_orig , hashes - > digests_cnt , hashes - > salts_cnt ) ;
log_info ( " Bitmaps: %u bits, %u entries, 0x%08x mask, %u bytes, %u/%u rotates " , bitmap_ctx - > bitmap_bits , bitmap_ctx - > bitmap_nums , bitmap_ctx - > bitmap_mask , bitmap_ctx - > bitmap_size , bitmap_ctx - > bitmap_shift1 , bitmap_ctx - > bitmap_shift2 ) ;
if ( user_options - > attack_mode = = ATTACK_MODE_STRAIGHT )
{
2016-09-27 11:13:07 +00:00
log_info ( " Rules: %u " , straight_ctx - > kernel_rules_cnt ) ;
2016-09-26 15:15:07 +00:00
}
if ( user_options - > quiet = = false ) log_info ( " " ) ;
if ( hashconfig - > opti_type )
{
log_info ( " Applicable Optimizers: " ) ;
for ( uint i = 0 ; i < 32 ; i + + )
2016-09-23 20:51:42 +00:00
{
2016-09-26 15:15:07 +00:00
const uint opti_bit = 1u < < i ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( hashconfig - > opti_type & opti_bit ) log_info ( " * %s " , stroptitype ( opti_bit ) ) ;
2016-09-23 20:51:42 +00:00
}
2016-09-26 15:15:07 +00:00
}
if ( user_options - > quiet = = false ) log_info ( " " ) ;
/**
* Watchdog and Temperature balance
*/
2016-09-28 20:28:44 +00:00
if ( hwmon_ctx - > enabled = = false & & user_options - > gpu_temp_disable = = false )
2016-09-26 15:15:07 +00:00
{
log_info ( " Watchdog: Hardware Monitoring Interface not found on your system " ) ;
}
2016-09-28 20:28:44 +00:00
if ( hwmon_ctx - > enabled = = true & & user_options - > gpu_temp_abort > 0 )
2016-09-26 15:15:07 +00:00
{
2016-09-28 20:28:44 +00:00
log_info ( " Watchdog: Temperature abort trigger set to %uc " , user_options - > gpu_temp_abort ) ;
2016-09-26 15:15:07 +00:00
}
else
{
2016-09-28 20:28:44 +00:00
log_info ( " Watchdog: Temperature abort trigger disabled " ) ;
2016-09-26 15:15:07 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-28 20:28:44 +00:00
if ( hwmon_ctx - > enabled = = true & & user_options - > gpu_temp_retain > 0 )
2016-09-26 15:15:07 +00:00
{
2016-09-28 20:28:44 +00:00
log_info ( " Watchdog: Temperature retain trigger set to %uc " , user_options - > gpu_temp_retain ) ;
2016-09-26 15:15:07 +00:00
}
else
{
2016-09-28 20:28:44 +00:00
log_info ( " Watchdog: Temperature retain trigger disabled " ) ;
2016-09-26 15:15:07 +00:00
}
if ( user_options - > quiet = = false ) log_info ( " " ) ;
}
2016-09-26 21:20:26 +00:00
# if defined (DEBUG)
if ( user_options - > benchmark = = true ) log_info ( " Hashmode: %d " , hashconfig - > hash_mode ) ;
# endif
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > quiet = = false ) log_info_nn ( " Initializing device kernels and memory... " ) ;
2016-09-26 15:15:07 +00:00
2016-09-27 09:03:45 +00:00
u64 * words_progress_done = ( u64 * ) mycalloc ( hashes - > salts_cnt , sizeof ( u64 ) ) ;
u64 * words_progress_rejected = ( u64 * ) mycalloc ( hashes - > salts_cnt , sizeof ( u64 ) ) ;
u64 * words_progress_restored = ( u64 * ) mycalloc ( hashes - > salts_cnt , sizeof ( u64 ) ) ;
data . words_progress_done = words_progress_done ;
data . words_progress_rejected = words_progress_rejected ;
data . words_progress_restored = words_progress_restored ;
2016-09-26 21:20:26 +00:00
/*
session_ctx_t * session_ctx = ( session_ctx_t * ) mymalloc ( sizeof ( session_ctx_t ) ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
data . session_ctx = session_ctx ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
session_ctx_init ( session_ctx ) ;
*/
2016-09-26 15:15:07 +00:00
2016-09-27 11:13:07 +00:00
opencl_session_begin ( opencl_ctx , hashconfig , hashes , straight_ctx , user_options , user_options_extra , folder_config , bitmap_ctx , tuning_db ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > quiet = = false ) log_info_nn ( " " ) ;
/**
* In benchmark - mode , inform user which algorithm is checked
*/
if ( user_options - > benchmark = = true )
{
if ( user_options - > machine_readable = = false )
{
char * hash_type = strhashtype ( hashconfig - > hash_mode ) ; // not a bug
log_info ( " Hashtype: %s " , hash_type ) ;
log_info ( " " ) ;
2016-09-26 15:15:07 +00:00
}
}
/**
2016-09-26 21:20:26 +00:00
* weak hash check is the first to write to potfile , so open it for writing from here
2016-09-26 15:15:07 +00:00
*/
2016-09-26 21:20:26 +00:00
potfile_write_open ( potfile_ctx ) ;
/**
* weak hash check
*/
if ( user_options - > weak_hash_threshold > = hashes - > salts_cnt )
2016-09-26 15:15:07 +00:00
{
2016-09-26 21:20:26 +00:00
hc_device_param_t * device_param = NULL ;
2016-09-26 15:15:07 +00:00
for ( uint device_id = 0 ; device_id < opencl_ctx - > devices_cnt ; device_id + + )
{
2016-09-26 21:20:26 +00:00
device_param = & opencl_ctx - > devices_param [ device_id ] ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
if ( device_param - > skipped ) continue ;
2016-09-26 21:20:26 +00:00
break ;
}
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > quiet = = false ) log_info_nn ( " Checking for weak hashes... " ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
for ( uint salt_pos = 0 ; salt_pos < hashes - > salts_cnt ; salt_pos + + )
{
2016-09-27 16:32:09 +00:00
weak_hash_check ( opencl_ctx , device_param , user_options , user_options_extra , straight_ctx , combinator_ctx , hashconfig , hashes , salt_pos ) ;
2016-09-26 21:20:26 +00:00
}
}
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
/**
* status and monitor threads
*/
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
uint inner_threads_cnt = 0 ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
hc_thread_t * inner_threads = ( hc_thread_t * ) mycalloc ( 10 , sizeof ( hc_thread_t ) ) ;
2016-09-26 15:15:07 +00:00
2016-09-28 20:38:09 +00:00
data . shutdown_inner = false ;
2016-09-28 11:51:00 +00:00
2016-09-26 21:20:26 +00:00
/**
* Outfile remove
*/
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > keyspace = = false & & user_options - > benchmark = = false & & user_options - > stdout_flag = = false )
{
hc_thread_create ( inner_threads [ inner_threads_cnt ] , thread_monitor , NULL ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
inner_threads_cnt + + ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( outcheck_ctx - > enabled = = true )
{
hc_thread_create ( inner_threads [ inner_threads_cnt ] , thread_outfile_remove , NULL ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
inner_threads_cnt + + ;
}
}
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
/**
* main loop
*/
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > quiet = = false )
{
if ( potfile_remove_cracks > 0 )
{
if ( potfile_remove_cracks = = 1 )
{
log_info ( " INFO: Removed 1 hash found in potfile " ) ;
log_info ( " " ) ;
}
else
{
log_info ( " INFO: Removed %d hashes found in potfile " , potfile_remove_cracks ) ;
log_info ( " " ) ;
}
}
}
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
// still needed?
// mask_ctx->masks_cnt = maskcnt;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
restore_data_t * rd = restore_ctx - > rd ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( mask_ctx - > masks_cnt )
{
for ( uint masks_pos = rd - > masks_pos ; masks_pos < mask_ctx - > masks_cnt ; masks_pos + + )
{
if ( masks_pos > rd - > masks_pos )
{
rd - > dictpos = 0 ;
}
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
rd - > masks_pos = masks_pos ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
mask_ctx - > masks_pos = masks_pos ;
2016-09-26 15:15:07 +00:00
2016-09-28 20:28:44 +00:00
const int rc_inner1_loop = inner1_loop ( user_options , user_options_extra , restore_ctx , logfile_ctx , induct_ctx , dictstat_ctx , loopback_ctx , opencl_ctx , hwmon_ctx , hashconfig , hashes , wl_data , straight_ctx , combinator_ctx , mask_ctx ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_inner1_loop = = - 1 ) return - 1 ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( opencl_ctx - > run_main_level2 = = false ) break ;
}
}
else
{
2016-09-28 20:28:44 +00:00
const int rc_inner1_loop = inner1_loop ( user_options , user_options_extra , restore_ctx , logfile_ctx , induct_ctx , dictstat_ctx , loopback_ctx , opencl_ctx , hwmon_ctx , hashconfig , hashes , wl_data , straight_ctx , combinator_ctx , mask_ctx ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_inner1_loop = = - 1 ) return - 1 ;
}
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
/* ???????? TODO
// problems could occur if already at startup everything was cracked (because of .pot file reading etc), we must set some variables here to avoid NULL pointers
if ( user_options - > attack_mode = = ATTACK_MODE_STRAIGHT )
{
if ( user_options_extra - > wordlist_mode = = WL_MODE_FILE )
{
if ( data . dictfile = = NULL )
{
if ( dictfiles ! = NULL )
{
data . dictfile = dictfiles [ 0 ] ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
hc_timer_set ( & data . timer_running ) ;
}
}
}
}
// NOTE: combi is okay because it is already set beforehand
else if ( user_options - > attack_mode = = ATTACK_MODE_HYBRID1 | | user_options - > attack_mode = = ATTACK_MODE_HYBRID2 )
{
if ( data . dictfile = = NULL )
{
if ( dictfiles ! = NULL )
{
hc_timer_set ( & data . timer_running ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
data . dictfile = dictfiles [ 0 ] ;
}
}
}
else if ( user_options - > attack_mode = = ATTACK_MODE_BF )
{
if ( mask_ctx - > mask = = NULL )
{
hc_timer_set ( & data . timer_running ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
mask_ctx - > mask = mask_ctx - > masks [ 0 ] ;
}
}
*/
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
// if cracked / aborted remove last induction dictionary
induct_ctx_cleanup ( induct_ctx ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
// wait for inner threads
2016-09-26 15:15:07 +00:00
2016-09-28 20:38:09 +00:00
data . shutdown_inner = true ;
2016-09-28 11:51:00 +00:00
2016-09-26 21:20:26 +00:00
for ( uint thread_idx = 0 ; thread_idx < inner_threads_cnt ; thread_idx + + )
{
hc_thread_wait ( 1 , & inner_threads [ thread_idx ] ) ;
}
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
myfree ( inner_threads ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
// we dont need restore file anymore
if ( restore_ctx - > enabled = = true )
{
if ( ( opencl_ctx - > devices_status = = STATUS_EXHAUSTED ) | | ( opencl_ctx - > devices_status = = STATUS_CRACKED ) )
{
if ( opencl_ctx - > run_thread_level1 = = true ) // this is to check for [c]heckpoint
{
unlink ( restore_ctx - > eff_restore_file ) ;
unlink ( restore_ctx - > new_restore_file ) ;
2016-09-23 20:51:42 +00:00
}
2016-09-26 21:20:26 +00:00
else
2016-09-23 20:51:42 +00:00
{
2016-09-26 21:20:26 +00:00
cycle_restore ( restore_ctx , opencl_ctx ) ;
}
}
else
{
cycle_restore ( restore_ctx , opencl_ctx ) ;
}
}
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
// finally save left hashes
if ( ( hashes - > hashlist_mode = = HL_MODE_FILE ) & & ( user_options - > remove = = true ) & & ( hashes - > digests_saved ! = hashes - > digests_done ) )
{
save_hash ( user_options , hashconfig , hashes ) ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* Clean up
*/
2016-09-26 15:15:07 +00:00
2016-09-27 09:03:45 +00:00
myfree ( words_progress_done ) ;
myfree ( words_progress_rejected ) ;
myfree ( words_progress_restored ) ;
2016-09-26 21:20:26 +00:00
opencl_session_destroy ( opencl_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
potfile_write_close ( potfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
bitmap_ctx_destroy ( bitmap_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
mask_ctx_destroy ( mask_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-27 16:32:09 +00:00
combinator_ctx_destroy ( combinator_ctx ) ;
2016-09-27 11:13:07 +00:00
straight_ctx_destroy ( straight_ctx ) ;
2016-09-26 21:20:26 +00:00
hashes_destroy ( hashes ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
hashconfig_destroy ( hashconfig ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
wl_data_destroy ( wl_data ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
return 0 ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
int main ( int argc , char * * argv )
{
/**
* To help users a bit
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_console = setup_console ( ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_console = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
setup_environment_variables ( ) ;
setup_umask ( ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
2016-09-26 21:20:26 +00:00
* Real init
2016-09-26 15:15:07 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
memset ( & data , 0 , sizeof ( hc_global_data_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
time_t proc_start ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
time ( & proc_start ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
data . proc_start = proc_start ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
hc_thread_mutex_init ( mux_display ) ;
hc_thread_mutex_init ( mux_hwmon ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
/**
* folder
*/
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
char * install_folder = NULL ;
char * shared_folder = NULL ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
# if defined (INSTALL_FOLDER)
install_folder = INSTALL_FOLDER ;
# endif
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
# if defined (SHARED_FOLDER)
shared_folder = SHARED_FOLDER ;
# endif
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
folder_config_t * folder_config = ( folder_config_t * ) mymalloc ( sizeof ( folder_config_t ) ) ;
2016-09-26 15:15:07 +00:00
2016-09-26 21:20:26 +00:00
folder_config_init ( folder_config , install_folder , shared_folder ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
2016-09-26 21:20:26 +00:00
* commandline parameters
2016-09-26 15:15:07 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
user_options_t * user_options = ( user_options_t * ) mymalloc ( sizeof ( user_options_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
data . user_options = user_options ;
2016-09-24 23:02:44 +00:00
2016-09-26 21:20:26 +00:00
user_options_init ( user_options ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_user_options_parse = user_options_parse ( user_options , argc , argv ) ;
if ( rc_user_options_parse = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
2016-09-26 21:20:26 +00:00
* some early exits
2016-09-26 15:15:07 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > version = = true )
2016-09-26 15:15:07 +00:00
{
2016-09-26 21:20:26 +00:00
log_info ( " %s " , VERSION_TAG ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
return 0 ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > usage = = true )
{
usage_big_print ( PROGNAME ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
return 0 ;
2016-09-26 15:15:07 +00:00
}
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
2016-09-26 21:20:26 +00:00
* restore
2016-09-26 15:15:07 +00:00
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
restore_ctx_t * restore_ctx = ( restore_ctx_t * ) mymalloc ( sizeof ( restore_ctx_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
data . restore_ctx = restore_ctx ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_restore_init = restore_ctx_init ( restore_ctx , user_options , folder_config , argc , argv ) ;
if ( rc_restore_init = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
2016-09-26 21:20:26 +00:00
* process user input
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
user_options_extra_t * user_options_extra = ( user_options_extra_t * ) mymalloc ( sizeof ( user_options_extra_t ) ) ;
data . user_options_extra = user_options_extra ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_user_options_extra_init = user_options_extra_init ( user_options , restore_ctx , user_options_extra ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_user_options_extra_init = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_user_options_sanity = user_options_sanity ( user_options , restore_ctx , user_options_extra ) ;
if ( rc_user_options_sanity = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 15:15:07 +00:00
/**
2016-09-26 21:20:26 +00:00
* prepare seeding for random number generator , required by logfile and rules generator
2016-09-26 15:15:07 +00:00
*/
2016-09-28 21:53:46 +00:00
setup_seeding ( user_options - > rp_gen_seed_chgd , user_options - > rp_gen_seed ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* Inform user things getting started ,
* - this is giving us a visual header before preparations start , so we do not need to clear them afterwards
*/
2015-12-04 14:47:52 +00:00
2016-09-28 21:53:46 +00:00
welcome_screen ( user_options , proc_start ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* logfile init
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
logfile_ctx_t * logfile_ctx = ( logfile_ctx_t * ) mymalloc ( sizeof ( logfile_ctx_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
data . logfile_ctx = logfile_ctx ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
logfile_init ( logfile_ctx , user_options , folder_config ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
logfile_generate_topid ( logfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
logfile_top_msg ( " START " ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
user_options_logger ( user_options , logfile_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* tuning db
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
char tuning_db_file [ 256 ] = { 0 } ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
snprintf ( tuning_db_file , sizeof ( tuning_db_file ) - 1 , " %s/%s " , folder_config - > shared_dir , TUNING_DB_FILE ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
tuning_db_t * tuning_db = tuning_db_init ( tuning_db_file ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* induction directory
*/
2016-01-15 16:23:07 +00:00
2016-09-26 21:20:26 +00:00
induct_ctx_t * induct_ctx = ( induct_ctx_t * ) mymalloc ( sizeof ( induct_ctx_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
data . induct_ctx = induct_ctx ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_induct_ctx_init = induct_ctx_init ( induct_ctx , user_options , folder_config , proc_start ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_induct_ctx_init = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* outfile - check directory
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
outcheck_ctx_t * outcheck_ctx = ( outcheck_ctx_t * ) mymalloc ( sizeof ( outcheck_ctx_t ) ) ;
2016-07-10 11:23:06 +00:00
2016-09-26 21:20:26 +00:00
data . outcheck_ctx = outcheck_ctx ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_outcheck_ctx_init = outcheck_ctx_init ( outcheck_ctx , user_options , folder_config ) ;
2016-07-10 11:23:06 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_outcheck_ctx_init = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
/**
2016-09-26 21:20:26 +00:00
* outfile itself
2016-09-23 20:51:42 +00:00
*/
2016-07-10 11:23:06 +00:00
2016-09-26 21:20:26 +00:00
outfile_ctx_t * outfile_ctx = mymalloc ( sizeof ( outfile_ctx_t ) ) ;
2016-07-10 11:23:06 +00:00
2016-09-26 21:20:26 +00:00
data . outfile_ctx = outfile_ctx ;
2016-07-10 11:23:06 +00:00
2016-09-26 21:20:26 +00:00
outfile_init ( outfile_ctx , user_options ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* Sanity check for hashfile vs outfile ( should not point to the same physical file )
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_outfile_and_hashfile = outfile_and_hashfile ( outfile_ctx , restore_ctx - > argv [ user_options_extra - > optind ] ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_outfile_and_hashfile = = - 1 ) return - 1 ;
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
/**
* potfile init
* this is only setting path because potfile can be used in read and write mode depending on user options
* plus it depends on hash_mode , so we continue using it in outer_loop
*/
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
potfile_ctx_t * potfile_ctx = mymalloc ( sizeof ( potfile_ctx_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
data . potfile_ctx = potfile_ctx ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
potfile_init ( potfile_ctx , folder_config - > profile_dir , user_options - > potfile_path , user_options - > potfile_disable ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* dictstat init
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
dictstat_ctx_t * dictstat_ctx = mymalloc ( sizeof ( dictstat_ctx_t ) ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
dictstat_init ( dictstat_ctx , user_options , folder_config ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* loopback init
*/
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
loopback_ctx_t * loopback_ctx = mymalloc ( sizeof ( loopback_ctx_t ) ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
data . loopback_ctx = loopback_ctx ;
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
loopback_init ( loopback_ctx ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
/**
* debugfile init
*/
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
debugfile_ctx_t * debugfile_ctx = mymalloc ( sizeof ( debugfile_ctx_t ) ) ;
data . debugfile_ctx = debugfile_ctx ;
debugfile_init ( debugfile_ctx , user_options - > debug_mode , user_options - > debug_file ) ;
2016-09-23 20:51:42 +00:00
2016-09-26 21:20:26 +00:00
/**
* cpu affinity
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( user_options - > cpu_affinity )
{
set_cpu_affinity ( user_options - > cpu_affinity ) ;
}
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
/**
* Init OpenCL library loader
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
opencl_ctx_t * opencl_ctx = ( opencl_ctx_t * ) mymalloc ( sizeof ( opencl_ctx_t ) ) ;
2016-09-17 15:05:01 +00:00
2016-09-26 21:20:26 +00:00
data . opencl_ctx = opencl_ctx ;
2016-09-17 15:05:01 +00:00
2016-09-26 21:20:26 +00:00
const int rc_opencl_init = opencl_ctx_init ( opencl_ctx , user_options ) ;
2016-09-17 15:05:01 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_opencl_init = = - 1 )
2016-09-23 20:51:42 +00:00
{
2016-09-26 21:20:26 +00:00
log_error ( " ERROR: opencl_ctx_init() failed " ) ;
2016-09-17 15:05:01 +00:00
2016-09-26 21:20:26 +00:00
return - 1 ;
}
2016-09-17 15:05:01 +00:00
2016-09-26 21:20:26 +00:00
/**
* Init OpenCL devices
*/
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
const int rc_devices_init = opencl_ctx_devices_init ( opencl_ctx , user_options ) ;
2015-12-04 14:47:52 +00:00
2016-09-26 21:20:26 +00:00
if ( rc_devices_init = = - 1 )
{
log_error ( " ERROR: opencl_ctx_devices_init() failed " ) ;
2016-06-25 19:56:18 +00:00
2016-09-26 21:20:26 +00:00
return - 1 ;
}
2016-06-02 10:32:24 +00:00
2016-09-26 21:20:26 +00:00
/**
* HM devices : init
*/
2016-06-02 10:32:24 +00:00
2016-09-28 13:26:56 +00:00
hwmon_ctx_t * hwmon_ctx = ( hwmon_ctx_t * ) mymalloc ( sizeof ( hwmon_ctx_t ) ) ;
data . hwmon_ctx = hwmon_ctx ;
2016-09-28 20:28:44 +00:00
const int rc_hwmon_init = hwmon_ctx_init ( hwmon_ctx , user_options , opencl_ctx ) ;
2016-09-28 13:26:56 +00:00
if ( rc_hwmon_init = = - 1 )
{
log_error ( " ERROR: hwmon_ctx_init() failed " ) ;
return - 1 ;
}
2016-09-23 20:51:42 +00:00
/**
2016-09-24 10:19:56 +00:00
* keypress thread
2016-09-23 20:51:42 +00:00
*/
2016-09-09 21:17:43 +00:00
2016-09-23 20:51:42 +00:00
uint outer_threads_cnt = 0 ;
2016-09-09 21:17:43 +00:00
2016-09-23 20:51:42 +00:00
hc_thread_t * outer_threads = ( hc_thread_t * ) mycalloc ( 10 , sizeof ( hc_thread_t ) ) ;
2016-09-09 21:17:43 +00:00
2016-09-28 20:38:09 +00:00
data . shutdown_outer = false ;
2016-09-28 11:51:00 +00:00
2016-09-23 20:51:42 +00:00
if ( user_options - > keyspace = = false & & user_options - > benchmark = = false & & user_options - > stdout_flag = = false )
{
if ( ( user_options_extra - > wordlist_mode = = WL_MODE_FILE ) | | ( user_options_extra - > wordlist_mode = = WL_MODE_MASK ) )
{
hc_thread_create ( outer_threads [ outer_threads_cnt ] , thread_keypress , NULL ) ;
2016-09-22 09:35:08 +00:00
2016-09-23 20:51:42 +00:00
outer_threads_cnt + + ;
}
}
2016-09-22 14:23:36 +00:00
2016-09-23 20:51:42 +00:00
/**
* outer loop
*/
2016-09-22 15:11:17 +00:00
2016-09-23 20:51:42 +00:00
if ( user_options - > benchmark = = true )
{
user_options - > quiet = true ;
2016-09-23 20:01:43 +00:00
2016-09-23 20:51:42 +00:00
if ( user_options - > hash_mode_chgd = = true )
{
2016-09-28 20:28:44 +00:00
const int rc = outer_loop ( user_options , user_options_extra , restore_ctx , folder_config , logfile_ctx , tuning_db , induct_ctx , outcheck_ctx , outfile_ctx , potfile_ctx , dictstat_ctx , loopback_ctx , opencl_ctx , hwmon_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( rc = = - 1 ) return - 1 ;
}
else
{
for ( int algorithm_pos = 0 ; algorithm_pos < DEFAULT_BENCHMARK_ALGORITHMS_CNT ; algorithm_pos + + )
{
user_options - > hash_mode = DEFAULT_BENCHMARK_ALGORITHMS_BUF [ algorithm_pos ] ;
2015-12-04 14:47:52 +00:00
2016-09-28 20:28:44 +00:00
const int rc = outer_loop ( user_options , user_options_extra , restore_ctx , folder_config , logfile_ctx , tuning_db , induct_ctx , outcheck_ctx , outfile_ctx , potfile_ctx , dictstat_ctx , loopback_ctx , opencl_ctx , hwmon_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( rc = = - 1 ) return - 1 ;
2016-09-24 11:23:18 +00:00
if ( opencl_ctx - > run_main_level1 = = false ) break ;
2016-09-23 20:51:42 +00:00
}
}
}
else
{
2016-09-28 20:28:44 +00:00
const int rc = outer_loop ( user_options , user_options_extra , restore_ctx , folder_config , logfile_ctx , tuning_db , induct_ctx , outcheck_ctx , outfile_ctx , potfile_ctx , dictstat_ctx , loopback_ctx , opencl_ctx , hwmon_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:51:42 +00:00
if ( rc = = - 1 ) return - 1 ;
2015-12-04 14:47:52 +00:00
}
2016-06-27 10:13:46 +00:00
// wait for outer threads
2016-09-28 20:38:09 +00:00
data . shutdown_outer = true ;
2016-09-28 11:51:00 +00:00
2016-06-26 14:09:05 +00:00
for ( uint thread_idx = 0 ; thread_idx < outer_threads_cnt ; thread_idx + + )
2016-06-25 10:05:16 +00:00
{
2016-06-26 14:09:05 +00:00
hc_thread_wait ( 1 , & outer_threads [ thread_idx ] ) ;
2016-06-25 10:05:16 +00:00
}
2016-09-26 21:22:07 +00:00
myfree ( outer_threads ) ;
2016-06-25 10:05:16 +00:00
2016-09-24 12:00:59 +00:00
if ( user_options - > benchmark = = true )
{
user_options - > quiet = false ;
}
2015-12-04 14:47:52 +00:00
// destroy others mutex
hc_thread_mutex_delete ( mux_display ) ;
2016-09-08 07:21:25 +00:00
hc_thread_mutex_delete ( mux_hwmon ) ;
2015-12-04 14:47:52 +00:00
// free memory
2016-09-24 11:10:19 +00:00
debugfile_destroy ( debugfile_ctx ) ;
2016-02-10 19:40:21 +00:00
tuning_db_destroy ( tuning_db ) ;
2016-09-24 11:05:09 +00:00
loopback_destroy ( loopback_ctx ) ;
2016-09-24 11:01:17 +00:00
dictstat_destroy ( dictstat_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-24 10:41:56 +00:00
potfile_destroy ( potfile_ctx ) ;
2016-09-24 11:01:17 +00:00
induct_ctx_destroy ( induct_ctx ) ;
2016-09-24 10:19:56 +00:00
outfile_destroy ( outfile_ctx ) ;
2016-09-22 20:40:47 +00:00
outcheck_ctx_destroy ( outcheck_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:01:43 +00:00
folder_config_destroy ( folder_config ) ;
user_options_extra_destroy ( user_options_extra ) ;
2016-09-28 20:28:44 +00:00
hwmon_ctx_destroy ( hwmon_ctx , user_options , opencl_ctx ) ;
2016-09-23 20:23:13 +00:00
2016-09-28 20:28:44 +00:00
opencl_ctx_devices_destroy ( opencl_ctx ) ;
2016-09-28 13:26:56 +00:00
2016-09-24 23:02:44 +00:00
restore_ctx_destroy ( restore_ctx ) ;
2015-12-04 14:47:52 +00:00
time_t proc_stop ;
time ( & proc_stop ) ;
logfile_top_uint ( proc_start ) ;
logfile_top_uint ( proc_stop ) ;
logfile_top_msg ( " STOP " ) ;
2016-09-23 19:41:05 +00:00
logfile_destroy ( logfile_ctx ) ;
2016-09-28 21:53:46 +00:00
goodbye_screen ( user_options , proc_start , proc_stop ) ;
2015-12-04 14:47:52 +00:00
2016-09-23 20:01:43 +00:00
user_options_destroy ( user_options ) ;
2016-09-17 18:18:38 +00:00
u32 rc_final = - 1 ;
2016-09-19 13:52:01 +00:00
if ( opencl_ctx - > devices_status = = STATUS_ABORTED ) rc_final = 2 ;
if ( opencl_ctx - > devices_status = = STATUS_QUIT ) rc_final = 2 ;
if ( opencl_ctx - > devices_status = = STATUS_EXHAUSTED ) rc_final = 1 ;
if ( opencl_ctx - > devices_status = = STATUS_CRACKED ) rc_final = 0 ;
2016-01-26 20:40:49 +00:00
2016-09-17 18:18:38 +00:00
opencl_ctx_destroy ( opencl_ctx ) ;
2015-12-04 14:47:52 +00:00
2016-09-17 18:18:38 +00:00
return rc_final ;
2015-12-04 14:47:52 +00:00
}