First set of fixes
There are still some problems but at least it does something now.
This commit is contained in:
parent
64fa986cd0
commit
4662e84995
|
@ -49,24 +49,6 @@ on_data (void *handle, struct unit *u, struct str *data)
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_eof (void *handle, struct unit *u)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_error (void *handle, struct unit *u)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_aborted (void *handle, struct unit *u)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct service g_http_service =
|
static struct service g_http_service =
|
||||||
{
|
{
|
||||||
.name = "HTTP",
|
.name = "HTTP",
|
||||||
|
@ -75,9 +57,9 @@ static struct service g_http_service =
|
||||||
.scan_init = scan_init,
|
.scan_init = scan_init,
|
||||||
.scan_free = scan_free,
|
.scan_free = scan_free,
|
||||||
.on_data = on_data,
|
.on_data = on_data,
|
||||||
.on_eof = on_eof,
|
.on_eof = NULL,
|
||||||
.on_error = on_error,
|
.on_error = NULL,
|
||||||
.on_aborted = on_aborted
|
.on_aborted = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
@ -30,44 +30,50 @@ static struct plugin_data
|
||||||
}
|
}
|
||||||
g_data;
|
g_data;
|
||||||
|
|
||||||
|
struct scan_data
|
||||||
|
{
|
||||||
|
struct str input; ///< Input buffer
|
||||||
|
};
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
scan_init (struct unit *u)
|
scan_init (struct unit *u)
|
||||||
{
|
{
|
||||||
// TODO
|
(void) u;
|
||||||
return NULL;
|
|
||||||
|
struct scan_data *scan = xcalloc (1, sizeof *scan);
|
||||||
|
str_init (&scan->input);
|
||||||
|
return scan;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
scan_free (void *handle)
|
scan_free (void *handle)
|
||||||
{
|
{
|
||||||
// TODO
|
struct scan_data *scan = handle;
|
||||||
|
str_free (&scan->input);
|
||||||
|
free (scan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_data (void *handle, struct unit *u, struct str *data)
|
on_data (void *handle, struct unit *u, struct str *data)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO: don't let the input buffer grow too much
|
||||||
|
struct scan_data *scan = handle;
|
||||||
|
str_append_str (&scan->input, data);
|
||||||
|
|
||||||
|
char *input = scan->input.str;
|
||||||
|
char *nl = strstr (input, "\r\n");
|
||||||
|
if (!nl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: parse the reply, make sure that it's actually SSH,
|
||||||
|
// don't put just any garbage in the output info
|
||||||
|
*nl = '\0';
|
||||||
|
g_data.api->unit_add_info (u, input);
|
||||||
|
g_data.api->unit_set_success (u, true);
|
||||||
|
g_data.api->unit_abort (u);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static struct service g_ssh_service =
|
||||||
on_eof (void *handle, struct unit *u)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_error (void *handle, struct unit *u)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_aborted (void *handle, struct unit *u)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct service g_http_service =
|
|
||||||
{
|
{
|
||||||
.name = "SSH",
|
.name = "SSH",
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
|
@ -75,16 +81,16 @@ static struct service g_http_service =
|
||||||
.scan_init = scan_init,
|
.scan_init = scan_init,
|
||||||
.scan_free = scan_free,
|
.scan_free = scan_free,
|
||||||
.on_data = on_data,
|
.on_data = on_data,
|
||||||
.on_eof = on_eof,
|
.on_eof = NULL,
|
||||||
.on_error = on_error,
|
.on_error = NULL,
|
||||||
.on_aborted = on_aborted
|
.on_aborted = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
initialize (void *ctx, struct plugin_api *api)
|
initialize (void *ctx, struct plugin_api *api)
|
||||||
{
|
{
|
||||||
g_data = (struct plugin_data) { .ctx = ctx, .api = api };
|
g_data = (struct plugin_data) { .ctx = ctx, .api = api };
|
||||||
api->register_service (ctx, &g_http_service);
|
api->register_service (ctx, &g_ssh_service);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
95
ponymap.c
95
ponymap.c
|
@ -70,7 +70,7 @@ init_terminal (void)
|
||||||
// Make sure all terminal features used by us are supported
|
// Make sure all terminal features used by us are supported
|
||||||
if (!set_a_foreground || !orig_pair
|
if (!set_a_foreground || !orig_pair
|
||||||
|| !enter_standout_mode || !exit_standout_mode
|
|| !enter_standout_mode || !exit_standout_mode
|
||||||
|| !clr_bol || !cursor_left)
|
|| !carriage_return || !cursor_left || !clr_eol)
|
||||||
{
|
{
|
||||||
del_curterm (cur_term);
|
del_curterm (cur_term);
|
||||||
return;
|
return;
|
||||||
|
@ -312,6 +312,10 @@ struct generator
|
||||||
struct transport *transport_iter; ///< Transport iterator
|
struct transport *transport_iter; ///< Transport iterator
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool generator_step (struct app_context *ctx);
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
struct app_context
|
struct app_context
|
||||||
{
|
{
|
||||||
struct str_map config; ///< User configuration
|
struct str_map config; ///< User configuration
|
||||||
|
@ -432,8 +436,9 @@ indicator_show (struct app_context *ctx)
|
||||||
if (self->shown || !g_terminal.initialized || !g_terminal.stdout_is_tty)
|
if (self->shown || !g_terminal.initialized || !g_terminal.stdout_is_tty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tputs (clr_bol, 1, putchar);
|
tputs (carriage_return, 1, putchar);
|
||||||
printf ("%s... %c", self->status, self->frames[self->position]);
|
printf ("%s... %c", self->status, self->frames[self->position]);
|
||||||
|
tputs (clr_eol, 1, putchar);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
indicator_set_timer (ctx);
|
indicator_set_timer (ctx);
|
||||||
|
|
||||||
|
@ -447,7 +452,8 @@ indicator_hide (struct app_context *ctx)
|
||||||
if (!self->shown)
|
if (!self->shown)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tputs (clr_bol, 1, putchar);
|
tputs (carriage_return, 1, putchar);
|
||||||
|
tputs (clr_eol, 1, putchar);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
|
|
||||||
ssize_t i = poller_timers_find
|
ssize_t i = poller_timers_find
|
||||||
|
@ -503,7 +509,16 @@ unit_abort (struct unit *u)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u->aborted = true;
|
u->aborted = true;
|
||||||
u->service->on_aborted (u->service_data, u);
|
if (u->service->on_aborted)
|
||||||
|
u->service->on_aborted (u->service_data, u);
|
||||||
|
|
||||||
|
ssize_t i;
|
||||||
|
struct app_context *ctx = u->target->ctx;
|
||||||
|
struct poller *poller = &ctx->poller;
|
||||||
|
if ((i = poller_find_by_fd (poller, u->socket_fd)) != -1)
|
||||||
|
poller_remove_at_index (poller, i);
|
||||||
|
while ((i = poller_timers_find_by_data (&poller->timers, u)) != -1)
|
||||||
|
poller_timers_remove_at_index (&poller->timers, i);
|
||||||
|
|
||||||
u->transport->cleanup (u);
|
u->transport->cleanup (u);
|
||||||
u->service->scan_free (u->service_data);
|
u->service->scan_free (u->service_data);
|
||||||
|
@ -516,11 +531,9 @@ unit_abort (struct unit *u)
|
||||||
// We're no longer running
|
// We're no longer running
|
||||||
LIST_UNLINK (u->target->running_units, u);
|
LIST_UNLINK (u->target->running_units, u);
|
||||||
|
|
||||||
// Get rid of all timers
|
// We might have made it possible to launch new units
|
||||||
struct poller *poller = &u->target->ctx->poller;
|
while (generator_step (ctx))
|
||||||
ssize_t i;
|
;
|
||||||
while ((i = poller_timers_find_by_data (&poller->timers, u)) != -1)
|
|
||||||
poller_timers_remove_at_index (&poller->timers, i);
|
|
||||||
|
|
||||||
if (u->success)
|
if (u->success)
|
||||||
{
|
{
|
||||||
|
@ -575,9 +588,15 @@ on_unit_ready (const struct pollfd *pfd, struct unit *u)
|
||||||
|
|
||||||
exception:
|
exception:
|
||||||
if (result == TRANSPORT_IO_EOF)
|
if (result == TRANSPORT_IO_EOF)
|
||||||
service->on_eof (u->service_data, u);
|
{
|
||||||
|
if (service->on_eof)
|
||||||
|
service->on_eof (u->service_data, u);
|
||||||
|
}
|
||||||
else if (result == TRANSPORT_IO_ERROR)
|
else if (result == TRANSPORT_IO_ERROR)
|
||||||
service->on_error (u->service_data, u);
|
{
|
||||||
|
if (service->on_error)
|
||||||
|
service->on_error (u->service_data, u);
|
||||||
|
}
|
||||||
|
|
||||||
unit_abort (u);
|
unit_abort (u);
|
||||||
|
|
||||||
|
@ -711,9 +730,7 @@ unit_make (struct target *target, uint32_t ip, uint16_t port,
|
||||||
static void
|
static void
|
||||||
try_finish_quit (struct app_context *ctx)
|
try_finish_quit (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->quitting
|
if (!ctx->running_targets && !ctx->generator.current_target)
|
||||||
&& !ctx->running_targets
|
|
||||||
&& !ctx->generator.current_target)
|
|
||||||
ctx->polling = false;
|
ctx->polling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -857,7 +874,7 @@ load_plugins (struct app_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *dot = strrchr (iter->d_name, '.');
|
char *dot = strrchr (iter->d_name, '.');
|
||||||
if (dot && !strcmp (dot, ".so"))
|
if (!dot || strcmp (dot, ".so"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *path = xstrdup_printf ("%s/%s", plugin_dir, iter->d_name);
|
char *path = xstrdup_printf ("%s/%s", plugin_dir, iter->d_name);
|
||||||
|
@ -1105,8 +1122,8 @@ initialize_tls (struct app_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fuck off, we're just scanning
|
// Fuck off, we're just scanning
|
||||||
SSL_CTX_set_verify (ctx->ssl_ctx, SSL_VERIFY_NONE, NULL);
|
SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);
|
||||||
SSL_CTX_set_mode (ctx->ssl_ctx,
|
SSL_CTX_set_mode (ssl_ctx,
|
||||||
SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||||
|
|
||||||
ctx->ssl_ctx = ssl_ctx;
|
ctx->ssl_ctx = ssl_ctx;
|
||||||
|
@ -1248,6 +1265,8 @@ target_dump_json (struct target *self, struct target_dump_data *data)
|
||||||
if (u->service != last_service)
|
if (u->service != last_service)
|
||||||
{
|
{
|
||||||
service = json_object ();
|
service = json_object ();
|
||||||
|
ports = json_array ();
|
||||||
|
|
||||||
json_array_append_new (services, service);
|
json_array_append_new (services, service);
|
||||||
json_object_set_new (service, "name",
|
json_object_set_new (service, "name",
|
||||||
json_string (u->service->name));
|
json_string (u->service->name));
|
||||||
|
@ -1256,7 +1275,6 @@ target_dump_json (struct target *self, struct target_dump_data *data)
|
||||||
json_object_set_new (service, "ports", ports);
|
json_object_set_new (service, "ports", ports);
|
||||||
|
|
||||||
last_service = u->service;
|
last_service = u->service;
|
||||||
ports = json_array ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t *port = json_object ();
|
json_t *port = json_object ();
|
||||||
|
@ -1426,6 +1444,7 @@ generator_make_target (struct app_context *ctx)
|
||||||
g->current_target = target;
|
g->current_target = target;
|
||||||
|
|
||||||
target->ref_count = 1;
|
target->ref_count = 1;
|
||||||
|
target->ctx = ctx;
|
||||||
target->ip = g->ip_iter;
|
target->ip = g->ip_iter;
|
||||||
if (g->ip_iter == g->ip_range_iter->original_address)
|
if (g->ip_iter == g->ip_range_iter->original_address)
|
||||||
target->hostname = xstrdup (g->ip_range_iter->original_name);
|
target->hostname = xstrdup (g->ip_range_iter->original_name);
|
||||||
|
@ -1458,16 +1477,21 @@ generator_step (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
struct generator *g = &ctx->generator;
|
struct generator *g = &ctx->generator;
|
||||||
|
|
||||||
// XXX: we're probably going to need a way to distinguish
|
if (ctx->quitting || !g->ip_range_iter)
|
||||||
// between "try again" and "stop trying".
|
|
||||||
if (!g->ip_range_iter)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!g->current_target)
|
if (!g->current_target)
|
||||||
generator_make_target (ctx);
|
generator_make_target (ctx);
|
||||||
if (unit_make (g->current_target, g->ip_iter, g->port_iter,
|
|
||||||
g->svc, g->transport_iter) != UNIT_MAKE_OK)
|
switch (unit_make (g->current_target,
|
||||||
|
g->ip_iter, g->port_iter, g->svc, g->transport_iter))
|
||||||
|
{
|
||||||
|
case UNIT_MAKE_OK:
|
||||||
|
case UNIT_MAKE_ERROR:
|
||||||
|
break;
|
||||||
|
case UNIT_MAKE_TRY_AGAIN:
|
||||||
|
// TODO: set a timer for a few seconds, we might eventually get lucky
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find the next available transport
|
// Try to find the next available transport
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -1646,7 +1670,7 @@ static bool
|
||||||
add_service (struct app_context *ctx, const char *name)
|
add_service (struct app_context *ctx, const char *name)
|
||||||
{
|
{
|
||||||
// To be resolved later
|
// To be resolved later
|
||||||
str_map_set (&ctx->svc_list, name, (void *) name);
|
str_map_set (&ctx->svc_list, name, xstrdup (name));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1678,14 +1702,14 @@ add_target (struct app_context *ctx, const char *target)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ip_range *range = xcalloc (1, sizeof *range);
|
struct ip_range *range = xcalloc (1, sizeof *range);
|
||||||
uint32_t bitmask = ~(((uint64_t) 1 << (32 - mask)) - 1);
|
uint32_t bitmask = ((uint64_t) 1 << (32 - mask)) - 1;
|
||||||
|
|
||||||
hard_assert (result->ai_family == AF_INET);
|
hard_assert (result->ai_family == AF_INET);
|
||||||
hard_assert (result->ai_addr->sa_family == AF_INET);
|
hard_assert (result->ai_addr->sa_family == AF_INET);
|
||||||
uint32_t addr = ntohl (((struct sockaddr_in *)
|
uint32_t addr = ntohl (((struct sockaddr_in *)
|
||||||
result->ai_addr)->sin_addr.s_addr);
|
result->ai_addr)->sin_addr.s_addr);
|
||||||
range->start = addr & bitmask;
|
range->start = addr & ~bitmask;
|
||||||
range->end = addr | bitmask;
|
range->end = addr | bitmask;
|
||||||
freeaddrinfo (result);
|
freeaddrinfo (result);
|
||||||
|
|
||||||
range->original_name = xstrdup (host);
|
range->original_name = xstrdup (host);
|
||||||
|
@ -1738,9 +1762,9 @@ resolve_service_names (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
struct str_map_iter iter;
|
struct str_map_iter iter;
|
||||||
str_map_iter_init (&iter, &ctx->svc_list);
|
str_map_iter_init (&iter, &ctx->svc_list);
|
||||||
const char *name;
|
char *name = NULL;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
while ((name = str_map_iter_next (&iter)))
|
while (free (name), (name = str_map_iter_next (&iter)))
|
||||||
{
|
{
|
||||||
struct service *service;
|
struct service *service;
|
||||||
if ((service = str_map_find (&ctx->services, name)))
|
if ((service = str_map_find (&ctx->services, name)))
|
||||||
|
@ -1892,8 +1916,10 @@ main (int argc, char *argv[])
|
||||||
if (!load_plugins (&ctx))
|
if (!load_plugins (&ctx))
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
|
|
||||||
LIST_PREPEND (ctx.transports, &g_transport_plain);
|
// TODO: make the order unimportant; this hopes all services support
|
||||||
|
// the plain transport and that it is the first on the list
|
||||||
initialize_tls (&ctx);
|
initialize_tls (&ctx);
|
||||||
|
LIST_PREPEND (ctx.transports, &g_transport_plain);
|
||||||
|
|
||||||
if (!ctx.port_list)
|
if (!ctx.port_list)
|
||||||
{
|
{
|
||||||
|
@ -1922,13 +1948,16 @@ main (int argc, char *argv[])
|
||||||
merge_port_ranges (&ctx);
|
merge_port_ranges (&ctx);
|
||||||
merge_ip_ranges (&ctx);
|
merge_ip_ranges (&ctx);
|
||||||
|
|
||||||
// TODO: initate the scan -> generate as many units as possible
|
// Initate the scan: generate as many units as possible
|
||||||
|
generator_init (&ctx);
|
||||||
|
while (generator_step (&ctx))
|
||||||
|
;
|
||||||
|
|
||||||
ctx.polling = true;
|
ctx.polling = true;
|
||||||
while (ctx.polling)
|
while (ctx.polling)
|
||||||
poller_run (&ctx.poller);
|
poller_run (&ctx.poller);
|
||||||
|
|
||||||
if (ctx.json_results && !json_dump_file (ctx.json_results,
|
if (ctx.json_results && json_dump_file (ctx.json_results,
|
||||||
ctx.json_filename, JSON_INDENT (2) | JSON_SORT_KEYS | JSON_ENCODE_ANY))
|
ctx.json_filename, JSON_INDENT (2) | JSON_SORT_KEYS | JSON_ENCODE_ANY))
|
||||||
print_error ("failed to write JSON output");
|
print_error ("failed to write JSON output");
|
||||||
|
|
||||||
|
|
4
utils.c
4
utils.c
|
@ -1214,11 +1214,11 @@ poller_run (struct poller *self)
|
||||||
if (n_fds == -1)
|
if (n_fds == -1)
|
||||||
exit_fatal ("%s: %s", "epoll", strerror (errno));
|
exit_fatal ("%s: %s", "epoll", strerror (errno));
|
||||||
|
|
||||||
poller_timers_dispatch (&self->timers);
|
|
||||||
|
|
||||||
self->dispatch_next = 0;
|
self->dispatch_next = 0;
|
||||||
self->dispatch_total = n_fds;
|
self->dispatch_total = n_fds;
|
||||||
|
|
||||||
|
poller_timers_dispatch (&self->timers);
|
||||||
|
|
||||||
while (self->dispatch_next < self->dispatch_total)
|
while (self->dispatch_next < self->dispatch_total)
|
||||||
{
|
{
|
||||||
struct epoll_event *revents = self->revents + self->dispatch_next;
|
struct epoll_event *revents = self->revents + self->dispatch_next;
|
||||||
|
|
Loading…
Reference in New Issue