mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-03-16 06:49:19 +08:00
Master process was converted to use libev
This commit is contained in:
committed by
Nikos Mavrogiannopoulos
parent
9252e22298
commit
0e604b8a9f
1
NEWS
1
NEWS
@@ -5,6 +5,7 @@
|
||||
- Added config option 'append-routes'. If set to true it will restore
|
||||
the old configuration semantics of appending the global routes to per
|
||||
user/group config.
|
||||
- Switched to an event-driven design in main; using libev
|
||||
|
||||
|
||||
* Version 0.10.9 (released 2015-10-07)
|
||||
|
||||
@@ -13,6 +13,7 @@ and is believed to be compatible with CISCO's AnyConnect SSL VPN.
|
||||
Required dependencies (Debian pkg/Fedora pkg):
|
||||
```
|
||||
libgnutls28-dev / gnutls-devel
|
||||
libev-dev / libev-devel
|
||||
```
|
||||
|
||||
Optional dependencies that enable specific functionality:
|
||||
|
||||
@@ -85,6 +85,14 @@ fi
|
||||
|
||||
AM_CONDITIONAL(LOCAL_PROTOBUF_C, test "x$with_local_protobuf_c" != xno)
|
||||
|
||||
AC_LIB_HAVE_LINKFLAGS(ev,, [#include <ev.h>], [ev_run(0,0);])
|
||||
if test x$ac_cv_libev = xyes; then
|
||||
AC_SUBST([LIBEV_LIBS], [$LIBEV])
|
||||
else
|
||||
AC_MSG_ERROR([[***
|
||||
*** libev4 was not found.
|
||||
***]])
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(local-talloc,
|
||||
AS_HELP_STRING([--with-local-talloc], [use the included talloc library]),
|
||||
|
||||
@@ -81,7 +81,8 @@ ocserv_LDADD += $(LIBGNUTLS_LIBS) $(PAM_LIBS) $(LIBUTIL) \
|
||||
$(LIBSECCOMP) $(LIBWRAP) $(LIBCRYPT) $(NEEDED_HTTP_PARSER_LIBS) \
|
||||
$(LIBPROTOBUF_C_LIBS) $(LIBSYSTEMD) $(LIBTALLOC_LIBS) \
|
||||
$(RADCLI_LIBS) $(LIBLZ4_LIBS) $(LIBKRB5_LIBS) \
|
||||
$(LIBTASN1_LIBS) $(LIBOATH_LIBS) $(LIBNETTLE_LIBS)
|
||||
$(LIBTASN1_LIBS) $(LIBOATH_LIBS) $(LIBNETTLE_LIBS) \
|
||||
$(LIBEV_LIBS)
|
||||
|
||||
|
||||
if PCL
|
||||
|
||||
@@ -192,7 +192,7 @@ static void method_reload(method_ctx *ctx, int cfd, uint8_t * msg,
|
||||
|
||||
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: reload");
|
||||
|
||||
request_reload(0);
|
||||
ev_feed_signal_event (loop, SIGHUP);
|
||||
|
||||
rep.status = 1;
|
||||
|
||||
@@ -214,7 +214,7 @@ static void method_stop(method_ctx *ctx, int cfd, uint8_t * msg,
|
||||
|
||||
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: stop");
|
||||
|
||||
request_stop(0);
|
||||
ev_feed_signal_event (loop, SIGTERM);
|
||||
|
||||
rep.status = 1;
|
||||
|
||||
@@ -766,21 +766,18 @@ static void ctl_handle_commands(main_server_st * s)
|
||||
close(cfd);
|
||||
}
|
||||
|
||||
int ctl_handler_set_fds(main_server_st * s, fd_set * rd_set, fd_set * wr_set)
|
||||
{
|
||||
if (s->config->use_occtl == 0)
|
||||
return -1;
|
||||
|
||||
FD_SET(s->ctl_fd, rd_set);
|
||||
return s->ctl_fd;
|
||||
}
|
||||
|
||||
void ctl_handler_run_pending(main_server_st* s, fd_set *rd_set, fd_set *wr_set)
|
||||
void ctl_handler_set_fds(main_server_st * s, ev_io *watcher)
|
||||
{
|
||||
if (s->config->use_occtl == 0)
|
||||
return;
|
||||
|
||||
if (FD_ISSET(s->ctl_fd, rd_set)) {
|
||||
ctl_handle_commands(s);
|
||||
}
|
||||
ev_io_set(watcher, s->ctl_fd, EV_READ);
|
||||
}
|
||||
|
||||
void ctl_handler_run_pending(main_server_st* s, ev_io *watcher)
|
||||
{
|
||||
if (s->config->use_occtl == 0)
|
||||
return;
|
||||
|
||||
ctl_handle_commands(s);
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
# define MAIN_CTL_HANDLER_H
|
||||
|
||||
#include <occtl/ctl.h>
|
||||
|
||||
#include <ev.h>
|
||||
|
||||
int ctl_handler_init(main_server_st* s);
|
||||
void ctl_handler_deinit(main_server_st* s);
|
||||
|
||||
int ctl_handler_set_fds(main_server_st* s, fd_set *rd_set, fd_set *wr_set);
|
||||
void ctl_handler_run_pending(main_server_st* s, fd_set *rd_set, fd_set *wr_set);
|
||||
void ctl_handler_set_fds(main_server_st* s, ev_io *watcher);
|
||||
void ctl_handler_run_pending(main_server_st* s, ev_io *watcher);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <ipc.pb-c.h>
|
||||
#include <script-list.h>
|
||||
#include <inttypes.h>
|
||||
#include <ev.h>
|
||||
|
||||
#ifdef HAVE_MALLOC_TRIM
|
||||
# include <malloc.h>
|
||||
@@ -182,6 +183,9 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned flags)
|
||||
{
|
||||
mslog(s, proc, LOG_INFO, "user disconnected (rx: %"PRIu64", tx: %"PRIu64")", proc->bytes_in, proc->bytes_out);
|
||||
|
||||
ev_io_stop(EV_A_ &proc->io);
|
||||
ev_child_stop(EV_A_ &proc->ev_child);
|
||||
|
||||
list_del(&proc->list);
|
||||
s->active_clients--;
|
||||
|
||||
|
||||
@@ -132,7 +132,6 @@ int handle_resume_store_req(main_server_st * s, struct proc_st *proc,
|
||||
mslog(s, NULL, LOG_INFO,
|
||||
"maximum number of stored TLS sessions reached (%u)",
|
||||
max);
|
||||
need_maintenance = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
749
src/main.c
749
src/main.c
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2015 Nikos Mavrogiannopoulos
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -46,6 +47,7 @@
|
||||
#ifdef HAVE_LIBWRAP
|
||||
# include <tcpd.h>
|
||||
#endif
|
||||
#include <ev.h>
|
||||
|
||||
#ifdef HAVE_LIBSYSTEMD
|
||||
# include <systemd/sd-daemon.h>
|
||||
@@ -72,12 +74,20 @@ ASN1_TYPE _kkdcp_pkix1_asn = ASN1_TYPE_EMPTY;
|
||||
int saved_argc = 0;
|
||||
char **saved_argv = NULL;
|
||||
|
||||
static void listen_watcher_cb (EV_P_ ev_io *w, int revents);
|
||||
|
||||
int syslog_open = 0;
|
||||
static unsigned int terminate = 0;
|
||||
static unsigned int reload_conf = 0;
|
||||
unsigned int need_maintenance = 0;
|
||||
static unsigned int need_children_cleanup = 0;
|
||||
sigset_t sig_default_set;
|
||||
struct ev_loop *loop;
|
||||
|
||||
/* EV watchers */
|
||||
ev_io ctl_watcher;
|
||||
ev_io sec_mod_watcher;
|
||||
ev_timer maintainance_watcher;
|
||||
ev_signal term_sig_watcher;
|
||||
ev_signal int_sig_watcher;
|
||||
ev_signal reload_sig_watcher;
|
||||
ev_child child_watcher;
|
||||
|
||||
static void add_listener(void *pool, struct listen_list_st *list,
|
||||
int fd, int family, int socktype, int protocol,
|
||||
@@ -94,6 +104,9 @@ static void add_listener(void *pool, struct listen_list_st *list,
|
||||
tmp->addr_len = addr_len;
|
||||
memcpy(&tmp->addr, addr, addr_len);
|
||||
|
||||
ev_init(&tmp->io, listen_watcher_cb);
|
||||
ev_io_set(&tmp->io, fd, EV_READ);
|
||||
|
||||
list_add(&list->head, &(tmp->list));
|
||||
list->total++;
|
||||
}
|
||||
@@ -370,7 +383,7 @@ listen_ports(void *pool, struct perm_cfg_st* config,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (config->config->foreground != 0)
|
||||
if (config->foreground != 0)
|
||||
fprintf(stderr, "listening on %d systemd sockets...\n", list->total);
|
||||
|
||||
return 0;
|
||||
@@ -483,61 +496,6 @@ int y;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void cleanup_children(main_server_st *s)
|
||||
{
|
||||
int status, estatus, ret;
|
||||
pid_t pid;
|
||||
struct script_wait_st *stmp = NULL, *spos;
|
||||
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
estatus = WEXITSTATUS(status);
|
||||
|
||||
if (WIFSIGNALED(status))
|
||||
estatus = 1;
|
||||
|
||||
if (pid == s->sec_mod_pid) {
|
||||
mslog(s, NULL, LOG_ERR, "ocserv-secmod died unexpectedly");
|
||||
terminate = 1;
|
||||
}
|
||||
|
||||
/* check if someone was waiting for that pid */
|
||||
list_for_each_safe(&s->script_list.head, stmp, spos, list) {
|
||||
if (stmp->pid == pid) {
|
||||
mslog(s, stmp->proc, LOG_DEBUG, "%s-script exit status: %u", stmp->up?"connect":"disconnect", estatus);
|
||||
list_del(&stmp->list);
|
||||
ret = handle_script_exit(s, stmp->proc, estatus);
|
||||
if (ret < 0) {
|
||||
remove_proc(s, stmp->proc, RPROC_KILL);
|
||||
} else {
|
||||
talloc_free(stmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WIFSIGNALED(status)) {
|
||||
if (WTERMSIG(status) == SIGSEGV)
|
||||
mslog(s, NULL, LOG_ERR, "Child %u died with sigsegv\n", (unsigned)pid);
|
||||
else if (WTERMSIG(status) == SIGSYS)
|
||||
mslog(s, NULL, LOG_ERR, "Child %u died with sigsys\n", (unsigned)pid);
|
||||
else
|
||||
mslog(s, NULL, LOG_ERR, "Child %u died with signal %d\n", (unsigned)pid, (int)WTERMSIG(status));
|
||||
}
|
||||
}
|
||||
need_children_cleanup = 0;
|
||||
}
|
||||
|
||||
static void handle_children(int signo)
|
||||
{
|
||||
need_children_cleanup = 1;
|
||||
}
|
||||
|
||||
static void handle_alarm(int signo)
|
||||
{
|
||||
need_maintenance = 1;
|
||||
}
|
||||
|
||||
static void drop_privileges(main_server_st* s)
|
||||
{
|
||||
int ret, e;
|
||||
@@ -660,31 +618,6 @@ void clear_lists(main_server_st *s)
|
||||
main_ban_db_deinit(s);
|
||||
}
|
||||
|
||||
static void kill_children(main_server_st* s)
|
||||
{
|
||||
struct proc_st *ctmp = NULL, *cpos;
|
||||
|
||||
/* kill the security module server */
|
||||
kill(s->sec_mod_pid, SIGTERM);
|
||||
list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) {
|
||||
if (ctmp->pid != -1) {
|
||||
remove_proc(s, ctmp, RPROC_KILL|RPROC_QUIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void request_stop(int signo)
|
||||
{
|
||||
/* kill all children */
|
||||
terminate = 1;
|
||||
}
|
||||
|
||||
void request_reload(int signo)
|
||||
{
|
||||
reload_conf = 1;
|
||||
}
|
||||
|
||||
|
||||
/* A UDP fd will not be forwarded to worker process before this number of
|
||||
* seconds has passed. That is to prevent a duplicate message messing the worker.
|
||||
*/
|
||||
@@ -842,67 +775,6 @@ fail:
|
||||
|
||||
}
|
||||
|
||||
#define MAINTAINANCE_TIME(s) (900)
|
||||
|
||||
static void check_other_work(main_server_st *s)
|
||||
{
|
||||
unsigned total = 10;
|
||||
|
||||
if (reload_conf != 0) {
|
||||
mslog(s, NULL, LOG_INFO, "reloading configuration");
|
||||
reload_cfg_file(s->main_pool, s->perm_config, 1);
|
||||
s->config = s->perm_config->config;
|
||||
tls_reload_crl(s, s->creds, 1);
|
||||
reload_conf = 0;
|
||||
kill(s->sec_mod_pid, SIGHUP);
|
||||
}
|
||||
|
||||
if (need_children_cleanup != 0) {
|
||||
cleanup_children(s);
|
||||
}
|
||||
|
||||
if (terminate != 0) {
|
||||
mslog(s, NULL, LOG_INFO, "termination request received; waiting for children to die");
|
||||
kill_children(s);
|
||||
remove(s->full_socket_file);
|
||||
remove(s->perm_config->occtl_socket_file);
|
||||
remove_pid_file();
|
||||
|
||||
while (waitpid(-1, NULL, WNOHANG) >= 0) {
|
||||
if (total == 0) {
|
||||
mslog(s, NULL, LOG_INFO, "not everyone died; forcing kill");
|
||||
kill(0, SIGKILL);
|
||||
}
|
||||
ms_sleep(500);
|
||||
total--;
|
||||
}
|
||||
|
||||
/* try to clean-up everything allocated to ease checks
|
||||
* for memory leaks.
|
||||
*/
|
||||
clear_lists(s);
|
||||
tls_global_deinit(s->creds);
|
||||
clear_cfg(s->perm_config);
|
||||
talloc_free(s->perm_config);
|
||||
talloc_free(s->main_pool);
|
||||
closelog();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Check if we need to expire any data */
|
||||
if (need_maintenance != 0) {
|
||||
need_maintenance = 0;
|
||||
mslog(s, NULL, LOG_DEBUG, "performing maintenance (banned IPs: %d)", main_ban_db_elems(s));
|
||||
|
||||
/* will make sure it only reloads when needed */
|
||||
tls_reload_crl(s, s->creds, 0);
|
||||
expire_tls_sessions(s);
|
||||
cleanup_banned_entries(s);
|
||||
clear_old_configs(s->perm_config);
|
||||
alarm(MAINTAINANCE_TIME(s));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBWRAP
|
||||
static int check_tcp_wrapper(int fd)
|
||||
{
|
||||
@@ -921,38 +793,326 @@ static int check_tcp_wrapper(int fd)
|
||||
# define check_tcp_wrapper(x) 0
|
||||
#endif
|
||||
|
||||
static void child_watcher_cb(struct ev_loop *loop, ev_child *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
|
||||
if (w->pid == s->sec_mod_pid) {
|
||||
mslog(s, NULL, LOG_ERR, "ocserv-secmod died unexpectedly");
|
||||
ev_feed_signal_event (loop, SIGTERM);
|
||||
return;
|
||||
}
|
||||
|
||||
if (WIFSIGNALED(w->rstatus)) {
|
||||
if (WTERMSIG(w->rstatus) == SIGSEGV)
|
||||
mslog(s, NULL, LOG_ERR, "Sec-mod %u died with sigsegv\n", (unsigned)w->pid);
|
||||
else if (WTERMSIG(w->rstatus) == SIGSYS)
|
||||
mslog(s, NULL, LOG_ERR, "Sec-mod %u died with sigsys\n", (unsigned)w->pid);
|
||||
else
|
||||
mslog(s, NULL, LOG_ERR, "Sec-mod %u died with signal %d\n", (unsigned)w->pid, (int)WTERMSIG(w->rstatus));
|
||||
}
|
||||
}
|
||||
|
||||
void script_child_watcher_cb(struct ev_loop *loop, ev_child *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
int ret;
|
||||
struct script_wait_st *stmp = (struct script_wait_st*)w;
|
||||
unsigned estatus;
|
||||
|
||||
estatus = WEXITSTATUS(w->rstatus);
|
||||
if (WIFSIGNALED(w->rstatus))
|
||||
estatus = 1;
|
||||
|
||||
/* check if someone was waiting for that pid */
|
||||
mslog(s, stmp->proc, LOG_DEBUG, "%s-script exit status: %u", stmp->up?"connect":"disconnect", estatus);
|
||||
list_del(&stmp->list);
|
||||
|
||||
ret = handle_script_exit(s, stmp->proc, estatus);
|
||||
if (ret < 0) {
|
||||
/* takes care of free */
|
||||
remove_proc(s, stmp->proc, RPROC_KILL);
|
||||
} else {
|
||||
talloc_free(stmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void worker_child_watcher_cb(struct ev_loop *loop, ev_child *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
|
||||
if (WIFSIGNALED(w->rstatus)) {
|
||||
if (WTERMSIG(w->rstatus) == SIGSEGV)
|
||||
mslog(s, NULL, LOG_ERR, "Child %u died with sigsegv\n", (unsigned)w->pid);
|
||||
else if (WTERMSIG(w->rstatus) == SIGSYS)
|
||||
mslog(s, NULL, LOG_ERR, "Child %u died with sigsys\n", (unsigned)w->pid);
|
||||
else
|
||||
mslog(s, NULL, LOG_ERR, "Child %u died with signal %d\n", (unsigned)w->pid, (int)WTERMSIG(w->rstatus));
|
||||
}
|
||||
}
|
||||
|
||||
static void kill_children(main_server_st* s)
|
||||
{
|
||||
struct proc_st *ctmp = NULL, *cpos;
|
||||
|
||||
/* kill the security module server */
|
||||
kill(s->sec_mod_pid, SIGTERM);
|
||||
list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) {
|
||||
if (ctmp->pid != -1) {
|
||||
remove_proc(s, ctmp, RPROC_KILL|RPROC_QUIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void term_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
unsigned total = 10;
|
||||
|
||||
mslog(s, NULL, LOG_INFO, "termination request received; waiting for children to die");
|
||||
kill_children(s);
|
||||
|
||||
while (waitpid(-1, NULL, WNOHANG) >= 0) {
|
||||
if (total == 0) {
|
||||
mslog(s, NULL, LOG_INFO, "not everyone died; forcing kill");
|
||||
kill(0, SIGKILL);
|
||||
}
|
||||
ms_sleep(500);
|
||||
total--;
|
||||
}
|
||||
|
||||
ev_break (loop, EVBREAK_ALL);
|
||||
}
|
||||
|
||||
static void reload_sig_watcher_cb(struct ev_loop *loop, ev_signal *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
|
||||
mslog(s, NULL, LOG_INFO, "reloading configuration");
|
||||
reload_cfg_file(s->main_pool, s->perm_config, 1);
|
||||
s->config = s->perm_config->config;
|
||||
tls_reload_crl(s, s->creds, 1);
|
||||
kill(s->sec_mod_pid, SIGHUP);
|
||||
}
|
||||
|
||||
static void cmd_watcher_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
struct proc_st *ctmp = (struct proc_st*)w;
|
||||
int ret;
|
||||
|
||||
/* Check for any pending commands */
|
||||
ret = handle_commands(s, ctmp);
|
||||
if (ret < 0) {
|
||||
remove_proc(s, ctmp, (ret!=ERR_WORKER_TERMINATED)?RPROC_KILL:0);
|
||||
}
|
||||
}
|
||||
|
||||
static void listen_watcher_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
struct listener_st *ltmp = (struct listener_st *)w;
|
||||
struct proc_st *ctmp = NULL;
|
||||
struct worker_st *ws = s->ws;
|
||||
int fd, ret;
|
||||
int cmd_fd[2];
|
||||
pid_t pid;
|
||||
|
||||
if (ltmp->sock_type == SOCK_TYPE_TCP || ltmp->sock_type == SOCK_TYPE_UNIX) {
|
||||
/* connection on TCP port */
|
||||
int stype = ltmp->sock_type;
|
||||
|
||||
ws->remote_addr_len = sizeof(ws->remote_addr);
|
||||
fd = accept(ltmp->fd, (void*)&ws->remote_addr, &ws->remote_addr_len);
|
||||
if (fd < 0) {
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error in accept(): %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
set_cloexec_flag (fd, 1);
|
||||
#ifndef __linux__
|
||||
/* OpenBSD sets the non-blocking flag if accept's fd is non-blocking */
|
||||
set_block(fd);
|
||||
#endif
|
||||
|
||||
if (s->config->max_clients > 0 && s->active_clients >= s->config->max_clients) {
|
||||
close(fd);
|
||||
mslog(s, NULL, LOG_INFO, "reached maximum client limit (active: %u)", s->active_clients);
|
||||
return;
|
||||
}
|
||||
|
||||
if (check_tcp_wrapper(fd) < 0) {
|
||||
close(fd);
|
||||
mslog(s, NULL, LOG_INFO, "TCP wrappers rejected the connection (see /etc/hosts->[allow|deny])");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ws->conn_type != SOCK_TYPE_UNIX && !s->config->listen_proxy_proto) {
|
||||
memset(&ws->our_addr, 0, sizeof(ws->our_addr));
|
||||
ws->our_addr_len = sizeof(ws->our_addr);
|
||||
if (getsockname(fd, (struct sockaddr*)&ws->our_addr, &ws->our_addr_len) < 0)
|
||||
ws->our_addr_len = 0;
|
||||
|
||||
if (check_if_banned(s, &ws->remote_addr, ws->remote_addr_len) != 0) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a command socket */
|
||||
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_fd);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "error creating command socket");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) { /* child */
|
||||
/* close any open descriptors, and erase
|
||||
* sensitive data before running the worker
|
||||
*/
|
||||
sigprocmask(SIG_SETMASK, &sig_default_set, NULL);
|
||||
close(cmd_fd[0]);
|
||||
clear_lists(s);
|
||||
close(s->sec_mod_fd);
|
||||
close(s->sec_mod_fd_sync);
|
||||
|
||||
/* clear the cookie key */
|
||||
safe_memset(s->cookie_key, 0, sizeof(s->cookie_key));
|
||||
safe_memset(s->prev_cookie_key, 0, sizeof(s->prev_cookie_key));
|
||||
|
||||
setproctitle(PACKAGE_NAME"-worker");
|
||||
kill_on_parent_kill(SIGTERM);
|
||||
|
||||
/* write sec-mod's address */
|
||||
memcpy(&ws->secmod_addr, &s->secmod_addr, s->secmod_addr_len);
|
||||
ws->secmod_addr_len = s->secmod_addr_len;
|
||||
|
||||
ws->main_pool = s->main_pool;
|
||||
ws->config = s->config;
|
||||
ws->perm_config = s->perm_config;
|
||||
ws->cmd_fd = cmd_fd[1];
|
||||
ws->tun_fd = -1;
|
||||
ws->dtls_tptr.fd = -1;
|
||||
ws->conn_fd = fd;
|
||||
ws->conn_type = stype;
|
||||
ws->creds = s->creds;
|
||||
|
||||
/* Drop privileges after this point */
|
||||
drop_privileges(s);
|
||||
|
||||
/* creds and config are not allocated
|
||||
* under s.
|
||||
*/
|
||||
talloc_free(s);
|
||||
#ifdef HAVE_MALLOC_TRIM
|
||||
/* try to return all the pages we've freed to
|
||||
* the operating system, to prevent the child from
|
||||
* accessing them. That's totally unreliable, so
|
||||
* sensitive data have to be overwritten anyway. */
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
vpn_server(ws);
|
||||
exit(0);
|
||||
} else if (pid == -1) {
|
||||
fork_failed:
|
||||
mslog(s, NULL, LOG_ERR, "fork failed");
|
||||
close(cmd_fd[0]);
|
||||
} else { /* parent */
|
||||
/* add_proc */
|
||||
ctmp = new_proc(s, pid, cmd_fd[0],
|
||||
&ws->remote_addr, ws->remote_addr_len,
|
||||
&ws->our_addr, ws->our_addr_len,
|
||||
ws->sid, sizeof(ws->sid));
|
||||
if (ctmp == NULL) {
|
||||
kill(pid, SIGTERM);
|
||||
goto fork_failed;
|
||||
}
|
||||
|
||||
ev_io_init(&ctmp->io, cmd_watcher_cb, cmd_fd[0], EV_READ);
|
||||
ev_io_start(loop, &ctmp->io);
|
||||
|
||||
ev_child_init(&ctmp->ev_child, worker_child_watcher_cb, pid, 0);
|
||||
ev_child_start(loop, &ctmp->ev_child);
|
||||
}
|
||||
close(cmd_fd[1]);
|
||||
close(fd);
|
||||
} else if (ltmp->sock_type == SOCK_TYPE_UDP) {
|
||||
/* connection on UDP port */
|
||||
forward_udp_to_owner(s, ltmp);
|
||||
}
|
||||
|
||||
if (s->config->rate_limit_ms > 0)
|
||||
ms_sleep(s->config->rate_limit_ms);
|
||||
}
|
||||
|
||||
static void sec_mod_watcher_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
int ret;
|
||||
|
||||
ret = handle_sec_mod_commands(s);
|
||||
if (ret < 0) { /* bad commands from sec-mod are unacceptable */
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error in command from sec-mod");
|
||||
ev_feed_signal_event (loop, SIGTERM);
|
||||
}
|
||||
}
|
||||
|
||||
static void ctl_watcher_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
|
||||
ctl_handler_run_pending(s, w);
|
||||
}
|
||||
|
||||
static void maintainance_watcher_cb(EV_P_ ev_timer *w, int revents)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
|
||||
/* Check if we need to expire any data */
|
||||
mslog(s, NULL, LOG_DEBUG, "performing maintenance (banned IPs: %d)", main_ban_db_elems(s));
|
||||
tls_reload_crl(s, s->creds, 0);
|
||||
expire_tls_sessions(s);
|
||||
cleanup_banned_entries(s);
|
||||
clear_old_configs(s->perm_config);
|
||||
}
|
||||
|
||||
static void syserr_cb (const char *msg)
|
||||
{
|
||||
main_server_st *s = ev_userdata(loop);
|
||||
|
||||
mslog(s, NULL, LOG_ERR, "libev fatal error: %s", msg);
|
||||
abort();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int fd, pid, e;
|
||||
int e;
|
||||
struct listener_st *ltmp = NULL;
|
||||
struct proc_st *ctmp = NULL, *cpos;
|
||||
fd_set rd_set, wr_set;
|
||||
int n = 0, ret, flags;
|
||||
int ret, flags;
|
||||
char *p;
|
||||
#ifdef HAVE_PSELECT
|
||||
struct timespec ts;
|
||||
#else
|
||||
struct timeval ts;
|
||||
#endif
|
||||
int cmd_fd[2];
|
||||
struct worker_st *ws;
|
||||
void *worker_pool;
|
||||
void *main_pool;
|
||||
unsigned set;
|
||||
main_server_st *s;
|
||||
sigset_t emptyset, blockset;
|
||||
/* tls credentials */
|
||||
struct tls_st creds;
|
||||
|
||||
#ifdef DEBUG_LEAKS
|
||||
talloc_enable_leak_report_full();
|
||||
#endif
|
||||
|
||||
saved_argc = argc;
|
||||
saved_argv = argv;
|
||||
|
||||
memset(&creds, 0, sizeof(creds));
|
||||
|
||||
loop = EV_DEFAULT;
|
||||
if (loop == NULL) {
|
||||
fprintf(stderr, "could not initialise libev\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* main pool */
|
||||
main_pool = talloc_init("main");
|
||||
if (main_pool == NULL) {
|
||||
@@ -976,20 +1136,9 @@ int main(int argc, char** argv)
|
||||
proc_table_init(s);
|
||||
main_ban_db_init(s);
|
||||
|
||||
sigemptyset(&blockset);
|
||||
sigemptyset(&emptyset);
|
||||
sigaddset(&blockset, SIGALRM);
|
||||
sigaddset(&blockset, SIGTERM);
|
||||
sigaddset(&blockset, SIGINT);
|
||||
sigaddset(&blockset, SIGCHLD);
|
||||
sigaddset(&blockset, SIGHUP);
|
||||
sigemptyset(&sig_default_set);
|
||||
|
||||
ocsignal(SIGINT, request_stop);
|
||||
ocsignal(SIGTERM, request_stop);
|
||||
ocsignal(SIGPIPE, SIG_IGN);
|
||||
ocsignal(SIGHUP, request_reload);
|
||||
ocsignal(SIGCHLD, handle_children);
|
||||
ocsignal(SIGALRM, handle_alarm);
|
||||
|
||||
/* Initialize GnuTLS */
|
||||
tls_global_init(&creds);
|
||||
@@ -1047,7 +1196,6 @@ int main(int argc, char** argv)
|
||||
write_pid_file();
|
||||
|
||||
s->sec_mod_fd = run_sec_mod(s, &s->sec_mod_fd_sync);
|
||||
|
||||
ret = ctl_handler_init(s);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot create command handler\n");
|
||||
@@ -1084,8 +1232,8 @@ int main(int argc, char** argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ws = talloc_zero(worker_pool, struct worker_st);
|
||||
if (ws == NULL) {
|
||||
s->ws = talloc_zero(worker_pool, struct worker_st);
|
||||
if (s->ws == NULL) {
|
||||
fprintf(stderr, "memory error\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -1105,217 +1253,60 @@ int main(int argc, char** argv)
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
|
||||
sigprocmask(SIG_BLOCK, &blockset, &sig_default_set);
|
||||
alarm(MAINTAINANCE_TIME(s));
|
||||
ev_set_userdata (loop, s);
|
||||
ev_set_syserr_cb(syserr_cb);
|
||||
|
||||
for (;;) {
|
||||
check_other_work(s);
|
||||
ev_init(&ctl_watcher, ctl_watcher_cb);
|
||||
ev_init(&sec_mod_watcher, sec_mod_watcher_cb);
|
||||
|
||||
/* initialize select */
|
||||
n = 0;
|
||||
FD_ZERO(&rd_set);
|
||||
FD_ZERO(&wr_set);
|
||||
ev_init (&int_sig_watcher, term_sig_watcher_cb);
|
||||
ev_signal_set (&int_sig_watcher, SIGINT);
|
||||
ev_signal_start (loop, &int_sig_watcher);
|
||||
|
||||
list_for_each(&s->listen_list.head, ltmp, list) {
|
||||
if (ltmp->fd == -1) continue;
|
||||
ev_init (&term_sig_watcher, term_sig_watcher_cb);
|
||||
ev_signal_set (&term_sig_watcher, SIGTERM);
|
||||
ev_signal_start (loop, &term_sig_watcher);
|
||||
|
||||
FD_SET(ltmp->fd, &rd_set);
|
||||
n = MAX(n, ltmp->fd);
|
||||
}
|
||||
ev_init (&reload_sig_watcher, reload_sig_watcher_cb);
|
||||
ev_signal_set (&reload_sig_watcher, SIGHUP);
|
||||
ev_signal_start (loop, &reload_sig_watcher);
|
||||
|
||||
list_for_each(&s->proc_list.head, ctmp, list) {
|
||||
if (ctmp->fd > 0) {
|
||||
FD_SET(ctmp->fd, &rd_set);
|
||||
n = MAX(n, ctmp->fd);
|
||||
}
|
||||
}
|
||||
/* set the standard fds we watch */
|
||||
list_for_each(&s->listen_list.head, ltmp, list) {
|
||||
if (ltmp->fd == -1) continue;
|
||||
|
||||
FD_SET(s->sec_mod_fd, &rd_set);
|
||||
n = MAX(n, s->sec_mod_fd);
|
||||
|
||||
ret = ctl_handler_set_fds(s, &rd_set, &wr_set);
|
||||
n = MAX(n, ret);
|
||||
|
||||
#ifdef HAVE_PSELECT
|
||||
ts.tv_nsec = 0;
|
||||
ts.tv_sec = 30;
|
||||
ret = pselect(n + 1, &rd_set, NULL/*&wr_set*/, NULL, &ts, &emptyset);
|
||||
#else
|
||||
ts.tv_usec = 0;
|
||||
ts.tv_sec = 30;
|
||||
sigprocmask(SIG_UNBLOCK, &blockset, NULL);
|
||||
ret = select(n + 1, &rd_set, NULL/*&wr_set*/, NULL, &ts);
|
||||
sigprocmask(SIG_BLOCK, &blockset, NULL);
|
||||
#endif
|
||||
|
||||
if (ret == -1 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "Error in pselect(): %s",
|
||||
strerror(e));
|
||||
terminate = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for new connections to accept */
|
||||
list_for_each(&s->listen_list.head, ltmp, list) {
|
||||
set = FD_ISSET(ltmp->fd, &rd_set);
|
||||
if (set && (ltmp->sock_type == SOCK_TYPE_TCP || ltmp->sock_type == SOCK_TYPE_UNIX)) {
|
||||
/* connection on TCP port */
|
||||
int stype = ltmp->sock_type;
|
||||
|
||||
ws->remote_addr_len = sizeof(ws->remote_addr);
|
||||
fd = accept(ltmp->fd, (void*)&ws->remote_addr, &ws->remote_addr_len);
|
||||
if (fd < 0) {
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error in accept(): %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
set_cloexec_flag (fd, 1);
|
||||
#ifndef __linux__
|
||||
/* OpenBSD sets the non-blocking flag if accept's fd is non-blocking */
|
||||
set_block(fd);
|
||||
#endif
|
||||
|
||||
if (s->config->max_clients > 0 && s->active_clients >= s->config->max_clients) {
|
||||
close(fd);
|
||||
mslog(s, NULL, LOG_INFO, "reached maximum client limit (active: %u)", s->active_clients);
|
||||
break;
|
||||
}
|
||||
|
||||
if (check_tcp_wrapper(fd) < 0) {
|
||||
close(fd);
|
||||
mslog(s, NULL, LOG_INFO, "TCP wrappers rejected the connection (see /etc/hosts->[allow|deny])");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ws->conn_type != SOCK_TYPE_UNIX && !s->config->listen_proxy_proto) {
|
||||
memset(&ws->our_addr, 0, sizeof(ws->our_addr));
|
||||
ws->our_addr_len = sizeof(ws->our_addr);
|
||||
if (getsockname(fd, (struct sockaddr*)&ws->our_addr, &ws->our_addr_len) < 0)
|
||||
ws->our_addr_len = 0;
|
||||
|
||||
if (check_if_banned(s, &ws->remote_addr, ws->remote_addr_len) != 0) {
|
||||
close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a command socket */
|
||||
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_fd);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "error creating command socket");
|
||||
close(fd);
|
||||
break;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) { /* child */
|
||||
/* close any open descriptors, and erase
|
||||
* sensitive data before running the worker
|
||||
*/
|
||||
sigprocmask(SIG_SETMASK, &sig_default_set, NULL);
|
||||
close(cmd_fd[0]);
|
||||
clear_lists(s);
|
||||
close(s->sec_mod_fd);
|
||||
close(s->sec_mod_fd_sync);
|
||||
|
||||
/* clear the cookie key */
|
||||
safe_memset(s->cookie_key, 0, sizeof(s->cookie_key));
|
||||
safe_memset(s->prev_cookie_key, 0, sizeof(s->prev_cookie_key));
|
||||
|
||||
setproctitle(PACKAGE_NAME"-worker");
|
||||
kill_on_parent_kill(SIGTERM);
|
||||
|
||||
/* write sec-mod's address */
|
||||
memcpy(&ws->secmod_addr, &s->secmod_addr, s->secmod_addr_len);
|
||||
ws->secmod_addr_len = s->secmod_addr_len;
|
||||
|
||||
ws->main_pool = main_pool;
|
||||
ws->config = s->config;
|
||||
ws->perm_config = s->perm_config;
|
||||
ws->cmd_fd = cmd_fd[1];
|
||||
ws->tun_fd = -1;
|
||||
ws->dtls_tptr.fd = -1;
|
||||
ws->conn_fd = fd;
|
||||
ws->conn_type = stype;
|
||||
ws->creds = &creds;
|
||||
|
||||
/* Drop privileges after this point */
|
||||
drop_privileges(s);
|
||||
|
||||
/* creds and config are not allocated
|
||||
* under s.
|
||||
*/
|
||||
talloc_free(s);
|
||||
#ifdef HAVE_MALLOC_TRIM
|
||||
/* try to return all the pages we've freed to
|
||||
* the operating system, to prevent the child from
|
||||
* accessing them. That's totally unreliable, so
|
||||
* sensitive data have to be overwritten anyway. */
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
vpn_server(ws);
|
||||
exit(0);
|
||||
} else if (pid == -1) {
|
||||
fork_failed:
|
||||
mslog(s, NULL, LOG_ERR, "fork failed");
|
||||
close(cmd_fd[0]);
|
||||
} else { /* parent */
|
||||
/* add_proc */
|
||||
ctmp = new_proc(s, pid, cmd_fd[0],
|
||||
&ws->remote_addr, ws->remote_addr_len,
|
||||
&ws->our_addr, ws->our_addr_len,
|
||||
ws->sid, sizeof(ws->sid));
|
||||
if (ctmp == NULL) {
|
||||
kill(pid, SIGTERM);
|
||||
goto fork_failed;
|
||||
}
|
||||
|
||||
}
|
||||
close(cmd_fd[1]);
|
||||
close(fd);
|
||||
|
||||
if (s->config->rate_limit_ms > 0)
|
||||
ms_sleep(s->config->rate_limit_ms);
|
||||
} else if (set && ltmp->sock_type == SOCK_TYPE_UDP) {
|
||||
/* connection on UDP port */
|
||||
forward_udp_to_owner(s, ltmp);
|
||||
|
||||
if (s->config->rate_limit_ms > 0)
|
||||
ms_sleep(s->config->rate_limit_ms);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for any pending commands */
|
||||
list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) {
|
||||
if (ctmp->fd >= 0 && FD_ISSET(ctmp->fd, &rd_set)) {
|
||||
ret = handle_commands(s, ctmp);
|
||||
if (ret < 0) {
|
||||
remove_proc(s, ctmp, (ret!=ERR_WORKER_TERMINATED)?RPROC_KILL:0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(s->sec_mod_fd, &rd_set)) {
|
||||
ret = handle_sec_mod_commands(s);
|
||||
if (ret < 0) { /* bad commands from sec-mod are unacceptable */
|
||||
mslog(s, NULL, LOG_ERR,
|
||||
"error in command from sec-mod");
|
||||
terminate = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for pending control commands */
|
||||
ctl_handler_run_pending(s, &rd_set, &wr_set);
|
||||
|
||||
#ifdef DEBUG_LEAKS
|
||||
talloc_report_full(s, stderr);
|
||||
#endif
|
||||
ev_io_start (loop, <mp->io);
|
||||
}
|
||||
|
||||
ev_io_set(&sec_mod_watcher, s->sec_mod_fd, EV_READ);
|
||||
ctl_handler_set_fds(s, &ctl_watcher);
|
||||
|
||||
ev_io_start (loop, &ctl_watcher);
|
||||
ev_io_start (loop, &sec_mod_watcher);
|
||||
|
||||
ev_child_init(&child_watcher, child_watcher_cb, s->sec_mod_pid, 0);
|
||||
ev_child_start (loop, &child_watcher);
|
||||
|
||||
ev_init(&maintainance_watcher, maintainance_watcher_cb);
|
||||
ev_timer_set(&maintainance_watcher, MAIN_MAINTAINANCE_TIME, MAIN_MAINTAINANCE_TIME);
|
||||
ev_timer_start(loop, &maintainance_watcher);
|
||||
|
||||
/* Main server loop */
|
||||
ev_run (loop, 0);
|
||||
|
||||
/* try to clean-up everything allocated to ease checks
|
||||
* for memory leaks.
|
||||
*/
|
||||
remove(s->full_socket_file);
|
||||
remove(s->perm_config->occtl_socket_file);
|
||||
remove_pid_file();
|
||||
|
||||
clear_lists(s);
|
||||
tls_global_deinit(s->creds);
|
||||
clear_cfg(s->perm_config);
|
||||
talloc_free(s->perm_config);
|
||||
talloc_free(s->main_pool);
|
||||
closelog();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
21
src/main.h
21
src/main.h
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Nikos Mavrogiannopoulos
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*
|
||||
* Author: Nikos Mavrogiannopoulos
|
||||
*
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <common.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/uio.h>
|
||||
#include <ev.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
# include <limits.h>
|
||||
@@ -42,6 +44,11 @@
|
||||
extern int saved_argc;
|
||||
extern char **saved_argv;
|
||||
|
||||
extern struct ev_loop *loop;
|
||||
extern ev_timer maintainance_watcher;
|
||||
|
||||
#define MAIN_MAINTAINANCE_TIME (900)
|
||||
|
||||
extern sigset_t sig_default_set;
|
||||
int cmd_parser (void *pool, int argc, char **argv, struct perm_cfg_st** config);
|
||||
void reload_cfg_file(void *pool, struct perm_cfg_st* config, unsigned archive);
|
||||
@@ -50,10 +57,8 @@ void clear_cfg(struct perm_cfg_st* config);
|
||||
void write_pid_file(void);
|
||||
void remove_pid_file(void);
|
||||
|
||||
/* set to 1 to start cleaning up cookies, sessions etc. */
|
||||
extern unsigned int need_maintenance;
|
||||
|
||||
struct listener_st {
|
||||
ev_io io;
|
||||
struct list_node list;
|
||||
int fd;
|
||||
sock_type_t sock_type;
|
||||
@@ -70,6 +75,9 @@ struct listen_list_st {
|
||||
};
|
||||
|
||||
struct script_wait_st {
|
||||
/* so that this structure can behave as ev_child */
|
||||
struct ev_child ev_child;
|
||||
|
||||
struct list_node list;
|
||||
|
||||
pid_t pid;
|
||||
@@ -88,6 +96,10 @@ enum {
|
||||
/* Each worker process maps to a unique proc_st structure.
|
||||
*/
|
||||
typedef struct proc_st {
|
||||
/* This is first so this structure can behave as an ev_io */
|
||||
struct ev_io io;
|
||||
struct ev_child ev_child;
|
||||
|
||||
struct list_node list;
|
||||
int fd; /* the command file descriptor */
|
||||
pid_t pid;
|
||||
@@ -208,6 +220,9 @@ typedef struct main_server_st {
|
||||
|
||||
void * auth_extra;
|
||||
|
||||
/* This one is on worker pool */
|
||||
struct worker_st *ws;
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
void * ctl_ctx;
|
||||
#else
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
# define SCRIPT_LIST_H
|
||||
|
||||
#include <main.h>
|
||||
#include <ev.h>
|
||||
|
||||
void script_child_watcher_cb(struct ev_loop *loop, ev_child *w, int revents);
|
||||
|
||||
inline static
|
||||
void add_to_script_list(main_server_st* s, pid_t pid, unsigned up, struct proc_st* proc)
|
||||
@@ -35,7 +38,10 @@ struct script_wait_st *stmp;
|
||||
stmp->proc = proc;
|
||||
stmp->pid = pid;
|
||||
stmp->up = up;
|
||||
|
||||
|
||||
ev_child_init(&stmp->ev_child, script_child_watcher_cb, pid, 0);
|
||||
ev_child_start(loop, &stmp->ev_child);
|
||||
|
||||
list_add(&s->script_list.head, &(stmp->list));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Clone from the Fedora 22 image
|
||||
FROM fedora:23
|
||||
|
||||
RUN yum install -y krb5-libs krb5-workstation
|
||||
RUN yum install -y krb5-libs krb5-workstation libev
|
||||
RUN yum install -y gnutls gnutls-utils iproute systemd
|
||||
RUN yum install -y bash net-tools nuttcp iputils openssh-clients passwd
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Clone from the Fedora 22 image
|
||||
FROM fedora:23
|
||||
|
||||
RUN yum install -y krb5-libs krb5-server krb5-workstation
|
||||
RUN yum install -y krb5-libs krb5-server krb5-workstation libev
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash net-tools nuttcp iputils openssh-clients
|
||||
RUN yum install -y libnl3 libtalloc
|
||||
RUN yum install -y libnl3 libtalloc libev
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
RUN yum install -y freeradius-client
|
||||
RUN yum install -y pam_krb5
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM debian:testing
|
||||
RUN apt-get update
|
||||
|
||||
RUN apt-get install -y libgnutls-deb0-28 libprotobuf-c1 liboath0
|
||||
RUN apt-get install -y libgnutls-deb0-28 libprotobuf-c1 liboath0 libev4
|
||||
RUN apt-get install -y libwrap0 libpam0g libseccomp2 libdbus-1-3 libreadline5 libnl-route-3-200
|
||||
RUN apt-get install -y libhttp-parser2.1 libpcl1 libopts25
|
||||
RUN apt-get install -y libsystemd0 valgrind nuttcp openssh-server bash
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM debian:testing
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y libgnutls-deb0-28 libprotobuf-c1 liboath0
|
||||
RUN apt-get install -y libgnutls-deb0-28 libprotobuf-c1 liboath0 libev4
|
||||
RUN apt-get install -y libwrap0 libpam0g libseccomp2 libdbus-1-3 libreadline5 libnl-route-3-200
|
||||
RUN apt-get install -y libhttp-parser2.1 libpcl1 libopts25
|
||||
RUN apt-get install -y libsystemd0 valgrind nuttcp openssh-server bash
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM debian:testing
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y libgnutls-deb0-28 liboath0 libprotobuf-c1
|
||||
RUN apt-get install -y libgnutls-deb0-28 liboath0 libprotobuf-c1 libev4
|
||||
RUN apt-get install -y libwrap0 libpam0g libseccomp2 libdbus-1-3 libreadline5 libnl-route-3-200
|
||||
RUN apt-get install -y libhttp-parser2.1 libpcl1 libopts25
|
||||
RUN apt-get install -y libsystemd0 valgrind nuttcp openssh-server bash
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM debian:testing
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y libgnutls-deb0-28 libprotobuf-c1 liboath0
|
||||
RUN apt-get install -y libgnutls-deb0-28 libprotobuf-c1 liboath0 libev4
|
||||
RUN apt-get install -y libwrap0 libpam0g libseccomp2 libdbus-1-3 libreadline5 libnl-route-3-200
|
||||
RUN apt-get install -y libhttp-parser2.1 libpcl1 libopts25
|
||||
RUN apt-get install -y libsystemd0 valgrind nuttcp openssh-server bash
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM debian:testing
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y haproxy libgnutls-deb0-28 libprotobuf-c1 liboath0
|
||||
RUN apt-get install -y haproxy libgnutls-deb0-28 libprotobuf-c1 liboath0 libev4
|
||||
RUN apt-get install -y libwrap0 libpam0g libseccomp2 libdbus-1-3 libreadline5 libnl-route-3-200
|
||||
RUN apt-get install -y libhttp-parser2.1 libpcl1 libopts25 autogen
|
||||
RUN apt-get install -y libsystemd0 valgrind nuttcp openssh-server bash
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM fedora:23
|
||||
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y libnl3 libtalloc freeradius-client lz4 radcli liboauth oathtool procps-ng iputils krb5-libs less bash openssh-server nuttcp
|
||||
RUN yum install -y libnl3 libtalloc freeradius-client lz4 radcli liboauth oathtool procps-ng iputils krb5-libs less bash openssh-server nuttcp libev
|
||||
RUN systemctl enable sshd
|
||||
RUN sed 's/PermitRootLogin without-password/PermitRootLogin yes/g' -i /etc/ssh/sshd_config
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM fedora:23
|
||||
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN yum install -y libnl3 libtalloc
|
||||
RUN yum install -y libnl3 libtalloc libev
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
RUN yum install -y pam
|
||||
RUN yum install -y freeradius-client
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM fedora:23
|
||||
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN yum install -y libnl3 libtalloc
|
||||
RUN yum install -y libnl3 libtalloc libev
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
RUN yum install -y pam
|
||||
RUN yum install -y freeradius-client
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM fedora:23
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN systemctl enable sshd
|
||||
RUN yum install -y libnl3 libtalloc haproxy
|
||||
RUN yum install -y libnl3 libtalloc haproxy libev
|
||||
RUN yum install -y freeradius-client
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
RUN yum install -y krb5-libs less
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM fedora:23
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN systemctl enable sshd
|
||||
RUN yum install -y libnl3 libtalloc haproxy
|
||||
RUN yum install -y libnl3 libtalloc haproxy libev
|
||||
RUN yum install -y freeradius-client
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
RUN yum install -y krb5-libs less
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM fedora:23
|
||||
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN yum install -y libnl3 libtalloc
|
||||
RUN yum install -y libnl3 libtalloc libev
|
||||
RUN yum install -y lz4 radcli liboauth oathtool
|
||||
RUN yum install -y freeradius-client
|
||||
RUN yum install -y freeradius
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM fedora:23
|
||||
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN yum install -y libnl3 libtalloc
|
||||
RUN yum install -y libnl3 libtalloc libev
|
||||
RUN yum install -y lz4 radcli liboauth oathtool
|
||||
RUN yum install -y freeradius-client
|
||||
RUN yum install -y freeradius less
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM fedora:23
|
||||
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN yum install -y libnl3 libtalloc
|
||||
RUN yum install -y libnl3 libtalloc libev
|
||||
RUN yum install -y freeradius-client
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
RUN yum install -y krb5-libs less
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM fedora:23
|
||||
RUN yum install -y gnutls gnutls-utils protobuf-c iproute pcllib http-parser tcp_wrappers pam systemd libseccomp
|
||||
RUN yum install -y bash openssh-server nuttcp
|
||||
RUN systemctl enable sshd
|
||||
RUN yum install -y libnl3 libtalloc haproxy
|
||||
RUN yum install -y libnl3 libtalloc haproxy libev
|
||||
RUN yum install -y freeradius-client
|
||||
RUN yum install -y lz4 radcli liboauth oathtool procps-ng iputils
|
||||
RUN yum install -y krb5-libs less
|
||||
|
||||
Reference in New Issue
Block a user