mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-15 12:29:35 +00:00
8458f07a57
The latter is more correct. The side effect is that filesize becomes smaller. gcc clang before O2 756112 762120 Os 674192 680216 after O2 748456 760728 Os 666536 674728
852 lines
20 KiB
C
852 lines
20 KiB
C
/**
|
|
* Author......: See docs/credits.txt
|
|
* License.....: MIT
|
|
*/
|
|
|
|
#include "common.h"
|
|
#include "types.h"
|
|
#include "rp.h"
|
|
#include "rp_cpu.h"
|
|
|
|
#define NEXT_RULEPOS(rp) if (++(rp) == rule_len) return (RULE_RC_SYNTAX_ERROR)
|
|
#define NEXT_RPTOI(r,rp,up) if (((up) = conv_pos ((r)[(rp)], pos_mem)) == -1) return (RULE_RC_SYNTAX_ERROR)
|
|
|
|
static int conv_pos (const u8 c, const int pos_mem)
|
|
{
|
|
if (c == RULE_LAST_REJECTED_SAVED_POS)
|
|
{
|
|
return pos_mem;
|
|
}
|
|
|
|
return conv_ctoi (c);
|
|
}
|
|
|
|
static void MANGLE_TOGGLE_AT (char *arr, const int pos)
|
|
{
|
|
if (class_alpha (arr[pos])) arr[pos] ^= 0x20;
|
|
}
|
|
|
|
static void MANGLE_LOWER_AT (char *arr, const int pos)
|
|
{
|
|
if (class_upper (arr[pos])) arr[pos] ^= 0x20;
|
|
}
|
|
|
|
static void MANGLE_UPPER_AT (char *arr, const int pos)
|
|
{
|
|
if (class_lower (arr[pos])) arr[pos] ^= 0x20;
|
|
}
|
|
|
|
static void MANGLE_SWITCH (char *arr, const int l, const int r)
|
|
{
|
|
char c = arr[r];
|
|
arr[r] = arr[l];
|
|
arr[l] = c;
|
|
}
|
|
|
|
static int mangle_lrest (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++) MANGLE_LOWER_AT (arr, pos);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_urest (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++) MANGLE_UPPER_AT (arr, pos);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_trest (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++) MANGLE_TOGGLE_AT (arr, pos);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_reverse (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
int l;
|
|
|
|
for (l = 0; l < arr_len; l++)
|
|
{
|
|
int r = arr_len - 1 - l;
|
|
|
|
if (l >= r) break;
|
|
|
|
MANGLE_SWITCH (arr, l, r);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_double (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
if ((arr_len * 2) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
memcpy (&arr[arr_len], arr, (size_t) arr_len);
|
|
|
|
return (arr_len * 2);
|
|
}
|
|
|
|
static int mangle_double_times (char arr[RP_PASSWORD_SIZE], int arr_len, int times)
|
|
{
|
|
if (((arr_len * times) + arr_len) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
int orig_len = arr_len;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < times; i++)
|
|
{
|
|
memcpy (&arr[arr_len], arr, orig_len);
|
|
|
|
arr_len += orig_len;
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_reflect (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
if ((arr_len * 2) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
mangle_double (arr, arr_len);
|
|
|
|
mangle_reverse (arr + arr_len, arr_len);
|
|
|
|
return (arr_len * 2);
|
|
}
|
|
|
|
static int mangle_rotate_left (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
int l;
|
|
int r;
|
|
|
|
for (l = 0, r = arr_len - 1; r > 0; r--)
|
|
{
|
|
MANGLE_SWITCH (arr, l, r);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_rotate_right (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
int l;
|
|
int r;
|
|
|
|
for (l = 0, r = arr_len - 1; l < r; l++)
|
|
{
|
|
MANGLE_SWITCH (arr, l, r);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_append (char arr[RP_PASSWORD_SIZE], int arr_len, char c)
|
|
{
|
|
if ((arr_len + 1) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
arr[arr_len] = c;
|
|
|
|
return (arr_len + 1);
|
|
}
|
|
|
|
static int mangle_prepend (char arr[RP_PASSWORD_SIZE], int arr_len, char c)
|
|
{
|
|
if ((arr_len + 1) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = arr_len - 1; arr_pos > -1; arr_pos--)
|
|
{
|
|
arr[arr_pos + 1] = arr[arr_pos];
|
|
}
|
|
|
|
arr[0] = c;
|
|
|
|
return (arr_len + 1);
|
|
}
|
|
|
|
static int mangle_delete_at (char arr[RP_PASSWORD_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = upos; arr_pos < arr_len - 1; arr_pos++)
|
|
{
|
|
arr[arr_pos] = arr[arr_pos + 1];
|
|
}
|
|
|
|
return (arr_len - 1);
|
|
}
|
|
|
|
static int mangle_extract (char arr[RP_PASSWORD_SIZE], int arr_len, int upos, int ulen)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
if ((upos + ulen) > arr_len) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = 0; arr_pos < ulen; arr_pos++)
|
|
{
|
|
arr[arr_pos] = arr[upos + arr_pos];
|
|
}
|
|
|
|
return (ulen);
|
|
}
|
|
|
|
static int mangle_omit (char arr[RP_PASSWORD_SIZE], int arr_len, int upos, int ulen)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
if ((upos + ulen) > arr_len) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = upos; arr_pos < arr_len - ulen; arr_pos++)
|
|
{
|
|
arr[arr_pos] = arr[arr_pos + ulen];
|
|
}
|
|
|
|
return (arr_len - ulen);
|
|
}
|
|
|
|
static int mangle_insert (char arr[RP_PASSWORD_SIZE], int arr_len, int upos, char c)
|
|
{
|
|
if (upos > arr_len) return (arr_len);
|
|
|
|
if ((arr_len + 1) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = arr_len - 1; arr_pos > upos - 1; arr_pos--)
|
|
{
|
|
arr[arr_pos + 1] = arr[arr_pos];
|
|
}
|
|
|
|
arr[upos] = c;
|
|
|
|
return (arr_len + 1);
|
|
}
|
|
|
|
static int mangle_insert_multi (char arr[RP_PASSWORD_SIZE], int arr_len, int arr_pos, char arr2[RP_PASSWORD_SIZE], int arr2_len, int arr2_pos, int arr2_cpy)
|
|
{
|
|
if ((arr_len + arr2_cpy) > RP_PASSWORD_SIZE) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (arr_pos > arr_len) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (arr2_pos > arr2_len) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if ((arr2_pos + arr2_cpy) > arr2_len) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (arr2_cpy < 1) return (RULE_RC_SYNTAX_ERROR);
|
|
|
|
memmove (arr2, arr2 + arr2_pos, arr2_len - arr2_pos);
|
|
|
|
memcpy (arr2 + arr2_cpy, arr + arr_pos, arr_len - arr_pos);
|
|
|
|
memcpy (arr + arr_pos, arr2, arr_len - arr_pos + arr2_cpy);
|
|
|
|
return (arr_len + arr2_cpy);
|
|
}
|
|
|
|
static int mangle_overstrike (char arr[RP_PASSWORD_SIZE], int arr_len, int upos, char c)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] = c;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_truncate_at (char arr[RP_PASSWORD_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
memset (arr + upos, 0, arr_len - upos);
|
|
|
|
return (upos);
|
|
}
|
|
|
|
static int mangle_replace (char arr[RP_PASSWORD_SIZE], int arr_len, char oldc, char newc)
|
|
{
|
|
int arr_pos;
|
|
|
|
for (arr_pos = 0; arr_pos < arr_len; arr_pos++)
|
|
{
|
|
if (arr[arr_pos] != oldc) continue;
|
|
|
|
arr[arr_pos] = newc;
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_purgechar (char arr[RP_PASSWORD_SIZE], int arr_len, char c)
|
|
{
|
|
int arr_pos;
|
|
|
|
int ret_len;
|
|
|
|
for (ret_len = 0, arr_pos = 0; arr_pos < arr_len; arr_pos++)
|
|
{
|
|
if (arr[arr_pos] == c) continue;
|
|
|
|
arr[ret_len] = arr[arr_pos];
|
|
|
|
ret_len++;
|
|
}
|
|
|
|
return (ret_len);
|
|
}
|
|
|
|
static int mangle_dupeblock_prepend (char arr[RP_PASSWORD_SIZE], int arr_len, int ulen)
|
|
{
|
|
if (ulen > arr_len) return (arr_len);
|
|
|
|
if ((arr_len + ulen) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
char cs[100] = { 0 };
|
|
|
|
memcpy (cs, arr, ulen);
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ulen; i++)
|
|
{
|
|
char c = cs[i];
|
|
|
|
arr_len = mangle_insert (arr, arr_len, i, c);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_dupeblock_append (char arr[RP_PASSWORD_SIZE], int arr_len, int ulen)
|
|
{
|
|
if (ulen > arr_len) return (arr_len);
|
|
|
|
if ((arr_len + ulen) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
int upos = arr_len - ulen;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ulen; i++)
|
|
{
|
|
char c = arr[upos + i];
|
|
|
|
arr_len = mangle_append (arr, arr_len, c);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_dupechar_at (char arr[RP_PASSWORD_SIZE], int arr_len, int upos, int ulen)
|
|
{
|
|
if ( arr_len == 0) return (arr_len);
|
|
if ((arr_len + ulen) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
char c = arr[upos];
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ulen; i++)
|
|
{
|
|
arr_len = mangle_insert (arr, arr_len, upos, c);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_dupechar (char arr[RP_PASSWORD_SIZE], int arr_len)
|
|
{
|
|
if ( arr_len == 0) return (arr_len);
|
|
if ((arr_len + arr_len) >= RP_PASSWORD_SIZE) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = arr_len - 1; arr_pos > -1; arr_pos--)
|
|
{
|
|
int new_pos = arr_pos * 2;
|
|
|
|
arr[new_pos] = arr[arr_pos];
|
|
|
|
arr[new_pos + 1] = arr[arr_pos];
|
|
}
|
|
|
|
return (arr_len * 2);
|
|
}
|
|
|
|
static int mangle_switch_at_check (char arr[RP_PASSWORD_SIZE], int arr_len, int upos, int upos2)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
if (upos2 >= arr_len) return (arr_len);
|
|
|
|
MANGLE_SWITCH (arr, upos, upos2);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_switch_at (char arr[RP_PASSWORD_SIZE], int arr_len, int upos, int upos2)
|
|
{
|
|
MANGLE_SWITCH (arr, upos, upos2);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_chr_shiftl (char arr[RP_PASSWORD_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] <<= 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_chr_shiftr (char arr[RP_PASSWORD_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] >>= 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_chr_incr (char arr[RP_PASSWORD_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] += 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_chr_decr (char arr[RP_PASSWORD_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] -= 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
static int mangle_title_sep (char arr[RP_PASSWORD_SIZE], int arr_len, char c)
|
|
{
|
|
int upper_next = 1;
|
|
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++)
|
|
{
|
|
if (arr[pos] == c)
|
|
{
|
|
upper_next = 1;
|
|
|
|
continue;
|
|
}
|
|
|
|
if (upper_next)
|
|
{
|
|
upper_next = 0;
|
|
|
|
MANGLE_UPPER_AT (arr, pos);
|
|
}
|
|
else
|
|
{
|
|
MANGLE_LOWER_AT (arr, pos);
|
|
}
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int _old_apply_rule (const char *rule, int rule_len, char in[RP_PASSWORD_SIZE], int in_len, char out[RP_PASSWORD_SIZE])
|
|
{
|
|
char mem[RP_PASSWORD_SIZE] = { 0 };
|
|
|
|
int pos_mem = -1;
|
|
|
|
if (in == NULL) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (out == NULL) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (in_len < 0 || in_len > RP_PASSWORD_SIZE) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (rule_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
|
|
int out_len = in_len;
|
|
int mem_len = in_len;
|
|
|
|
memcpy (out, in, out_len);
|
|
|
|
int rule_pos;
|
|
|
|
for (rule_pos = 0; rule_pos < rule_len; rule_pos++)
|
|
{
|
|
int upos, upos2;
|
|
int ulen;
|
|
|
|
switch (rule[rule_pos])
|
|
{
|
|
case ' ':
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_NOOP:
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST:
|
|
out_len = mangle_lrest (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST:
|
|
out_len = mangle_urest (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST_UFIRST:
|
|
out_len = mangle_lrest (out, out_len);
|
|
if (out_len) MANGLE_UPPER_AT (out, 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST_LFIRST:
|
|
out_len = mangle_urest (out, out_len);
|
|
if (out_len) MANGLE_LOWER_AT (out, 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TREST:
|
|
out_len = mangle_trest (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLE_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if (upos < out_len) MANGLE_TOGGLE_AT (out, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REVERSE:
|
|
out_len = mangle_reverse (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD:
|
|
out_len = mangle_double (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD_TIMES:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_double_times (out, out_len, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REFLECT:
|
|
out_len = mangle_reflect (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_LEFT:
|
|
mangle_rotate_left (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_RIGHT:
|
|
mangle_rotate_right (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_APPEND:
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_append (out, out_len, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PREPEND:
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_prepend (out, out_len, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_FIRST:
|
|
out_len = mangle_delete_at (out, out_len, 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_LAST:
|
|
out_len = mangle_delete_at (out, out_len, (out_len) ? out_len - 1 : 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
out_len = mangle_delete_at (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_EXTRACT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_extract (out, out_len, upos, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OMIT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_omit (out, out_len, upos, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_INSERT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_insert (out, out_len, upos, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OVERSTRIKE:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_overstrike (out, out_len, upos, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TRUNCATE_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
out_len = mangle_truncate_at (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_replace (out, out_len, rule[rule_pos - 1], rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PURGECHAR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_purgechar (out, out_len, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLECASE_REC:
|
|
/* todo */
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_FIRST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupechar_at (out, out_len, 0, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_LAST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupechar_at (out, out_len, out_len - 1, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_ALL:
|
|
out_len = mangle_dupechar (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_FIRST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupeblock_prepend (out, out_len, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_LAST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupeblock_append (out, out_len, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_FIRST:
|
|
if (out_len >= 2) mangle_switch_at (out, out_len, 0, 1);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_LAST:
|
|
if (out_len >= 2) mangle_switch_at (out, out_len, out_len - 1, out_len - 2);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos2);
|
|
out_len = mangle_switch_at_check (out, out_len, upos, upos2);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTL:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_shiftl (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_shiftr (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_INCR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_incr (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_DECR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_decr (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NP1:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos >= 0) && ((upos + 1) < out_len)) mangle_overstrike (out, out_len, upos, out[upos + 1]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NM1:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos >= 1) && ((upos + 0) < out_len)) mangle_overstrike (out, out_len, upos, out[upos - 1]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TITLE_SEP:
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_title_sep (out, out_len, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TITLE:
|
|
out_len = mangle_title_sep (out, out_len, ' ');
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_EXTRACT_MEMORY:
|
|
if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos2);
|
|
if ((out_len = mangle_insert_multi (out, out_len, upos2, mem, mem_len, upos, ulen)) < 1) return (out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_APPEND_MEMORY:
|
|
if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
if ((out_len + mem_len) >= RP_PASSWORD_SIZE) return (RULE_RC_REJECT_ERROR);
|
|
memcpy (out + out_len, mem, mem_len);
|
|
out_len += mem_len;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PREPEND_MEMORY:
|
|
if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
if ((mem_len + out_len) >= RP_PASSWORD_SIZE) return (RULE_RC_REJECT_ERROR);
|
|
memcpy (mem + mem_len, out, out_len);
|
|
out_len += mem_len;
|
|
memcpy (out, mem, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MEMORIZE_WORD:
|
|
memcpy (mem, out, out_len);
|
|
mem_len = out_len;
|
|
break;
|
|
|
|
case RULE_OP_REJECT_LESS:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if (out_len > upos) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_GREATER:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if (out_len < upos) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_EQUAL:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if (out_len != upos) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_CONTAIN:
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (strchr (out, rule[rule_pos]) != NULL) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_NOT_CONTAIN:
|
|
NEXT_RULEPOS (rule_pos);
|
|
char *match = strchr (out, rule[rule_pos]);
|
|
if (match != NULL)
|
|
{
|
|
pos_mem = (int)(match - out);
|
|
}
|
|
else
|
|
{
|
|
return (RULE_RC_REJECT_ERROR);
|
|
}
|
|
break;
|
|
|
|
case RULE_OP_REJECT_EQUAL_FIRST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (out[0] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_EQUAL_LAST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (out[out_len - 1] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_EQUAL_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos + 1) > out_len) return (RULE_RC_REJECT_ERROR);
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (out[upos] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_CONTAINS:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos + 1) > out_len) return (RULE_RC_REJECT_ERROR);
|
|
NEXT_RULEPOS (rule_pos);
|
|
int c; int cnt;
|
|
for (c = 0, cnt = 0; c < out_len && cnt < upos; c++)
|
|
{
|
|
if (out[c] == rule[rule_pos])
|
|
{
|
|
cnt++;
|
|
pos_mem = c;
|
|
}
|
|
}
|
|
|
|
if (cnt < upos) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_MEMORY:
|
|
if ((out_len == mem_len) && (memcmp (out, mem, out_len) == 0)) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
default:
|
|
return (RULE_RC_SYNTAX_ERROR);
|
|
}
|
|
}
|
|
|
|
memset (out + out_len, 0, RP_PASSWORD_SIZE - out_len);
|
|
|
|
return (out_len);
|
|
}
|
|
|
|
int run_rule_engine (const int rule_len, const char *rule_buf)
|
|
{
|
|
if (rule_len == 0) return 0;
|
|
|
|
if (rule_len == 1)
|
|
if (rule_buf[0] == RULE_OP_MANGLE_NOOP) return 0;
|
|
|
|
return 1;
|
|
}
|