beautifications

This commit is contained in:
van Hauser 2015-05-07 13:16:57 +02:00
commit e1419a0002
2 changed files with 4002 additions and 3937 deletions

120
hydra.c
View file

@ -1,3 +1,4 @@
/* /*
* hydra (c) 2001-2014 by van Hauser / THC <vh@thc.org> * hydra (c) 2001-2014 by van Hauser / THC <vh@thc.org>
* http://www.thc.org * http://www.thc.org
@ -48,13 +49,11 @@ extern void service_xmpp(char *target, char *ip, int sp, unsigned char options,
extern void service_irc(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_irc(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern void service_http_proxy_urlenum(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_http_proxy_urlenum(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern void service_s7_300(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_s7_300(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE
extern void service_rtsp(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_rtsp(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
#ifdef HAVE_MATH_H #ifdef HAVE_MATH_H
extern void service_mysql(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern void service_mysql(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern int service_mysql_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_mysql_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
@ -138,14 +137,14 @@ extern int service_vmauthd_init(char *ip, int sp, unsigned char options, char *m
extern int service_vnc_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_vnc_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern int service_xmpp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_xmpp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
extern int service_s7_300_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_s7_300_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE
extern int service_rtsp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port); extern int service_rtsp_init(char *ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port);
// ADD NEW SERVICES HERE
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
char *SERVICES = char *SERVICES =
"asterisk afp cisco cisco-enable cvs firebird ftp ftps http[s]-{head|get} http[s]-{get|post}-form http-proxy http-proxy-urlenum icq imap[s] irc ldap2[s] ldap3[-{cram|digest}md5][s] mssql mysql ncp nntp oracle oracle-listener oracle-sid pcanywhere pcnfs pop3[s] postgres rdp redis rexec rlogin rsh s7-300 sapr3 sip smb smtp[s] smtp-enum snmp socks5 ssh sshkey svn teamspeak telnet[s] vmauthd vnc xmpp rtsp"; "asterisk afp cisco cisco-enable cvs firebird ftp ftps http[s]-{head|get} http[s]-{get|post}-form http-proxy http-proxy-urlenum icq imap[s] irc ldap2[s] ldap3[-{cram|digest}md5][s] mssql mysql ncp nntp oracle oracle-listener oracle-sid pcanywhere pcnfs pop3[s] postgres rdp redis rexec rlogin rsh rtsp s7-300 sapr3 sip smb smtp[s] smtp-enum snmp socks5 ssh sshkey svn teamspeak telnet[s] vmauthd vnc xmpp";
#define MAXBUF 520 #define MAXBUF 520
#define MAXLINESIZE ( ( MAXBUF / 2 ) - 4 ) #define MAXLINESIZE ( ( MAXBUF / 2 ) - 4 )
@ -768,7 +767,8 @@ void hydra_restore_read() {
int i, j, orig_debug = debug; int i, j, orig_debug = debug;
char out[1024]; char out[1024];
if (debug) printf("[DEBUG] reading restore file %s\n", RESTOREFILE); if (debug)
printf("[DEBUG] reading restore file %s\n", RESTOREFILE);
if ((f = fopen(RESTOREFILE, "r")) == NULL) { if ((f = fopen(RESTOREFILE, "r")) == NULL) {
fprintf(stderr, "[ERROR] restore file (%s) not found - ", RESTOREFILE); fprintf(stderr, "[ERROR] restore file (%s) not found - ", RESTOREFILE);
perror(""); perror("");
@ -784,7 +784,8 @@ void hydra_restore_read() {
} }
fck = (int) fread(&bf_options, sizeof(bf_options), 1, f); fck = (int) fread(&bf_options, sizeof(bf_options), 1, f);
fck = (int) fread(mynull, sizeof(mynull), 1, f); fck = (int) fread(mynull, sizeof(mynull), 1, f);
if (debug) printf("[DEBUG] reading restore file: Step 1 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 1 complete\n");
if (mynull[0] + mynull[1] + mynull[2] + mynull[3] == 0) { if (mynull[0] + mynull[1] + mynull[2] + mynull[3] == 0) {
bf_options.crs = NULL; bf_options.crs = NULL;
} else { } else {
@ -792,7 +793,8 @@ void hydra_restore_read() {
memcpy(bf_options.crs, mynull, sizeof(mynull)); memcpy(bf_options.crs, mynull, sizeof(mynull));
fck = fread(bf_options.crs + sizeof(mynull), BF_CHARSMAX - sizeof(mynull), 1, f); fck = fread(bf_options.crs + sizeof(mynull), BF_CHARSMAX - sizeof(mynull), 1, f);
} }
if (debug) printf("[DEBUG] reading restore file: Step 2 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 2 complete\n");
fck = (int) fread(&hydra_brains, sizeof(hydra_brain), 1, f); fck = (int) fread(&hydra_brains, sizeof(hydra_brain), 1, f);
hydra_brains.ofp = stdout; hydra_brains.ofp = stdout;
@ -800,7 +802,8 @@ void hydra_restore_read() {
hydra_options.restore = 1; hydra_options.restore = 1;
verbose = hydra_options.verbose; verbose = hydra_options.verbose;
debug = hydra_options.debug; debug = hydra_options.debug;
if (debug || orig_debug) printf("[DEBUG] run_debug %d, orig_debug %d\n", debug, orig_debug); if (debug || orig_debug)
printf("[DEBUG] run_debug %d, orig_debug %d\n", debug, orig_debug);
if (orig_debug) { if (orig_debug) {
debug = 1; debug = 1;
hydra_options.debug = 1; hydra_options.debug = 1;
@ -815,35 +818,42 @@ void hydra_restore_read() {
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] reading restore file: Step 3 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 3 complete\n");
if (strlen(out) > 0) { if (strlen(out) > 0) {
hydra_options.outfile_ptr = malloc(strlen(out) + 1); hydra_options.outfile_ptr = malloc(strlen(out) + 1);
strcpy(hydra_options.outfile_ptr, out); strcpy(hydra_options.outfile_ptr, out);
} else } else
hydra_options.outfile_ptr = NULL; hydra_options.outfile_ptr = NULL;
if (debug) printf("[DEBUG] reading restore file: Step 4 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 4 complete\n");
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] reading restore file: Step 5 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 5 complete\n");
if (strlen(out) == 0) if (strlen(out) == 0)
hydra_options.miscptr = NULL; hydra_options.miscptr = NULL;
else { else {
hydra_options.miscptr = malloc(strlen(out) + 1); hydra_options.miscptr = malloc(strlen(out) + 1);
strcpy(hydra_options.miscptr, out); strcpy(hydra_options.miscptr, out);
} }
if (debug) printf("[DEBUG] reading restore file: Step 6 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 6 complete\n");
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] reading restore file: Step 7 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 7 complete\n");
hydra_options.service = malloc(strlen(out) + 1); hydra_options.service = malloc(strlen(out) + 1);
strcpy(hydra_options.service, out); strcpy(hydra_options.service, out);
if (debug) printf("[DEBUG] reading restore file: Step 8 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 8 complete\n");
login_ptr = malloc(hydra_brains.sizelogin); login_ptr = malloc(hydra_brains.sizelogin);
fck = (int) fread(login_ptr, hydra_brains.sizelogin, 1, f); fck = (int) fread(login_ptr, hydra_brains.sizelogin, 1, f);
if (debug) printf("[DEBUG] reading restore file: Step 9 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 9 complete\n");
if ((hydra_options.mode & 64) != 64) { // NOT colonfile mode if ((hydra_options.mode & 64) != 64) { // NOT colonfile mode
pass_ptr = malloc(hydra_brains.sizepass); pass_ptr = malloc(hydra_brains.sizepass);
fck = (int) fread(pass_ptr, hydra_brains.sizepass, 1, f); fck = (int) fread(pass_ptr, hydra_brains.sizepass, 1, f);
@ -851,7 +861,8 @@ void hydra_restore_read() {
hydra_options.colonfile = empty_login; // dummy hydra_options.colonfile = empty_login; // dummy
pass_ptr = csv_ptr = login_ptr; pass_ptr = csv_ptr = login_ptr;
} }
if (debug) printf("[DEBUG] reading restore file: Step 10 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 10 complete\n");
hydra_targets = malloc((hydra_brains.targets + 3) * sizeof(hydra_targets)); hydra_targets = malloc((hydra_brains.targets + 3) * sizeof(hydra_targets));
for (j = 0; j < hydra_brains.targets; j++) { for (j = 0; j < hydra_brains.targets; j++) {
@ -901,7 +912,8 @@ void hydra_restore_read() {
hydra_targets[j]->use_count = 0; hydra_targets[j]->use_count = 0;
hydra_targets[j]->failed = 0; hydra_targets[j]->failed = 0;
} }
if (debug) printf("[DEBUG] reading restore file: Step 11 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 11 complete\n");
hydra_heads = malloc((hydra_options.max_use + 2) * sizeof(int) + 8); hydra_heads = malloc((hydra_options.max_use + 2) * sizeof(int) + 8);
for (j = 0; j < hydra_options.max_use; j++) { for (j = 0; j < hydra_options.max_use; j++) {
hydra_heads[j] = malloc(sizeof(hydra_head)); hydra_heads[j] = malloc(sizeof(hydra_head));
@ -919,7 +931,8 @@ void hydra_restore_read() {
if (hydra_heads[j]->redo) { if (hydra_heads[j]->redo) {
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
if (debug) printf("[DEBUG] TEMP head %d: out[0] == %d, hydra_heads[j]->current_login_ptr[0] == %d\n", j, out[0], hydra_heads[j]->current_login_ptr[0]); if (debug)
printf("[DEBUG] TEMP head %d: out[0] == %d, hydra_heads[j]->current_login_ptr[0] == %d\n", j, out[0], hydra_heads[j]->current_login_ptr[0]);
if (out[0] != 0 || hydra_heads[j]->current_login_ptr[0] != 0) { if (out[0] != 0 || hydra_heads[j]->current_login_ptr[0] != 0) {
hydra_heads[j]->current_pass_ptr = malloc(strlen(out) + 1); hydra_heads[j]->current_pass_ptr = malloc(strlen(out) + 1);
strcpy(hydra_heads[j]->current_pass_ptr, out); strcpy(hydra_heads[j]->current_pass_ptr, out);
@ -934,7 +947,8 @@ void hydra_restore_read() {
hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login; hydra_heads[j]->current_login_ptr = hydra_heads[j]->current_pass_ptr = empty_login;
} }
} }
if (debug) printf("[DEBUG] reading restore file: Step 12 complete\n"); if (debug)
printf("[DEBUG] reading restore file: Step 12 complete\n");
sck = fgets(out, sizeof(out), f); sck = fgets(out, sizeof(out), f);
if (out[0] != 0 && out[strlen(out) - 1] == '\n') if (out[0] != 0 && out[strlen(out) - 1] == '\n')
out[strlen(out) - 1] = 0; out[strlen(out) - 1] = 0;
@ -1185,10 +1199,10 @@ void hydra_service_init(int target_no) {
x = service_xmpp_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); x = service_xmpp_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
if (strcmp(hydra_options.service, "s7-300") == 0) if (strcmp(hydra_options.service, "s7-300") == 0)
x = service_s7_300_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); x = service_s7_300_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
// ADD NEW SERVICES HERE
if (strcmp(hydra_options.service, "rtsp") == 0) if (strcmp(hydra_options.service, "rtsp") == 0)
x = service_rtsp_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); x = service_rtsp_init(hydra_targets[target_no]->ip, -1, options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
// ADD NEW SERVICES HERE
if (x != 0 && x != 99) { if (x != 0 && x != 99) {
if (x > 0 && x < 4) if (x > 0 && x < 4)
@ -1386,12 +1400,11 @@ int hydra_spawn_head(int head_no, int target_no) {
#endif #endif
if (strcmp(hydra_options.service, "s7-300") == 0) if (strcmp(hydra_options.service, "s7-300") == 0)
service_s7_300(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port); service_s7_300(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
if (strcmp(hydra_options.service, "rtsp") == 0)
service_rtsp(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
if (strcmp(hydra_options.service, "rtsp") == 0){
service_rtsp(hydra_targets[target_no]->ip, hydra_heads[head_no]->sp[1], options, hydra_options.miscptr, hydra_brains.ofp, hydra_targets[target_no]->port);
}
// just in case a module returns (which it shouldnt) we let it exit here // just in case a module returns (which it shouldnt) we let it exit here
exit(-1); exit(-1);
} else { } else {
@ -1485,8 +1498,8 @@ int hydra_lookup_port(char *service) {
{"rdp", PORT_RDP, PORT_RDP_SSL}, {"rdp", PORT_RDP, PORT_RDP_SSL},
{"asterisk", PORT_ASTERISK, PORT_ASTERISK_SSL}, {"asterisk", PORT_ASTERISK, PORT_ASTERISK_SSL},
{"s7-300", PORT_S7_300, PORT_S7_300_SSL}, {"s7-300", PORT_S7_300, PORT_S7_300_SSL},
// ADD NEW SERVICES HERE - add new port numbers to hydra.h
{"rtsp", PORT_RTSP, PORT_RTSP_SSL}, {"rtsp", PORT_RTSP, PORT_RTSP_SSL},
// ADD NEW SERVICES HERE - add new port numbers to hydra.h
{"", PORT_NOPORT, PORT_NOPORT} {"", PORT_NOPORT, PORT_NOPORT}
}; };
@ -1507,7 +1520,8 @@ int hydra_lookup_port(char *service) {
// killit = 1 : kill(pid); fail = 1 : redo, fail = 2/3 : disable // killit = 1 : kill(pid); fail = 1 : redo, fail = 2/3 : disable
void hydra_kill_head(int head_no, int killit, int fail) { void hydra_kill_head(int head_no, int killit, int fail) {
if (debug) printf("[DEBUG] head_no %d, kill %d, fail %d\n", head_no, killit, fail); if (debug)
printf("[DEBUG] head_no %d, kill %d, fail %d\n", head_no, killit, fail);
if (head_no < 0) if (head_no < 0)
return; return;
if (hydra_heads[head_no]->active > 0) { if (hydra_heads[head_no]->active > 0) {
@ -2972,6 +2986,7 @@ int main(int argc, char *argv[]) {
} }
// ADD NEW SERVICES HERE // ADD NEW SERVICES HERE
if (i == 0) { if (i == 0) {
fprintf(stderr, "[ERROR] Unknown service: %s\n", hydra_options.service); fprintf(stderr, "[ERROR] Unknown service: %s\n", hydra_options.service);
exit(-1); exit(-1);
@ -3044,7 +3059,6 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[WARNING] reducing maximum tasks to MAXTASKS (%d)\n", MAXTASKS); fprintf(stderr, "[WARNING] reducing maximum tasks to MAXTASKS (%d)\n", MAXTASKS);
hydra_options.max_use = MAXTASKS; hydra_options.max_use = MAXTASKS;
} }
// script kiddie patch // script kiddie patch
if (hydra_options.server != NULL && (hydra_strcasestr(hydra_options.server, "gmail.") != NULL || hydra_strcasestr(hydra_options.server, "googlemail.") != NULL)) if (hydra_options.server != NULL && (hydra_strcasestr(hydra_options.server, "gmail.") != NULL || hydra_strcasestr(hydra_options.server, "googlemail.") != NULL))
fprintf(stderr, "[WARNING] Google Mail has bruteforce detection and sends false positives. You are not doing anything illegal right?!\n"); fprintf(stderr, "[WARNING] Google Mail has bruteforce detection and sends false positives. You are not doing anything illegal right?!\n");
@ -3594,7 +3608,8 @@ int main(int argc, char *argv[]) {
tmp_time = time(NULL); tmp_time = time(NULL);
for (head_no = 0; head_no < hydra_options.max_use; head_no++) { for (head_no = 0; head_no < hydra_options.max_use; head_no++) {
if (debug && hydra_heads[head_no]->active != -1) printf("[DEBUG] head_no[%d] to target_no %d active %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->active); if (debug && hydra_heads[head_no]->active != -1)
printf("[DEBUG] head_no[%d] to target_no %d active %d\n", head_no, hydra_heads[head_no]->target_no, hydra_heads[head_no]->active);
switch (hydra_heads[head_no]->active) { switch (hydra_heads[head_no]->active) {
case -1: case -1:
// disabled head, ignored // disabled head, ignored
@ -3610,7 +3625,8 @@ int main(int argc, char *argv[]) {
if (debug) if (debug)
printf("[DEBUG] child %d got target %d selected\n", head_no, hydra_heads[head_no]->target_no); printf("[DEBUG] child %d got target %d selected\n", head_no, hydra_heads[head_no]->target_no);
if (hydra_heads[head_no]->target_no < 0) { if (hydra_heads[head_no]->target_no < 0) {
if (debug) printf("[DEBUG] hydra_select_target() reports no more targets left\n"); if (debug)
printf("[DEBUG] hydra_select_target() reports no more targets left\n");
hydra_kill_head(head_no, 0, 3); hydra_kill_head(head_no, 0, 3);
} else } else
hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); // target_no is ignored if head->redo == 1 hydra_spawn_head(head_no, hydra_heads[head_no]->target_no); // target_no is ignored if head->redo == 1
@ -3650,34 +3666,47 @@ int main(int argc, char *argv[]) {
if (colored_output) { if (colored_output) {
if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) {
if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0)
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target);
else else
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port,
hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr);
} else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) {
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port,
hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr);
} else } else
printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); printf("[\e[1;32m%d\e[0m][\e[1;32m%s\e[0m] host: \e[1;32m%s\e[0m login: \e[1;32m%s\e[0m password: \e[1;32m%s\e[0m\n",
hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target,
hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr);
} else { } else {
if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) {
if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0)
printf("[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target); printf("[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target);
else else
printf("[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr); printf("[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr);
} else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) {
printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); printf("[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr);
} else } else
printf("[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); printf("[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr);
} }
if (hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) { if (hydra_options.outfile_ptr != NULL && hydra_brains.ofp != NULL) {
if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) { if (hydra_heads[head_no]->current_login_ptr == NULL || strlen(hydra_heads[head_no]->current_login_ptr) == 0) {
if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0)
fprintf(hydra_brains.ofp, "[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target); fprintf(hydra_brains.ofp, "[%d][%s] host: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target);
else else
fprintf(hydra_brains.ofp, "[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr); fprintf(hydra_brains.ofp, "[%d][%s] host: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_pass_ptr);
} else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) { } else if (hydra_heads[head_no]->current_pass_ptr == NULL || strlen(hydra_heads[head_no]->current_pass_ptr) == 0) {
fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr); fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr);
} else } else
fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service, hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr); fprintf(hydra_brains.ofp, "[%d][%s] host: %s login: %s password: %s\n", hydra_targets[hydra_heads[head_no]->target_no]->port, hydra_options.service,
hydra_targets[hydra_heads[head_no]->target_no]->target, hydra_heads[head_no]->current_login_ptr, hydra_heads[head_no]->current_pass_ptr);
} }
if (hydra_options.exit_found) { // option set says quit target after on valid login/pass pair is found if (hydra_options.exit_found) { // option set says quit target after on valid login/pass pair is found
if (hydra_targets[hydra_heads[head_no]->target_no]->done == 0) { if (hydra_targets[hydra_heads[head_no]->target_no]->done == 0) {
@ -3836,7 +3865,8 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "[ERROR] illegal target result value (%d=>%d)\n", i, hydra_targets[i]->done); fprintf(stderr, "[ERROR] illegal target result value (%d=>%d)\n", i, hydra_targets[i]->done);
} }
if (debug) printf("[DEBUG] killing all remaining childs now that might be stuck\n"); if (debug)
printf("[DEBUG] killing all remaining childs now that might be stuck\n");
for (i = 0; i < hydra_options.max_use; i++) for (i = 0; i < hydra_options.max_use; i++)
if (hydra_heads[i]->active > 0 && hydra_heads[i]->pid > 0) if (hydra_heads[i]->active > 0 && hydra_heads[i]->pid > 0)
hydra_kill_head(i, 1, 3); hydra_kill_head(i, 1, 3);

35
sasl.c
View file

@ -1,4 +1,5 @@
#include "sasl.h" #include "sasl.h"
/* /*
print_hex is used for debug print_hex is used for debug
it displays the string buf hexa values of size len it displays the string buf hexa values of size len
@ -6,6 +7,7 @@ it displays the string buf hexa values of size len
int print_hex(unsigned char *buf, int len) { int print_hex(unsigned char *buf, int len) {
int i; int i;
int n; int n;
for (i = 0, n = 0; i < len; i++) { for (i = 0, n = 0; i < len; i++) {
if (n > 7) { if (n > 7) {
printf("\n"); printf("\n");
@ -17,6 +19,7 @@ n++;
printf("\n"); printf("\n");
return (0); return (0);
} }
/* /*
RFC 4013: SASLprep: Stringprep Profile for User Names and Passwords RFC 4013: SASLprep: Stringprep Profile for User Names and Passwords
code based on gsasl_saslprep from GSASL project code based on gsasl_saslprep from GSASL project
@ -24,6 +27,7 @@ code based on gsasl_saslprep from GSASL project
int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) { int sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out) {
#if LIBIDN #if LIBIDN
int rc; int rc;
rc = stringprep_profile(in, out, "SASLprep", (flags & SASL_ALLOW_UNASSIGNED) ? STRINGPREP_NO_UNASSIGNED : 0); rc = stringprep_profile(in, out, "SASLprep", (flags & SASL_ALLOW_UNASSIGNED) ? STRINGPREP_NO_UNASSIGNED : 0);
if (rc != STRINGPREP_OK) { if (rc != STRINGPREP_OK) {
*out = NULL; *out = NULL;
@ -38,6 +42,7 @@ return -1;
#endif #endif
#else #else
size_t i, inlen = strlen(in); size_t i, inlen = strlen(in);
for (i = 0; i < inlen; i++) { for (i = 0; i < inlen; i++) {
if (in[i] & 0x80) { if (in[i] & 0x80) {
*out = NULL; *out = NULL;
@ -54,6 +59,7 @@ strcpy(*out, in);
#endif #endif
return 0; return 0;
} }
/* /*
RFC 4616: The PLAIN Simple Authentication and Security Layer (SASL) Mechanism RFC 4616: The PLAIN Simple Authentication and Security Layer (SASL) Mechanism
sasl_plain computes the plain authentication from strings login and password sasl_plain computes the plain authentication from strings login and password
@ -64,6 +70,7 @@ void sasl_plain(char *result, char *login, char *pass) {
char *preplogin; char *preplogin;
char *preppasswd; char *preppasswd;
int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin); int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return;
@ -83,7 +90,9 @@ hydra_tobase64((unsigned char *) result, strlen(preplogin) * 2 + strlen(preppass
free(preplogin); free(preplogin);
free(preppasswd); free(preppasswd);
} }
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
/* /*
RFC 2195: IMAP/POP AUTHorize Extension for Simple Challenge/Response RFC 2195: IMAP/POP AUTHorize Extension for Simple Challenge/Response
sasl_cram_md5 computes the cram-md5 authentication from password string sasl_cram_md5 computes the cram-md5 authentication from password string
@ -98,6 +107,7 @@ unsigned char md5_raw[MD5_DIGEST_LENGTH];
MD5_CTX md5c; MD5_CTX md5c;
int i, rc; int i, rc;
char *preppasswd; char *preppasswd;
if (challenge == NULL) { if (challenge == NULL) {
result = NULL; result = NULL;
return; return;
@ -137,6 +147,7 @@ result += 2;
} }
free(preppasswd); free(preppasswd);
} }
/* /*
sasl_cram_sha1 computes the cram-sha1 authentication from password string sasl_cram_sha1 computes the cram-sha1 authentication from password string
and the challenge sent by the server, and stored the value in variable and the challenge sent by the server, and stored the value in variable
@ -150,6 +161,7 @@ unsigned char sha1_raw[SHA_DIGEST_LENGTH];
SHA_CTX shac; SHA_CTX shac;
int i, rc; int i, rc;
char *preppasswd; char *preppasswd;
if (challenge == NULL) { if (challenge == NULL) {
result = NULL; result = NULL;
return; return;
@ -189,6 +201,7 @@ result += 2;
} }
free(preppasswd); free(preppasswd);
} }
/* /*
sasl_cram_sha256 computes the cram-sha256 authentication from password string sasl_cram_sha256 computes the cram-sha256 authentication from password string
and the challenge sent by the server, and stored the value in variable and the challenge sent by the server, and stored the value in variable
@ -202,6 +215,7 @@ unsigned char sha256_raw[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256c; SHA256_CTX sha256c;
int i, rc; int i, rc;
char *preppasswd; char *preppasswd;
if (challenge == NULL) { if (challenge == NULL) {
result = NULL; result = NULL;
return; return;
@ -241,6 +255,7 @@ result += 2;
} }
free(preppasswd); free(preppasswd);
} }
/* /*
RFC 2831: Using Digest Authentication as a SASL Mechanism RFC 2831: Using Digest Authentication as a SASL Mechanism
the parameter result must be able to hold at least 500 bytes!! the parameter result must be able to hold at least 500 bytes!!
@ -256,6 +271,7 @@ MD5_CTX md5c;
char *preplogin; char *preplogin;
char *preppasswd; char *preppasswd;
int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin); int rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
memset(realm, 0, sizeof(realm)); memset(realm, 0, sizeof(realm));
if (rc) { if (rc) {
result = NULL; result = NULL;
@ -302,6 +318,7 @@ for (i = 0; i < ind; i++) {
//removing space chars between comma separated value if any //removing space chars between comma separated value if any
while ((array[i] != NULL) && (array[i][0] == ' ')) { while ((array[i] != NULL) && (array[i][0] == ' ')) {
char *tmp = strdup(array[i]); char *tmp = strdup(array[i]);
memset(array[i], 0, sizeof(array[i])); memset(array[i], 0, sizeof(array[i]));
strcpy(array[i], tmp + 1); strcpy(array[i], tmp + 1);
free(tmp); free(tmp);
@ -311,11 +328,13 @@ if (strstr(array[i], "nonce=") != NULL) {
if (strstr(array[i], "\"") != NULL) { if (strstr(array[i], "\"") != NULL) {
//assume last char is also a double-quote //assume last char is also a double-quote
int nonce_string_len = strlen(array[i]) - strlen("nonce=\"") - 1; int nonce_string_len = strlen(array[i]) - strlen("nonce=\"") - 1;
if ((nonce_string_len > 0) && (nonce_string_len <= sizeof(nonce) - 1)) { if ((nonce_string_len > 0) && (nonce_string_len <= sizeof(nonce) - 1)) {
strncpy(nonce, strstr(array[i], "nonce=") + strlen("nonce=") + 1, nonce_string_len); strncpy(nonce, strstr(array[i], "nonce=") + strlen("nonce=") + 1, nonce_string_len);
nonce[nonce_string_len] = '\0'; nonce[nonce_string_len] = '\0';
} else { } else {
int j; int j;
for (j = 0; j < ind; j++) for (j = 0; j < ind; j++)
if (array[j] != NULL) if (array[j] != NULL)
free(array[j]); free(array[j]);
@ -332,11 +351,13 @@ if (strstr(array[i], "realm=") != NULL) {
if (strstr(array[i], "\"") != NULL) { if (strstr(array[i], "\"") != NULL) {
//assume last char is also a double-quote //assume last char is also a double-quote
int realm_string_len = strlen(array[i]) - strlen("realm=\"") - 1; int realm_string_len = strlen(array[i]) - strlen("realm=\"") - 1;
if ((realm_string_len > 0) && (realm_string_len <= sizeof(realm) - 1)) { if ((realm_string_len > 0) && (realm_string_len <= sizeof(realm) - 1)) {
strncpy(realm, strstr(array[i], "realm=") + strlen("realm=") + 1, realm_string_len); strncpy(realm, strstr(array[i], "realm=") + strlen("realm=") + 1, realm_string_len);
realm[realm_string_len] = '\0'; realm[realm_string_len] = '\0';
} else { } else {
int i; int i;
for (i = 0; i < ind; i++) for (i = 0; i < ind; i++)
if (array[i] != NULL) if (array[i] != NULL)
free(array[i]); free(array[i]);
@ -350,6 +371,7 @@ realm[sizeof(realm) - 1] = '\0';
} }
} }
if (strstr(array[i], "qop=") != NULL) { if (strstr(array[i], "qop=") != NULL) {
/* /*
The value "auth" indicates authentication; the value "auth-int" indicates The value "auth" indicates authentication; the value "auth-int" indicates
authentication with integrity protection; the value "auth-conf" authentication with integrity protection; the value "auth-conf"
@ -358,6 +380,7 @@ indicates authentication with integrity protection and encryption.
auth_find = 1; auth_find = 1;
if ((strstr(array[i], "\"auth\"") == NULL) && (strstr(array[i], "\"auth,") == NULL) && (strstr(array[i], ",auth\"") == NULL)) { if ((strstr(array[i], "\"auth\"") == NULL) && (strstr(array[i], "\"auth,") == NULL) && (strstr(array[i], ",auth\"") == NULL)) {
int j; int j;
for (j = 0; j < ind; j++) for (j = 0; j < ind; j++)
if (array[j] != NULL) if (array[j] != NULL)
free(array[j]); free(array[j]);
@ -370,11 +393,13 @@ if (strstr(array[i], "algorithm=") != NULL) {
if (strstr(array[i], "\"") != NULL) { if (strstr(array[i], "\"") != NULL) {
//assume last char is also a double-quote //assume last char is also a double-quote
int algo_string_len = strlen(array[i]) - strlen("algorithm=\"") - 1; int algo_string_len = strlen(array[i]) - strlen("algorithm=\"") - 1;
if ((algo_string_len > 0) && (algo_string_len <= sizeof(algo) - 1)) { if ((algo_string_len > 0) && (algo_string_len <= sizeof(algo) - 1)) {
strncpy(algo, strstr(array[i], "algorithm=") + strlen("algorithm=") + 1, algo_string_len); strncpy(algo, strstr(array[i], "algorithm=") + strlen("algorithm=") + 1, algo_string_len);
algo[algo_string_len] = '\0'; algo[algo_string_len] = '\0';
} else { } else {
int j; int j;
for (j = 0; j < ind; j++) for (j = 0; j < ind; j++)
if (array[j] != NULL) if (array[j] != NULL)
free(array[j]); free(array[j]);
@ -388,6 +413,7 @@ algo[sizeof(algo) - 1] = '\0';
} }
if ((strstr(algo, "MD5") == NULL) && (strstr(algo, "md5") == NULL)) { if ((strstr(algo, "MD5") == NULL) && (strstr(algo, "md5") == NULL)) {
int j; int j;
for (j = 0; j < ind; j++) for (j = 0; j < ind; j++)
if (array[j] != NULL) if (array[j] != NULL)
free(array[j]); free(array[j]);
@ -416,6 +442,7 @@ MD5_Final(response, &md5c);
//for MD5-sess //for MD5-sess
if (strstr(algo, "5-sess") != NULL) { if (strstr(algo, "5-sess") != NULL) {
buffer[0] = 0; //memset(buffer, 0, sizeof(buffer)); => buffer is char*! buffer[0] = 0; //memset(buffer, 0, sizeof(buffer)); => buffer is char*!
/* per RFC 2617 Errata ID 1649 */ /* per RFC 2617 Errata ID 1649 */
if ((strstr(type, "proxy") != NULL) || (strstr(type, "GET") != NULL) || (strstr(type, "HEAD") != NULL)) { if ((strstr(type, "proxy") != NULL) || (strstr(type, "GET") != NULL) || (strstr(type, "HEAD") != NULL)) {
memset(buffer3, 0, sizeof(buffer3)); memset(buffer3, 0, sizeof(buffer3));
@ -520,6 +547,7 @@ type, miscptr, webtarget, preplogin, realm, buffer, nonce, algo, miscptr, header
free(preplogin); free(preplogin);
free(preppasswd); free(preppasswd);
} }
/* /*
RFC 5802: Salted Challenge Response Authentication Mechanism RFC 5802: Salted Challenge Response Authentication Mechanism
Note: SCRAM is a client-first SASL mechanism Note: SCRAM is a client-first SASL mechanism
@ -543,10 +571,12 @@ char ClientProof[SHA_DIGEST_LENGTH];
unsigned char clientproof_b64[50]; unsigned char clientproof_b64[50];
char *preppasswd; char *preppasswd;
int rc = sasl_saslprep(pass, 0, &preppasswd); int rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return;
} }
/*client-final-message */ /*client-final-message */
if (debug) if (debug)
hydra_report(stderr, "DEBUG S: %s\n", serverfirstmessage); hydra_report(stderr, "DEBUG S: %s\n", serverfirstmessage);
@ -587,6 +617,7 @@ free(preppasswd);
result = NULL; result = NULL;
return; return;
} }
/* SaltedPassword := Hi(Normalize(password), salt, i) */ /* SaltedPassword := Hi(Normalize(password), salt, i) */
saltlen = from64tobits((char *) salt, buffer); saltlen = from64tobits((char *) salt, buffer);
if (PKCS5_PBKDF2_HMAC_SHA1(preppasswd, strlen(preppasswd), (unsigned char *) salt, saltlen, iter, SHA_DIGEST_LENGTH, SaltedPassword) != 1) { if (PKCS5_PBKDF2_HMAC_SHA1(preppasswd, strlen(preppasswd), (unsigned char *) salt, saltlen, iter, SHA_DIGEST_LENGTH, SaltedPassword) != 1) {
@ -595,14 +626,18 @@ free(preppasswd);
result = NULL; result = NULL;
return; return;
} }
/* ClientKey := HMAC(SaltedPassword, "Client Key") */ /* ClientKey := HMAC(SaltedPassword, "Client Key") */
#define CLIENT_KEY "Client Key" #define CLIENT_KEY "Client Key"
HMAC(EVP_sha1(), SaltedPassword, SHA_DIGEST_LENGTH, (const unsigned char *) CLIENT_KEY, strlen(CLIENT_KEY), ClientKey, &resultlen); HMAC(EVP_sha1(), SaltedPassword, SHA_DIGEST_LENGTH, (const unsigned char *) CLIENT_KEY, strlen(CLIENT_KEY), ClientKey, &resultlen);
/* StoredKey := H(ClientKey) */ /* StoredKey := H(ClientKey) */
SHA1((const unsigned char *) ClientKey, SHA_DIGEST_LENGTH, StoredKey); SHA1((const unsigned char *) ClientKey, SHA_DIGEST_LENGTH, StoredKey);
/* ClientSignature := HMAC(StoredKey, AuthMessage) */ /* ClientSignature := HMAC(StoredKey, AuthMessage) */
snprintf(AuthMessage, 500, "%s,%s,%s", clientfirstmessagebare, serverfirstmessage, clientfinalmessagewithoutproof); snprintf(AuthMessage, 500, "%s,%s,%s", clientfirstmessagebare, serverfirstmessage, clientfinalmessagewithoutproof);
HMAC(EVP_sha1(), StoredKey, SHA_DIGEST_LENGTH, (const unsigned char *) AuthMessage, strlen(AuthMessage), ClientSignature, &resultlen); HMAC(EVP_sha1(), StoredKey, SHA_DIGEST_LENGTH, (const unsigned char *) AuthMessage, strlen(AuthMessage), ClientSignature, &resultlen);
/* ClientProof := ClientKey XOR ClientSignature */ /* ClientProof := ClientKey XOR ClientSignature */
xor(ClientProof, (char *) ClientKey, (char *) ClientSignature, 20); xor(ClientProof, (char *) ClientKey, (char *) ClientSignature, 20);
to64frombits(clientproof_b64, (const unsigned char *) ClientProof, 20); to64frombits(clientproof_b64, (const unsigned char *) ClientProof, 20);