mirror of
https://github.com/vanhauser-thc/thc-hydra.git
synced 2025-03-12 04:36:23 -07:00
739 lines
23 KiB
C
739 lines
23 KiB
C
|
|
/*
|
|
* This file handles all that needs to be done...
|
|
* Some stuff is stolen from gcombust since I never used pipes... ok, i
|
|
* only used them in reallife :)
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "callbacks.h"
|
|
#include "interface.h"
|
|
#include "support.h"
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
int hydra_pid = 0;
|
|
|
|
char port[10];
|
|
char tasks[10];
|
|
char timeout[10];
|
|
char smbparm[128];
|
|
char sapr3id[4];
|
|
char passLoginNull[4];
|
|
|
|
#define BUF_S 1024
|
|
|
|
void hydra_select_file(GtkEntry *widget, char *text) {
|
|
#ifdef GTK_TYPE_FILE_CHOOSER
|
|
GtkWidget *dialog;
|
|
char *filename;
|
|
|
|
dialog = gtk_file_chooser_dialog_new(text, (GtkWindow *)wndMain, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
|
|
|
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
|
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
|
gtk_entry_set_text(widget, filename);
|
|
g_free(filename);
|
|
}
|
|
gtk_widget_destroy(dialog);
|
|
#endif
|
|
}
|
|
|
|
int hydra_get_options(char *options[]) {
|
|
/* get the stuff from the gtk entries... */
|
|
int i = 1;
|
|
GtkWidget *widget;
|
|
GtkWidget *widget2;
|
|
int j;
|
|
gchar *tmp;
|
|
GString *a;
|
|
|
|
options[0] = HYDRA_BIN;
|
|
|
|
/* get the port */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "spnPort");
|
|
j = gtk_spin_button_get_value_as_int((GtkSpinButton *)widget);
|
|
if (j != 0) {
|
|
snprintf(port, 10, "%d", j);
|
|
options[i++] = "-s";
|
|
options[i++] = port;
|
|
}
|
|
|
|
/* prefer ipv6 */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkIPV6");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-6";
|
|
}
|
|
|
|
/* use SSL? */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkSSL");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-S";
|
|
}
|
|
|
|
/* use old SSL? */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkOldSSL");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-O";
|
|
}
|
|
|
|
/* be verbose? */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkVerbose");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-v";
|
|
}
|
|
|
|
/* show attempts */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkAttempts");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-V";
|
|
}
|
|
|
|
/* debug mode? */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkDebug");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-d";
|
|
}
|
|
|
|
/* COMPLETE HELP */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkCompleteHelp");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-h";
|
|
}
|
|
|
|
/* Service Module Usage Details */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkServiceDetails");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-U";
|
|
}
|
|
|
|
/* use colon separated list? */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkColon");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-C";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entColonFile");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else {
|
|
/* disable usernames */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkDisUser");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
} else {
|
|
/* get the username, or username list */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "radioUsername1");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-l";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entUsername");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
} else {
|
|
options[i++] = "-L";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entUsernameFile");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
}
|
|
}
|
|
|
|
/* get the pass, pass list, or generate */
|
|
/* The "generate" button was implemented by Petar Kaleychev <petar.kaleychev@gmail.com> */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "radioPass1");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-p";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entPass");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
}
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "radioPass2");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-P";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entPassFile");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
}
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "radioGenerate");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-x";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entGeneration");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
}
|
|
}
|
|
|
|
/* empty passes / login as pass / reversed login? */
|
|
memset(passLoginNull, 0, 4);
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkPassNull");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
passLoginNull[0] = 'n';
|
|
}
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkPassLogin");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
if (passLoginNull[0] == 0) {
|
|
passLoginNull[0] = 's';
|
|
} else {
|
|
passLoginNull[1] = 's';
|
|
}
|
|
}
|
|
/* The "Try reversed login" button was implemented by Petar Kaleychev <petar.kaleychev@gmail.com> */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkPassReverse");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
if (passLoginNull[0] == 0) {
|
|
passLoginNull[0] = 'r';
|
|
} else if (passLoginNull[1] == 0) {
|
|
passLoginNull[1] = 'r';
|
|
} else {
|
|
passLoginNull[2] = 'r';
|
|
}
|
|
}
|
|
if (passLoginNull[0] != 0) {
|
|
options[i++] = "-e";
|
|
options[i++] = passLoginNull;
|
|
}
|
|
|
|
/* #of tasks */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "spnTasks");
|
|
j = gtk_spin_button_get_value_as_int((GtkSpinButton *)widget);
|
|
if (j != 40) {
|
|
snprintf(tasks, 10, "%d", j);
|
|
options[i++] = "-t";
|
|
options[i++] = tasks;
|
|
}
|
|
|
|
/* timeout */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "spnTimeout");
|
|
j = gtk_spin_button_get_value_as_int((GtkSpinButton *)widget);
|
|
if (j != 30) {
|
|
snprintf(timeout, 10, "%d", j);
|
|
options[i++] = "-w";
|
|
options[i++] = timeout;
|
|
}
|
|
|
|
/* loop around users? */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkUsernameLoop");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-u";
|
|
}
|
|
|
|
/* exit after first found pair? */
|
|
/* per host */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkExitf");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-f";
|
|
}
|
|
/* global */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkExitF");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-F";
|
|
}
|
|
|
|
/* Do not print messages about connection errors */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkNoErr");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
options[i++] = "-q";
|
|
}
|
|
|
|
/* get additional parameters */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entProtocol");
|
|
tmp = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
if (!strncmp(tmp, "http-proxy", 10)) {
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entHTTPProxyURL");
|
|
options[i++] = "-m";
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else if (!strncmp(tmp, "http-", 5) || !strncmp(tmp, "https-", 6)) {
|
|
options[i++] = "-m";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entHTTPURL");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else if (!strcmp(tmp, "cisco-enable")) {
|
|
options[i++] = "-m";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entCiscoPass");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else if (!strcmp(tmp, "ldap3-crammd5")) {
|
|
options[i++] = "-m";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entLDAPDN");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else if (!strcmp(tmp, "ldap3-digestmd5")) {
|
|
options[i++] = "-m";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entLDAPDN");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else if (!strcmp(tmp, "smb")) {
|
|
memset(smbparm, 0, sizeof(smbparm));
|
|
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkDomain");
|
|
widget2 = lookup_widget(GTK_WIDGET(wndMain), "chkLocal");
|
|
options[i++] = "-m";
|
|
strncpy(smbparm, "Both", sizeof(smbparm));
|
|
smbparm[strlen("Both")] = '\0';
|
|
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
strncpy(smbparm, "Domain", sizeof(smbparm));
|
|
smbparm[strlen("Domain")] = '\0';
|
|
}
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget2)) {
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
strncpy(smbparm, "Both", sizeof(smbparm));
|
|
smbparm[strlen("Both")] = '\0';
|
|
} else {
|
|
strncpy(smbparm, "Local", sizeof(smbparm));
|
|
smbparm[strlen("Local")] = '\0';
|
|
}
|
|
}
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkNTLM");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
strcat(smbparm, "Hash");
|
|
}
|
|
options[i++] = smbparm;
|
|
} else if (!strcmp(tmp, "smb2")) {
|
|
memset(smbparm, 0, sizeof(smbparm));
|
|
|
|
options[i++] = "-m";
|
|
options[i++] = smbparm;
|
|
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkNTLM");
|
|
int pth = gtk_toggle_button_get_active((GtkToggleButton *)widget);
|
|
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entSMB2Workgroup");
|
|
|
|
snprintf(smbparm, sizeof(smbparm) - 1, "nthash:%s workgroup:{%s}", pth ? "true" : "false", (char *)gtk_entry_get_text((GtkEntry *)widget));
|
|
} else if (!strcmp(tmp, "sapr3")) {
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "spnSAPR3");
|
|
j = gtk_spin_button_get_value_as_int((GtkSpinButton *)widget);
|
|
snprintf(sapr3id, sizeof(sapr3id), "%d", j);
|
|
options[i++] = "-m";
|
|
options[i++] = sapr3id;
|
|
|
|
} else if (!strcmp(tmp, "cvs") || !strcmp(tmp, "svn")) {
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entCVS");
|
|
options[i++] = "-m";
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else if (!strcmp(tmp, "snmp")) {
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entSNMP");
|
|
options[i++] = "-m";
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
} else if (!strcmp(tmp, "telnet")) {
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entTelnet");
|
|
if ((char *)gtk_entry_get_text((GtkEntry *)widget) != NULL) {
|
|
options[i++] = "-m";
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
}
|
|
}
|
|
|
|
/* clean up proxy settings */
|
|
unsetenv("HYDRA_PROXY_HTTP");
|
|
unsetenv("HYDRA_PROXY_CONNECT");
|
|
unsetenv("HYDRA_PROXY_AUTH");
|
|
|
|
/* proxy support */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "radioProxy");
|
|
|
|
if (!gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
widget2 = lookup_widget(GTK_WIDGET(wndMain), "entHTTPProxy");
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "radioProxy2");
|
|
|
|
/* which variable do we set? */
|
|
if ((!strncmp(tmp, "http-", 5)) && (gtk_toggle_button_get_active((GtkToggleButton *)widget))) {
|
|
setenv("HYDRA_PROXY_HTTP", gtk_entry_get_text((GtkEntry *)widget2), 1);
|
|
} else {
|
|
setenv("HYDRA_PROXY_CONNECT", (char *)gtk_entry_get_text((GtkEntry *)widget2), 1);
|
|
}
|
|
|
|
/* do we need to provide user and pass? */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "chkProxyAuth");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entProxyUser");
|
|
widget2 = lookup_widget(GTK_WIDGET(wndMain), "entProxyPass");
|
|
a = g_string_new((gchar *)gtk_entry_get_text((GtkEntry *)widget));
|
|
a = g_string_append_c(a, ':');
|
|
a = g_string_append(a, gtk_entry_get_text((GtkEntry *)widget2));
|
|
setenv("HYDRA_PROXY_AUTH", a->str, 1);
|
|
(void)g_string_free(a, TRUE);
|
|
}
|
|
}
|
|
|
|
/* get the target, or target list */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "radioTarget1");
|
|
if (gtk_toggle_button_get_active((GtkToggleButton *)widget)) {
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entTarget");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
} else {
|
|
options[i++] = "-M";
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entTargetFile");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
}
|
|
|
|
/* get the service */
|
|
widget = lookup_widget(GTK_WIDGET(wndMain), "entProtocol");
|
|
options[i++] = (char *)gtk_entry_get_text((GtkEntry *)widget);
|
|
|
|
options[i] = NULL;
|
|
return i;
|
|
}
|
|
|
|
int update_statusbar() {
|
|
int i, j;
|
|
char *options[128];
|
|
guint context_id;
|
|
GtkStatusbar *statusbar;
|
|
extern guint message_id;
|
|
GString *statustext = g_string_new("hydra ");
|
|
|
|
i = hydra_get_options(options);
|
|
|
|
for (j = 1; j < i; j++) {
|
|
statustext = g_string_append(statustext, options[j]);
|
|
statustext = g_string_append_c(statustext, ' ');
|
|
}
|
|
|
|
statusbar = (GtkStatusbar *)lookup_widget(GTK_WIDGET(wndMain), "statusbar");
|
|
context_id = gtk_statusbar_get_context_id(statusbar, "status");
|
|
|
|
/* an old message in stack? */
|
|
if (message_id != 0) {
|
|
gtk_statusbar_remove(statusbar, context_id, message_id);
|
|
}
|
|
|
|
message_id = gtk_statusbar_push(statusbar, context_id, (gchar *)statustext->str);
|
|
|
|
(void)g_string_free(statustext, TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int read_into(int fd) {
|
|
char in_buf[BUF_S];
|
|
char *passline;
|
|
char *start, *end;
|
|
int result;
|
|
GtkWidget *output;
|
|
GtkTextBuffer *outputbuf;
|
|
GtkTextIter outputiter;
|
|
|
|
if ((result = read(fd, in_buf, BUF_S - 1)) < 0) {
|
|
g_warning("%s::%i: read returned negative!", __FILE__, __LINE__);
|
|
return FALSE;
|
|
} else if (result == 0) {
|
|
return FALSE;
|
|
} else {
|
|
in_buf[result] = 0;
|
|
}
|
|
|
|
output = lookup_widget(GTK_WIDGET(wndMain), "txtOutput");
|
|
outputbuf = gtk_text_view_get_buffer((GtkTextView *)output);
|
|
|
|
gtk_text_buffer_get_iter_at_offset(outputbuf, &outputiter, -1);
|
|
|
|
if ((passline = strstr(in_buf, "password: ")) == NULL) {
|
|
gtk_text_buffer_insert(outputbuf, &outputiter, in_buf, result);
|
|
} else {
|
|
start = in_buf;
|
|
end = in_buf;
|
|
while ((end = (strchr(end + 1, '\n'))) < passline) {
|
|
start = end;
|
|
}
|
|
|
|
if (start != in_buf) {
|
|
gtk_text_buffer_insert(outputbuf, &outputiter, in_buf, (start - in_buf + 1));
|
|
}
|
|
gtk_text_buffer_insert_with_tags_by_name(outputbuf, &outputiter, start, (end - start + 1), "bold", NULL);
|
|
|
|
if (end - in_buf - result > 0) {
|
|
gtk_text_buffer_insert(outputbuf, &outputiter, end + 1, -1);
|
|
}
|
|
}
|
|
|
|
if (strstr(in_buf, " finished at ") != NULL) {
|
|
gtk_text_buffer_insert_with_tags_by_name(outputbuf, &outputiter, "<finished>\n\n", -1, "bold", NULL);
|
|
}
|
|
|
|
if (result == BUF_S - 1) /* there might be more available, recurse baby! */
|
|
return read_into(fd);
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
/* wait for hydra output */
|
|
|
|
static int wait_hydra_output(gpointer data) {
|
|
static int stdout_ok = TRUE, stderr_ok = TRUE;
|
|
fd_set rset;
|
|
struct timeval tv;
|
|
int result, max;
|
|
int *fd = data;
|
|
int status;
|
|
|
|
g_assert((stdout_ok == TRUE) || (stderr_ok == TRUE));
|
|
|
|
tv.tv_sec = 0;
|
|
tv.tv_usec = 0;
|
|
|
|
FD_ZERO(&rset);
|
|
max = -1;
|
|
|
|
if (stdout_ok) {
|
|
FD_SET(fd[0], &rset);
|
|
max = fd[0];
|
|
}
|
|
if (stderr_ok) {
|
|
FD_SET(fd[1], &rset);
|
|
if (-1 == max)
|
|
max = fd[1];
|
|
else
|
|
max = fd[0] > fd[1] ? fd[0] : fd[1];
|
|
}
|
|
|
|
result = select(max + 1, &rset, NULL, NULL, &tv);
|
|
|
|
if (result < 0)
|
|
g_error("wait_hydra_output: select returned negative!");
|
|
else if (result == 0)
|
|
return TRUE;
|
|
|
|
if (stdout_ok && FD_ISSET(fd[0], &rset))
|
|
stdout_ok = read_into(fd[0]);
|
|
if (stderr_ok && FD_ISSET(fd[1], &rset))
|
|
stderr_ok = read_into(fd[1]);
|
|
|
|
if (!(stdout_ok || stderr_ok)) {
|
|
waitpid(hydra_pid, &status, 0);
|
|
hydra_pid = 0;
|
|
stdout_ok = stderr_ok = TRUE;
|
|
return FALSE;
|
|
} else
|
|
return TRUE;
|
|
}
|
|
|
|
/* assumes a successfull pipe() won't set the fd's to -1 */
|
|
static void close_pipe(int *pipe) {
|
|
if (-1 != pipe[0]) {
|
|
close(pipe[0]);
|
|
pipe[0] = -1;
|
|
}
|
|
if (-1 != pipe[1]) {
|
|
close(pipe[1]);
|
|
pipe[1] = -1;
|
|
}
|
|
}
|
|
|
|
/* executes the command stored in command->elemets (which is suitable for execv())
|
|
* returns an int *pfd with file descriptors:
|
|
* pfd[0] STDOUT output of the command and
|
|
* pfd[1] STDERR output of the command
|
|
*/
|
|
|
|
int *popen_re_unbuffered(char *command) {
|
|
static int p_r[2] = {-1, -1}, p_e[2] = {-1, -1};
|
|
static int *pfd = NULL;
|
|
|
|
char *options[128];
|
|
|
|
hydra_pid = 0;
|
|
|
|
update_statusbar();
|
|
|
|
/* only allocate once */
|
|
if (NULL == pfd)
|
|
pfd = malloc(sizeof(int) * 2);
|
|
|
|
/* clean up from last command */
|
|
close_pipe(p_r);
|
|
close_pipe(p_e);
|
|
|
|
if (pipe(p_r) < 0 || pipe(p_e) < 0) {
|
|
g_warning("popen_rw_unbuffered: Error creating pipe!");
|
|
return NULL;
|
|
}
|
|
|
|
if ((hydra_pid = fork()) < 0) {
|
|
g_warning("popen_rw_unbuffered: Error forking!");
|
|
return NULL;
|
|
} else if (hydra_pid == 0) { /* child */
|
|
int k;
|
|
|
|
if (setpgid(getpid(), getpid()) < 0)
|
|
g_warning("popen_rw_unbuffered: setpgid() failed");
|
|
if (close(p_r[0]) < 0)
|
|
g_warning("popen_rw_unbuffered: close(p_r[0]) failed");
|
|
if (p_r[1] != STDOUT_FILENO)
|
|
if (dup2(p_r[1], STDOUT_FILENO) < 0)
|
|
g_warning("popen_rw_unbuffered: child dup2 STDOUT failed!");
|
|
if (close(p_r[1]) < 0)
|
|
g_warning("popen_rw_unbuffered: close(p_r[1]) failed");
|
|
|
|
if (close(p_e[0]) < 0)
|
|
g_warning("popen_rw_unbuffered: close(p_e[0]) failed");
|
|
if (p_e[1] != STDERR_FILENO)
|
|
if (dup2(p_e[1], STDERR_FILENO) < 0)
|
|
g_warning("popen_rw_unbuffered: child dup2 STDERR failed!");
|
|
if (close(p_e[1]) < 0)
|
|
g_warning("popen_rw_unbuffered: close(p_e[1]) failed");
|
|
|
|
(void)hydra_get_options(options);
|
|
|
|
execv(HYDRA_BIN, options);
|
|
|
|
g_warning("%s %i: popen_rw_unbuffered: execv() returned", __FILE__, __LINE__);
|
|
|
|
for (k = 0; options[k] != NULL; k++) {
|
|
g_warning("%s", options[k]);
|
|
}
|
|
gtk_main_quit();
|
|
} else { /* parent */
|
|
if (close(p_r[1]) < 0)
|
|
g_warning("popen_rw_unbuffered: close(p_r[1]) (parent) failed");
|
|
if (close(p_e[1]) < 0)
|
|
g_warning("popen_rw_unbuffered: close(p_e[1]) (parent) failed");
|
|
pfd[0] = p_r[0];
|
|
pfd[1] = p_e[0];
|
|
return pfd;
|
|
}
|
|
g_assert_not_reached();
|
|
return pfd;
|
|
}
|
|
|
|
void on_quit1_activate(GtkMenuItem *menuitem, gpointer user_data) { gtk_main_quit(); }
|
|
|
|
void on_about1_activate(GtkMenuItem *menuitem, gpointer user_data) {}
|
|
|
|
void on_btnStart_clicked(GtkButton *button, gpointer user_data) {
|
|
int *fd = NULL;
|
|
|
|
fd = popen_re_unbuffered(NULL);
|
|
g_timeout_add(200, wait_hydra_output, fd);
|
|
}
|
|
|
|
void on_btnStop_clicked(GtkButton *button, gpointer user_data) {
|
|
if (hydra_pid != 0) {
|
|
kill(hydra_pid, SIGTERM);
|
|
hydra_pid = 0;
|
|
}
|
|
}
|
|
|
|
void on_wndMain_destroy(GtkObject *object, gpointer user_data) {
|
|
if (hydra_pid != 0) {
|
|
kill(hydra_pid, SIGTERM);
|
|
hydra_pid = 0;
|
|
}
|
|
gtk_main_quit();
|
|
}
|
|
|
|
gboolean on_entTargetFile_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
|
|
hydra_select_file((GtkEntry *)widget, "Select target list");
|
|
gtk_widget_grab_focus(widget);
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean on_entUsernameFile_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
|
|
hydra_select_file((GtkEntry *)widget, "Select username list");
|
|
gtk_widget_grab_focus(widget);
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean on_entPassFile_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
|
|
hydra_select_file((GtkEntry *)widget, "Select password list");
|
|
gtk_widget_grab_focus(widget);
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean on_entColonFile_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
|
|
hydra_select_file((GtkEntry *)widget, "Select colon separated user,password list");
|
|
gtk_widget_grab_focus(widget);
|
|
return TRUE;
|
|
}
|
|
|
|
void on_btnSave_clicked(GtkButton *button, gpointer user_data) {
|
|
#ifdef GTK_TYPE_FILE_CHOOSER
|
|
GtkWidget *dialog;
|
|
char *filename;
|
|
gchar *text;
|
|
int fd;
|
|
GtkWidget *output;
|
|
GtkTextBuffer *outputbuf;
|
|
GtkTextIter start;
|
|
GtkTextIter end;
|
|
|
|
dialog = gtk_file_chooser_dialog_new("Save output", (GtkWindow *)wndMain, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
|
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
|
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
|
|
|
output = lookup_widget(GTK_WIDGET(wndMain), "txtOutput");
|
|
outputbuf = gtk_text_view_get_buffer((GtkTextView *)output);
|
|
gtk_text_buffer_get_start_iter(outputbuf, &start);
|
|
gtk_text_buffer_get_end_iter(outputbuf, &end);
|
|
|
|
text = gtk_text_buffer_get_text(outputbuf, &start, &end, TRUE);
|
|
|
|
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
|
if (fd >= 0) {
|
|
write(fd, text, strlen(text));
|
|
close(fd);
|
|
}
|
|
g_free(text);
|
|
g_free(filename);
|
|
}
|
|
gtk_widget_destroy(dialog);
|
|
#endif
|
|
}
|
|
|
|
void on_chkColon_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
|
|
GtkWidget *user, *pass;
|
|
|
|
user = lookup_widget(GTK_WIDGET(wndMain), "frmUsername");
|
|
;
|
|
pass = lookup_widget(GTK_WIDGET(wndMain), "frmPass");
|
|
|
|
if (gtk_toggle_button_get_active(togglebutton)) {
|
|
gtk_widget_set_sensitive(user, FALSE);
|
|
gtk_widget_set_sensitive(pass, FALSE);
|
|
} else {
|
|
gtk_widget_set_sensitive(user, TRUE);
|
|
gtk_widget_set_sensitive(pass, TRUE);
|
|
}
|
|
}
|
|
|
|
void on_chkDisUser_toggled(GtkToggleButton *togglebutton, gpointer user_data) {
|
|
GtkWidget *radioUsername1, *radioUsername2, *entUsername, *entUsernameFile;
|
|
|
|
radioUsername1 = lookup_widget(GTK_WIDGET(wndMain), "radioUsername1");
|
|
;
|
|
radioUsername2 = lookup_widget(GTK_WIDGET(wndMain), "radioUsername2");
|
|
entUsername = lookup_widget(GTK_WIDGET(wndMain), "entUsername");
|
|
entUsernameFile = lookup_widget(GTK_WIDGET(wndMain), "entUsernameFile");
|
|
|
|
if (gtk_toggle_button_get_active(togglebutton)) {
|
|
gtk_widget_set_sensitive(radioUsername1, FALSE);
|
|
gtk_widget_set_sensitive(radioUsername2, FALSE);
|
|
gtk_widget_set_sensitive(entUsername, FALSE);
|
|
gtk_widget_set_sensitive(entUsernameFile, FALSE);
|
|
} else {
|
|
gtk_widget_set_sensitive(radioUsername1, TRUE);
|
|
gtk_widget_set_sensitive(radioUsername2, TRUE);
|
|
gtk_widget_set_sensitive(entUsername, TRUE);
|
|
gtk_widget_set_sensitive(entUsernameFile, TRUE);
|
|
}
|
|
}
|
|
|
|
void on_btnClear_clicked(GtkButton *button, gpointer user_data) {
|
|
GtkWidget *output;
|
|
GtkTextBuffer *outputbuf;
|
|
|
|
output = lookup_widget(GTK_WIDGET(wndMain), "txtOutput");
|
|
outputbuf = gtk_text_view_get_buffer((GtkTextView *)output);
|
|
gtk_text_buffer_set_text(outputbuf, "", -1);
|
|
}
|