updates in unix socket creation

This commit is contained in:
Nikos Mavrogiannopoulos
2013-03-16 21:27:58 +01:00
parent f941e6af69
commit 82df00f0b0
5 changed files with 91 additions and 78 deletions

View File

@@ -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);
}
}

View File

@@ -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];

View File

@@ -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;

View File

@@ -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

View File

@@ -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;