mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
updates in unix socket creation
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include <gnutls/crypto.h>
|
||||
#include <tlslib.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <cloexec.h>
|
||||
#include "ipc.h"
|
||||
#include "setproctitle.h"
|
||||
@@ -379,59 +380,24 @@ struct banned_st *btmp;
|
||||
|
||||
void run_sec_mod(main_server_st * s)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int sd, e, ret;
|
||||
int e;
|
||||
pid_t pid;
|
||||
|
||||
sa.sun_family = AF_UNIX;
|
||||
|
||||
/* make socket name */
|
||||
snprintf(s->socket_file, sizeof(s->socket_file), "%s.%u", s->config->socket_file_prefix, (unsigned)getpid());
|
||||
snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", s->socket_file);
|
||||
|
||||
remove(s->socket_file);
|
||||
|
||||
sd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sd == -1) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "could not create socket '%s': %s", s->socket_file, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = bind(sd, (struct sockaddr *)&sa, sizeof(sa));
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "could not bind socket '%s': %s", s->socket_file, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = chown(sa.sun_path, s->config->uid, s->config->gid);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "could not chown socket '%s': %s", s->socket_file, strerror(e));
|
||||
}
|
||||
|
||||
ret = listen(sd, 1024);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "could not listen to socket '%s': %s", s->socket_file, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
set_cloexec_flag (sd, 1);
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) { /* child */
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||
setproctitle(PACKAGE_NAME"-secmod");
|
||||
|
||||
sec_mod_server(s->config, sd);
|
||||
sec_mod_server(s->config, s->socket_file);
|
||||
exit(0);
|
||||
} else if (pid > 0) { /* parent */
|
||||
close(sd);
|
||||
s->sec_mod_pid = pid;
|
||||
} else {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "error in fork(): %s", strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
41
src/main.c
41
src/main.c
@@ -32,6 +32,7 @@
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <cloexec.h>
|
||||
#include <script-list.h>
|
||||
|
||||
@@ -304,6 +305,7 @@ static void remove_proc(main_server_st* s, struct proc_st *proc, unsigned k)
|
||||
proc->lease->in_use = 0;
|
||||
list_del(&proc->list);
|
||||
free(proc);
|
||||
s->active_clients--;
|
||||
}
|
||||
|
||||
static void cleanup_children(main_server_st *s)
|
||||
@@ -367,25 +369,6 @@ static void drop_privileges(main_server_st* s)
|
||||
}
|
||||
}
|
||||
|
||||
rl.rlim_cur = 0;
|
||||
rl.rlim_max = 0;
|
||||
ret = setrlimit(RLIMIT_NPROC, &rl);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "cannot enforce NPROC limit: %s\n",
|
||||
strerror(e));
|
||||
}
|
||||
|
||||
#define MAX_WORKER_MEM (128*1024)
|
||||
rl.rlim_cur = MAX_WORKER_MEM;
|
||||
rl.rlim_max = MAX_WORKER_MEM;
|
||||
ret = setrlimit(RLIMIT_AS, &rl);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "cannot enforce AS limit: %s\n",
|
||||
strerror(e));
|
||||
}
|
||||
|
||||
if (s->config->gid != -1 && (getgid() == 0 || getegid() == 0)) {
|
||||
ret = setgid(s->config->gid);
|
||||
if (ret < 0) {
|
||||
@@ -407,6 +390,25 @@ static void drop_privileges(main_server_st* s)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rl.rlim_cur = 0;
|
||||
rl.rlim_max = 0;
|
||||
ret = setrlimit(RLIMIT_NPROC, &rl);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "cannot enforce NPROC limit: %s\n",
|
||||
strerror(e));
|
||||
}
|
||||
|
||||
#define MAX_WORKER_MEM (4*1024*1024)
|
||||
rl.rlim_cur = MAX_WORKER_MEM;
|
||||
rl.rlim_max = MAX_WORKER_MEM;
|
||||
ret = setrlimit(RLIMIT_AS, &rl);
|
||||
if (ret < 0) {
|
||||
e = errno;
|
||||
mslog(s, NULL, LOG_ERR, "cannot enforce AS limit: %s\n",
|
||||
strerror(e));
|
||||
}
|
||||
}
|
||||
|
||||
/* clears the server llist and clist. To be used after fork().
|
||||
@@ -797,6 +799,7 @@ int main(int argc, char** argv)
|
||||
erase_cookies(&s);
|
||||
|
||||
setproctitle(PACKAGE_NAME"-worker");
|
||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||
|
||||
ws.config = &config;
|
||||
ws.cmd_fd = cmd_fd[1];
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
@@ -147,7 +148,7 @@ int fd, ret;
|
||||
}
|
||||
|
||||
void
|
||||
sec_mod_server(struct cfg_st* config, int sd)
|
||||
sec_mod_server(struct cfg_st* config, const char* socket_file)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
socklen_t sa_len;
|
||||
@@ -160,6 +161,8 @@ struct pin_st pins;
|
||||
gnutls_datum_t data, out;
|
||||
uint16_t length;
|
||||
struct iovec iov[2];
|
||||
int sd;
|
||||
int mask;
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, SIG_DFL);
|
||||
@@ -178,7 +181,41 @@ struct iovec iov[2];
|
||||
syslog(LOG_ERR, "error in memory allocation");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sun_family = AF_UNIX;
|
||||
snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", socket_file);
|
||||
remove(socket_file);
|
||||
|
||||
sd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sd == -1) {
|
||||
e = errno;
|
||||
syslog(LOG_ERR, "could not create socket '%s': %s", socket_file, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mask = umask(066);
|
||||
ret = bind(sd, (struct sockaddr *)&sa, SUN_LEN(&sa));
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
syslog(LOG_ERR, "could not bind socket '%s': %s", socket_file, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
umask(mask);
|
||||
|
||||
ret = chown(socket_file, config->uid, config->gid);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
syslog(LOG_ERR, "could not chown socket '%s': %s", socket_file, strerror(e));
|
||||
}
|
||||
|
||||
ret = listen(sd, 1024);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
syslog(LOG_ERR, "could not listen to socket '%s': %s", socket_file, strerror(e));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = load_pins(config, &pins);
|
||||
if (ret < 0) {
|
||||
syslog(LOG_ERR, "error loading PIN files");
|
||||
@@ -215,6 +252,7 @@ struct iovec iov[2];
|
||||
}
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "sec-mod initialized (socket: %s)", socket_file);
|
||||
for (;;) {
|
||||
sa_len = sizeof(sa);
|
||||
cfd = accept(sd, (struct sockaddr *)&sa, &sa_len);
|
||||
@@ -226,7 +264,9 @@ struct iovec iov[2];
|
||||
|
||||
/* read request */
|
||||
ret = recv(cfd, buffer, buffer_size, 0);
|
||||
if (ret <= 2) {
|
||||
if (ret == 0)
|
||||
goto cont;
|
||||
else if (ret <= 2) {
|
||||
e = errno;
|
||||
syslog(LOG_ERR, "error receiving sec-mod data: %s", strerror(e));
|
||||
goto cont;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef SEC_MOD_H
|
||||
|
||||
void sec_mod_server(struct cfg_st* config, int sd);
|
||||
void sec_mod_server(struct cfg_st* config, const char* file);
|
||||
|
||||
#endif
|
||||
|
||||
40
src/tlslib.c
40
src/tlslib.c
@@ -192,7 +192,7 @@ static int verify_certificate_cb(gnutls_session_t session)
|
||||
|
||||
ws = gnutls_session_get_ptr(session);
|
||||
if (ws == NULL) {
|
||||
syslog(LOG_ERR, "%s:%d: could not obtain worker state.", __func__, __LINE__);
|
||||
syslog(LOG_ERR, "%s:%d: could not obtain worker state", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ static int verify_certificate_cb(gnutls_session_t session)
|
||||
|
||||
gnutls_free(out.data);
|
||||
#else
|
||||
oclog(ws, LOG_INFO, "client certificate verification failed.");
|
||||
oclog(ws, LOG_INFO, "client certificate verification failed");
|
||||
#endif
|
||||
|
||||
goto fail;
|
||||
@@ -328,6 +328,7 @@ int ret;
|
||||
struct key_cb_data {
|
||||
unsigned idx; /* the index of the key */
|
||||
struct sockaddr_un sa;
|
||||
unsigned sa_len;
|
||||
};
|
||||
|
||||
static
|
||||
@@ -346,22 +347,22 @@ int key_cb_common_func (gnutls_privkey_t key, void* userdata, const gnutls_datum
|
||||
if (sd == -1) {
|
||||
e = errno;
|
||||
syslog(LOG_ERR, "error opening socket: %s", strerror(e));
|
||||
return -1;
|
||||
return GNUTLS_E_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
ret = connect(sd, (struct sockaddr *)&cdata->sa, sizeof(cdata->sa));
|
||||
ret = connect(sd, (struct sockaddr *)&cdata->sa, cdata->sa_len);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
syslog(LOG_ERR, "error connecting to sec-mod socket '%s': %s",
|
||||
cdata->sa.sun_path, strerror(e));
|
||||
return -1;
|
||||
return GNUTLS_E_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
header[0] = cdata->idx;
|
||||
header[1] = type;
|
||||
|
||||
iov[0].iov_base = header;
|
||||
iov[0].iov_len = sizeof(header);
|
||||
iov[0].iov_len = 2;
|
||||
iov[1].iov_base = raw_data->data;
|
||||
iov[1].iov_len = raw_data->size;
|
||||
|
||||
@@ -401,7 +402,7 @@ int key_cb_common_func (gnutls_privkey_t key, void* userdata, const gnutls_datum
|
||||
error:
|
||||
close(sd);
|
||||
gnutls_free(output->data);
|
||||
return -1;
|
||||
return GNUTLS_E_INTERNAL_ERROR;
|
||||
|
||||
}
|
||||
|
||||
@@ -445,8 +446,8 @@ struct key_cb_data * cdata;
|
||||
} else {
|
||||
ret = gnutls_load_file(s->config->cert[i], &data);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "error loading file '%s'", s->config->key[i]);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
mslog(s, NULL, LOG_ERR, "error loading file '%s'", s->config->cert[i]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pcert_list_size = 8;
|
||||
@@ -473,8 +474,11 @@ struct key_cb_data * cdata;
|
||||
}
|
||||
|
||||
cdata->idx = i;
|
||||
|
||||
memset(&cdata->sa, 0, sizeof(cdata->sa));
|
||||
cdata->sa.sun_family = AF_UNIX;
|
||||
snprintf(cdata->sa.sun_path, sizeof(cdata->sa.sun_path), "%s", s->socket_file);
|
||||
cdata->sa_len = SUN_LEN(&cdata->sa);
|
||||
|
||||
/* load the private key */
|
||||
ret = gnutls_privkey_import_ext2(key, gnutls_pubkey_get_pk_algorithm(pcert_list[0].pubkey, NULL),
|
||||
@@ -510,7 +514,7 @@ const char* perr;
|
||||
set_dh_params(s, s->creds.xcred);
|
||||
|
||||
if (s->config->key_size == 0 || s->config->cert_size == 0) {
|
||||
mslog(s, NULL, LOG_ERR, "no certificate or key files were specified.\n");
|
||||
mslog(s, NULL, LOG_ERR, "no certificate or key files were specified");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -518,7 +522,7 @@ const char* perr;
|
||||
|
||||
ret = load_key_files(s);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "error loading the certificate or key file\n");
|
||||
mslog(s, NULL, LOG_ERR, "error loading the certificate or key file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -529,12 +533,12 @@ const char* perr;
|
||||
s->config->ca,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "error setting the CA (%s) file.\n",
|
||||
mslog(s, NULL, LOG_ERR, "error setting the CA (%s) file",
|
||||
s->config->ca);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mslog(s, NULL, LOG_INFO, "processed %d CA certificate(s).\n", ret);
|
||||
mslog(s, NULL, LOG_INFO, "processed %d CA certificate(s)", ret);
|
||||
}
|
||||
|
||||
if (s->config->crl != NULL) {
|
||||
@@ -543,7 +547,7 @@ const char* perr;
|
||||
s->config->crl,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "error setting the CRL (%s) file.\n",
|
||||
mslog(s, NULL, LOG_ERR, "error setting the CRL (%s) file",
|
||||
s->config->crl);
|
||||
exit(1);
|
||||
}
|
||||
@@ -555,7 +559,7 @@ const char* perr;
|
||||
|
||||
ret = gnutls_priority_init(&s->creds.cprio, s->config->priorities, &perr);
|
||||
if (ret == GNUTLS_E_PARSING_ERROR)
|
||||
mslog(s, NULL, LOG_ERR, "error in TLS priority string: %s\n", perr);
|
||||
mslog(s, NULL, LOG_ERR, "error in TLS priority string: %s", perr);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
|
||||
ret = gnutls_session_ticket_key_generate(&s->creds.ticket_key);
|
||||
@@ -619,14 +623,14 @@ gnutls_x509_crt_t crt;
|
||||
gnutls_free(data.data);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error calculating hash of '%s': %s\n", file, gnutls_strerror(ret));
|
||||
fprintf(stderr, "error calculating hash of '%s': %s", file, gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
size_t ret_size = sizeof(digest)*2+1;
|
||||
retval = malloc(ret_size);
|
||||
if (retval == NULL) {
|
||||
fprintf(stderr, "Memory error\n");
|
||||
fprintf(stderr, "memory error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -634,7 +638,7 @@ gnutls_x509_crt_t crt;
|
||||
data.size = sizeof(digest);
|
||||
ret = gnutls_hex_encode(&data, retval, &ret_size);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error in hex encode: %s\n", gnutls_strerror(ret));
|
||||
fprintf(stderr, "error in hex encode: %s", gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
retval[ret_size] = 0;
|
||||
|
||||
Reference in New Issue
Block a user