Updated code to follow with kernel coding style

Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This commit is contained in:
Nikos Mavrogiannopoulos
2024-12-01 15:16:53 +01:00
parent f5b85f130a
commit 78c65b5adf
142 changed files with 9273 additions and 6911 deletions

View File

@@ -38,21 +38,22 @@
#include "auth/pam.h"
static int ocserv_conv(int msg_size, const struct pam_message **msg,
struct pam_response **resp, void *uptr)
struct pam_response **resp, void *uptr)
{
*resp = NULL;
return PAM_SUCCESS;
}
static int pam_acct_open_session(void *vctx, unsigned auth_method, const struct common_acct_info_st *ai, const void *sid, unsigned sid_size)
static int pam_acct_open_session(void *vctx, unsigned int auth_method,
const struct common_acct_info_st *ai,
const void *sid, unsigned int sid_size)
{
int pret;
pam_handle_t *ph;
struct pam_conv dc;
int pret;
pam_handle_t *ph;
struct pam_conv dc;
if (ai->username[0] == 0) {
oc_syslog(LOG_NOTICE,
"PAM-acct: no username present");
oc_syslog(LOG_NOTICE, "PAM-acct: no username present");
return ERR_AUTH_FAIL;
}
@@ -60,13 +61,15 @@ struct pam_conv dc;
dc.appdata_ptr = NULL;
pret = pam_start(PACKAGE, ai->username, &dc, &ph);
if (pret != PAM_SUCCESS) {
oc_syslog(LOG_NOTICE, "PAM-acct init: %s", pam_strerror(ph, pret));
oc_syslog(LOG_NOTICE, "PAM-acct init: %s",
pam_strerror(ph, pret));
goto fail1;
}
pret = pam_acct_mgmt(ph, PAM_DISALLOW_NULL_AUTHTOK);
if (pret != PAM_SUCCESS) {
oc_syslog(LOG_INFO, "PAM-acct account error: %s", pam_strerror(ph, pret));
oc_syslog(LOG_INFO, "PAM-acct account error: %s",
pam_strerror(ph, pret));
goto fail2;
}
@@ -77,18 +80,19 @@ fail2:
pam_end(ph, pret);
fail1:
return -1;
}
static void pam_acct_close_session(void *vctx, unsigned auth_method, const struct common_acct_info_st *ai, stats_st *stats, unsigned status)
static void pam_acct_close_session(void *vctx, unsigned int auth_method,
const struct common_acct_info_st *ai,
stats_st *stats, unsigned int status)
{
}
const struct acct_mod_st pam_acct_funcs = {
.type = ACCT_TYPE_PAM,
.auth_types = ALL_AUTH_TYPES,
.open_session = pam_acct_open_session,
.close_session = pam_acct_close_session,
.type = ACCT_TYPE_PAM,
.auth_types = ALL_AUTH_TYPES,
.open_session = pam_acct_open_session,
.close_session = pam_acct_close_session,
};
#endif

View File

@@ -33,9 +33,9 @@
#ifdef HAVE_RADIUS
#ifdef LEGACY_RADIUS
# include <freeradius-client.h>
#include <freeradius-client.h>
#else
# include <radcli/radcli.h>
#include <radcli/radcli.h>
#endif
#include <sec-mod-acct.h>
@@ -61,19 +61,21 @@ static void acct_radius_vhost_init(void **_vctx, void *pool, void *additional)
}
if (config->nas_identifier) {
strlcpy(vctx->nas_identifier, config->nas_identifier, sizeof(vctx->nas_identifier));
strlcpy(vctx->nas_identifier, config->nas_identifier,
sizeof(vctx->nas_identifier));
} else {
vctx->nas_identifier[0] = 0;
}
if (rc_read_dictionary(vctx->rh, rc_conf_str(vctx->rh, "dictionary")) != 0) {
if (rc_read_dictionary(vctx->rh, rc_conf_str(vctx->rh, "dictionary")) !=
0) {
fprintf(stderr, "error reading the radius dictionary\n");
exit(EXIT_FAILURE);
}
*_vctx = vctx;
return;
fail:
fail:
fprintf(stderr, "radius initialization error\n");
exit(EXIT_FAILURE);
}
@@ -108,12 +110,15 @@ static void append_stats(rc_handle *rh, VALUE_PAIR **send, stats_st *stats)
rc_avpair_add(rh, send, PW_ACCT_OUTPUT_GIGAWORDS, &uout, -1, 0);
}
static void append_acct_standard(struct radius_vhost_ctx *vctx, rc_handle *rh, const common_acct_info_st *ai, VALUE_PAIR **send)
static void append_acct_standard(struct radius_vhost_ctx *vctx, rc_handle *rh,
const common_acct_info_st *ai,
VALUE_PAIR **send)
{
uint32_t i;
if (vctx->nas_identifier[0] != 0) {
rc_avpair_add(rh, send, PW_NAS_IDENTIFIER, vctx->nas_identifier, -1, 0);
rc_avpair_add(rh, send, PW_NAS_IDENTIFIER, vctx->nas_identifier,
-1, 0);
}
if (ai->our_ip[0] != 0) {
@@ -122,9 +127,11 @@ static void append_acct_standard(struct radius_vhost_ctx *vctx, rc_handle *rh, c
if (inet_pton(AF_INET, ai->our_ip, &in) != 0) {
in.s_addr = ntohl(in.s_addr);
rc_avpair_add(rh, send, PW_NAS_IP_ADDRESS, (char*)&in, sizeof(struct in_addr), 0);
rc_avpair_add(rh, send, PW_NAS_IP_ADDRESS, (char *)&in,
sizeof(struct in_addr), 0);
} else if (inet_pton(AF_INET6, ai->our_ip, &in6) != 0) {
rc_avpair_add(rh, send, PW_NAS_IPV6_ADDRESS, (char*)&in6, sizeof(struct in6_addr), 0);
rc_avpair_add(rh, send, PW_NAS_IPV6_ADDRESS,
(char *)&in6, sizeof(struct in6_addr), 0);
}
}
@@ -138,9 +145,11 @@ static void append_acct_standard(struct radius_vhost_ctx *vctx, rc_handle *rh, c
if (ai->ipv4[0] != 0) {
struct in_addr in;
if (inet_pton(AF_INET, ai->ipv4, &in) == 1) {
in.s_addr = ntohl(in.s_addr);
if (rc_avpair_add(rh, send, PW_FRAMED_IP_ADDRESS, &in, sizeof(in), 0) == NULL) {
if (rc_avpair_add(rh, send, PW_FRAMED_IP_ADDRESS, &in,
sizeof(in), 0) == NULL) {
return;
}
}
@@ -149,8 +158,10 @@ static void append_acct_standard(struct radius_vhost_ctx *vctx, rc_handle *rh, c
#ifndef LEGACY_RADIUS /* bug in freeradius-client */
if (ai->ipv6[0] != 0) {
struct in6_addr in;
if (inet_pton(AF_INET6, ai->ipv6, &in) == 1) {
if (rc_avpair_add(rh, send, PW_FRAMED_IPV6_ADDRESS, &in, sizeof(in), 0) == NULL) {
if (rc_avpair_add(rh, send, PW_FRAMED_IPV6_ADDRESS, &in,
sizeof(in), 0) == NULL) {
return;
}
}
@@ -164,7 +175,9 @@ static void append_acct_standard(struct radius_vhost_ctx *vctx, rc_handle *rh, c
rc_avpair_add(rh, send, PW_ACCT_AUTHENTIC, &i, -1, 0);
}
static void radius_acct_session_stats(void *_vctx, unsigned auth_method, const common_acct_info_st *ai, stats_st *stats)
static void radius_acct_session_stats(void *_vctx, unsigned int auth_method,
const common_acct_info_st *ai,
stats_st *stats)
{
int ret;
uint32_t status_type;
@@ -175,7 +188,8 @@ static void radius_acct_session_stats(void *_vctx, unsigned auth_method, const c
oc_syslog(LOG_DEBUG, "radius-auth: sending session interim update");
if (rc_avpair_add(vctx->rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) {
if (rc_avpair_add(vctx->rh, &send, PW_ACCT_STATUS_TYPE, &status_type,
-1, 0) == NULL) {
goto cleanup;
}
@@ -188,15 +202,18 @@ static void radius_acct_session_stats(void *_vctx, unsigned auth_method, const c
rc_avpair_free(recvd);
if (ret != OK_RC) {
oc_syslog(LOG_NOTICE, "radius-auth: radius_open_session: %d", ret);
oc_syslog(LOG_NOTICE, "radius-auth: radius_open_session: %d",
ret);
goto cleanup;
}
cleanup:
cleanup:
rc_avpair_free(send);
}
static int radius_acct_open_session(void *_vctx, unsigned auth_method, const common_acct_info_st *ai, const void *sid, unsigned sid_size)
static int radius_acct_open_session(void *_vctx, unsigned int auth_method,
const common_acct_info_st *ai,
const void *sid, unsigned int sid_size)
{
int ret;
uint32_t status_type;
@@ -212,13 +229,15 @@ static int radius_acct_open_session(void *_vctx, unsigned auth_method, const com
oc_syslog(LOG_DEBUG, "radius-auth: opening session %s", ai->safe_id);
if (rc_avpair_add(vctx->rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) {
if (rc_avpair_add(vctx->rh, &send, PW_ACCT_STATUS_TYPE, &status_type,
-1, 0) == NULL) {
ret = -1;
goto cleanup;
}
if (ai->user_agent[0] != 0) {
rc_avpair_add(vctx->rh, &send, PW_CONNECT_INFO, ai->user_agent, -1, 0);
rc_avpair_add(vctx->rh, &send, PW_CONNECT_INFO, ai->user_agent,
-1, 0);
}
append_acct_standard(vctx, vctx->rh, ai, &send);
@@ -229,18 +248,22 @@ static int radius_acct_open_session(void *_vctx, unsigned auth_method, const com
rc_avpair_free(recvd);
if (ret != OK_RC) {
oc_syslog(LOG_NOTICE, "radius-auth: radius_open_session: %d", ret);
oc_syslog(LOG_NOTICE, "radius-auth: radius_open_session: %d",
ret);
ret = -1;
goto cleanup;
}
ret = 0;
cleanup:
cleanup:
rc_avpair_free(send);
return ret;
}
static void radius_acct_close_session(void *_vctx, unsigned auth_method, const common_acct_info_st *ai, stats_st *stats, unsigned discon_reason)
static void radius_acct_close_session(void *_vctx, unsigned int auth_method,
const common_acct_info_st *ai,
stats_st *stats,
unsigned int discon_reason)
{
int ret;
uint32_t status_type;
@@ -250,7 +273,8 @@ static void radius_acct_close_session(void *_vctx, unsigned auth_method, const c
status_type = PW_STATUS_STOP;
oc_syslog(LOG_DEBUG, "radius-auth: closing session");
if (rc_avpair_add(vctx->rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL)
if (rc_avpair_add(vctx->rh, &send, PW_ACCT_STATUS_TYPE, &status_type,
-1, 0) == NULL)
return;
if (discon_reason == REASON_USER_DISCONNECT)
@@ -277,11 +301,12 @@ static void radius_acct_close_session(void *_vctx, unsigned auth_method, const c
rc_avpair_free(recvd);
if (ret != OK_RC) {
oc_syslog(LOG_INFO, "radius-auth: radius_close_session: %d", ret);
oc_syslog(LOG_INFO, "radius-auth: radius_close_session: %d",
ret);
goto cleanup;
}
cleanup:
cleanup:
rc_avpair_free(send);
}

View File

@@ -35,10 +35,10 @@
int get_user_auth_group(const char *username, const char *suggested,
char *groupname, int groupname_size)
{
struct passwd * pwd;
struct group *grp;
int ret;
unsigned found;
struct passwd *pwd;
struct group *grp;
int ret;
unsigned int found;
groupname[0] = 0;
@@ -47,61 +47,69 @@ unsigned found;
if (suggested != NULL) {
gid_t groups[MAX_GROUPS];
int ngroups = ARRAY_SIZE(groups);
unsigned i;
unsigned int i;
ret = getgrouplist(username, pwd->pw_gid, groups, &ngroups);
ret = getgrouplist(username, pwd->pw_gid, groups,
&ngroups);
if (ret <= 0) {
return 0;
}
found = 0;
for (i=0;i<ngroups;i++) {
for (i = 0; i < ngroups; i++) {
grp = getgrgid(groups[i]);
if (grp != NULL && strcmp(suggested, grp->gr_name) == 0) {
strlcpy(groupname, grp->gr_name, groupname_size);
if (grp != NULL &&
strcmp(suggested, grp->gr_name) == 0) {
strlcpy(groupname, grp->gr_name,
groupname_size);
found = 1;
break;
}
}
if (found == 0) {
oc_syslog(LOG_NOTICE,
"user '%s' requested group '%s' but is not a member",
username, suggested);
oc_syslog(
LOG_NOTICE,
"user '%s' requested group '%s' but is not a member",
username, suggested);
return -1;
}
} else {
struct group* grp = getgrgid(pwd->pw_gid);
struct group *grp = getgrgid(pwd->pw_gid);
if (grp != NULL)
strlcpy(groupname, grp->gr_name, groupname_size);
strlcpy(groupname, grp->gr_name,
groupname_size);
}
}
return 0;
}
void unix_group_list(void *pool, unsigned gid_min, char ***groupname, unsigned *groupname_size)
void unix_group_list(void *pool, unsigned int gid_min, char ***groupname,
unsigned int *groupname_size)
{
struct group *grp;
setgrent();
*groupname_size = 0;
*groupname = talloc_size(pool, sizeof(char*)*MAX_GROUPS);
*groupname = talloc_size(pool, sizeof(char *) * MAX_GROUPS);
if (*groupname == NULL) {
goto exit;
}
while ((grp = getgrent()) != NULL && (*groupname_size) < MAX_GROUPS) {
if (grp->gr_gid >= gid_min) {
(*groupname)[(*groupname_size)] = talloc_strdup(*groupname, grp->gr_name);
(*groupname)[(*groupname_size)] =
talloc_strdup(*groupname, grp->gr_name);
if ((*groupname)[(*groupname_size)] == NULL)
break;
(*groupname_size)++;
}
}
exit:
exit:
endgrent();
}

View File

@@ -1,16 +1,17 @@
#ifndef OC_AUTH_UNIX_H
# define OC_AUTH_UNIX_H
#define OC_AUTH_UNIX_H
# include <config.h>
#include <config.h>
#if defined(HAVE_GSSAPI) || defined(HAVE_PAM)
# define HAVE_GET_USER_AUTH_GROUP
#define HAVE_GET_USER_AUTH_GROUP
#endif
#ifdef HAVE_GET_USER_AUTH_GROUP
int get_user_auth_group(const char *username, const char *suggested,
char *groupname, int groupname_size);
void unix_group_list(void *pool, unsigned gid_min, char ***groupname, unsigned *groupname_size);
void unix_group_list(void *pool, unsigned int gid_min, char ***groupname,
unsigned int *groupname_size);
#endif
#endif

View File

@@ -1,5 +1,5 @@
#ifndef AUTH_COMMON_H
# define AUTH_COMMON_H
#define AUTH_COMMON_H
#define MAX_PASSWORD_TRIES 3

View File

@@ -17,7 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#ifdef HAVE_GSSAPI
@@ -42,7 +41,7 @@
struct gssapi_vhost_ctx_st {
gss_cred_id_t creds;
gss_OID_set oids;
unsigned no_local_map;
unsigned int no_local_map;
time_t ticket_freshness_secs;
};
@@ -57,8 +56,7 @@ struct gssapi_ctx_st {
};
/* Taken from openconnect's gssapi */
static void print_gss_err(const char *where,
gss_OID mech, OM_uint32 err_maj,
static void print_gss_err(const char *where, gss_OID mech, OM_uint32 err_maj,
OM_uint32 err_min)
{
OM_uint32 major, minor, msg_ctx = 0;
@@ -69,7 +67,8 @@ static void print_gss_err(const char *where,
mech, &msg_ctx, &status);
if (GSS_ERROR(major))
break;
oc_syslog(LOG_ERR, "gssapi: %s[maj]: %s\n", where, (char *)status.value);
oc_syslog(LOG_ERR, "gssapi: %s[maj]: %s\n", where,
(char *)status.value);
gss_release_buffer(&minor, &status);
} while (msg_ctx);
@@ -79,16 +78,15 @@ static void print_gss_err(const char *where,
mech, &msg_ctx, &status);
if (GSS_ERROR(major))
break;
oc_syslog(LOG_ERR, "gssapi: %s[min]: %s\n", where, (char *)status.value);
oc_syslog(LOG_ERR, "gssapi: %s[min]: %s\n", where,
(char *)status.value);
gss_release_buffer(&minor, &status);
} while (msg_ctx);
}
const gss_OID_desc spnego_mech = {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
const gss_OID_set_desc desired_mechs = {
.count = 1,
.elements = (gss_OID)&spnego_mech
};
const gss_OID_desc spnego_mech = { 6, (void *)"\x2b\x06\x01\x05\x05\x02" };
const gss_OID_set_desc desired_mechs = { .count = 1,
.elements = (gss_OID)&spnego_mech };
static void gssapi_vhost_init(void **_vctx, void *pool, void *additional)
{
@@ -118,21 +116,26 @@ static void gssapi_vhost_init(void **_vctx, void *pool, void *additional)
cred_store.count = 1;
cred_store.elements = &element;
ret = gss_acquire_cred_from(&minor, name, 0, (gss_OID_set)&desired_mechs, 2,
&cred_store, &vctx->creds, &vctx->oids, &time);
ret = gss_acquire_cred_from(&minor, name, 0,
(gss_OID_set)&desired_mechs, 2,
&cred_store, &vctx->creds,
&vctx->oids, &time);
if (ret != GSS_S_COMPLETE) {
ret = -1;
print_gss_err("gss_acquire_cred(keytab)", GSS_C_NO_OID, ret, minor);
print_gss_err("gss_acquire_cred(keytab)", GSS_C_NO_OID,
ret, minor);
exit(EXIT_FAILURE);
}
} else {
ret = gss_acquire_cred(&minor, name, 0, (gss_OID_set)&desired_mechs, 2,
&vctx->creds, &vctx->oids, &time);
ret = gss_acquire_cred(&minor, name, 0,
(gss_OID_set)&desired_mechs, 2,
&vctx->creds, &vctx->oids, &time);
if (ret != GSS_S_COMPLETE) {
ret = -1;
print_gss_err("gss_acquire_cred", GSS_C_NO_OID, ret, minor);
print_gss_err("gss_acquire_cred", GSS_C_NO_OID, ret,
minor);
exit(EXIT_FAILURE);
}
}
@@ -149,7 +152,8 @@ static void gssapi_vhost_deinit(void *_vctx)
gss_release_cred(&minor, &vctx->creds);
}
static int get_name(struct gssapi_ctx_st *pctx, gss_name_t client, gss_OID mech_type)
static int get_name(struct gssapi_ctx_st *pctx, gss_name_t client,
gss_OID mech_type)
{
int ret;
OM_uint32 minor;
@@ -168,20 +172,24 @@ static int get_name(struct gssapi_ctx_st *pctx, gss_name_t client, gss_OID mech_
pctx->username[name.length] = 0;
}
oc_syslog(LOG_DEBUG, "gssapi: authenticated GSSAPI user: %.*s", (unsigned)name.length, (char*)name.value);
oc_syslog(LOG_DEBUG, "gssapi: authenticated GSSAPI user: %.*s",
(unsigned int)name.length, (char *)name.value);
gss_release_buffer(&minor, &name);
if (pctx->vctx->no_local_map == 0) {
ret = gss_localname(&minor, client, mech_type, &name);
if (GSS_ERROR(ret) || name.length >= MAX_USERNAME_SIZE) {
print_gss_err("gss_localname", mech_type, ret, minor);
oc_syslog(LOG_INFO, "gssapi: authenticated user doesn't map to a local user");
oc_syslog(
LOG_INFO,
"gssapi: authenticated user doesn't map to a local user");
return -1;
}
memcpy(pctx->username, name.value, name.length);
pctx->username[name.length] = 0;
oc_syslog(LOG_INFO, "gssapi: authenticated local user: %s", pctx->username);
oc_syslog(LOG_INFO, "gssapi: authenticated local user: %s",
pctx->username);
gss_release_buffer(&minor, &name);
}
@@ -192,38 +200,49 @@ static int get_name(struct gssapi_ctx_st *pctx, gss_name_t client, gss_OID mech_
return 0;
}
static int verify_krb5_constraints(struct gssapi_ctx_st *pctx, gss_OID mech_type)
static int verify_krb5_constraints(struct gssapi_ctx_st *pctx,
gss_OID mech_type)
{
int ret;
OM_uint32 minor;
krb5_timestamp authtime;
if (mech_type == NULL ||
((mech_type->length != gss_mech_krb5->length || memcmp(mech_type->elements, gss_mech_krb5->elements, mech_type->length) != 0) &&
(mech_type->length != gss_mech_krb5_old->length || memcmp(mech_type->elements, gss_mech_krb5_old->elements, mech_type->length) != 0)) ||
((mech_type->length != gss_mech_krb5->length ||
memcmp(mech_type->elements, gss_mech_krb5->elements,
mech_type->length) != 0) &&
(mech_type->length != gss_mech_krb5_old->length ||
memcmp(mech_type->elements, gss_mech_krb5_old->elements,
mech_type->length) != 0)) ||
pctx->vctx->ticket_freshness_secs == 0) {
return 0;
}
ret = gsskrb5_extract_authtime_from_sec_context (&minor, pctx->gssctx, &authtime);
ret = gsskrb5_extract_authtime_from_sec_context(&minor, pctx->gssctx,
&authtime);
if (GSS_ERROR(ret)) {
print_gss_err("gsskrb5_extract_authtime_from_sec_context", mech_type, ret, minor);
print_gss_err("gsskrb5_extract_authtime_from_sec_context",
mech_type, ret, minor);
return -1;
}
if (time(NULL) > authtime + pctx->vctx->ticket_freshness_secs) {
oc_syslog(LOG_INFO, "gssapi: the presented kerberos ticket for %s is too old", pctx->username);
oc_syslog(
LOG_INFO,
"gssapi: the presented kerberos ticket for %s is too old",
pctx->username);
return -1;
}
return 0;
}
static int gssapi_auth_init(void **ctx, void *pool, void *_vctx, const common_auth_init_st *info)
static int gssapi_auth_init(void **ctx, void *pool, void *_vctx,
const common_auth_init_st *info)
{
struct gssapi_ctx_st *pctx;
OM_uint32 minor, flags, time;
gss_buffer_desc buf= GSS_C_EMPTY_BUFFER;
gss_buffer_desc buf = GSS_C_EMPTY_BUFFER;
gss_name_t client = GSS_C_NO_NAME;
gss_OID mech_type = GSS_C_NO_OID;
int ret;
@@ -243,20 +262,22 @@ static int gssapi_auth_init(void **ctx, void *pool, void *_vctx, const common_au
pctx->vctx = vctx;
ret = oc_base64_decode_alloc(pctx, spnego, strlen(spnego), &raw, &raw_len);
ret = oc_base64_decode_alloc(pctx, spnego, strlen(spnego), &raw,
&raw_len);
if (ret == 0) {
oc_syslog(LOG_ERR, "gssapi: error in base64 decoding %s", __func__);
oc_syslog(LOG_ERR, "gssapi: error in base64 decoding %s",
__func__);
return ERR_AUTH_FAIL;
}
buf.value = raw;
buf.length = raw_len;
ret = gss_accept_sec_context(&minor, &pctx->gssctx, vctx->creds, &buf,
GSS_C_NO_CHANNEL_BINDINGS, &client, &mech_type, &pctx->msg,
&flags, &time, &pctx->delegated_creds);
GSS_C_NO_CHANNEL_BINDINGS, &client,
&mech_type, &pctx->msg, &flags, &time,
&pctx->delegated_creds);
talloc_free(raw);
if (ret == GSS_S_CONTINUE_NEEDED) {
gss_release_name(&minor, &client);
ret = ERR_AUTH_CONTINUE;
@@ -277,11 +298,13 @@ static int gssapi_auth_init(void **ctx, void *pool, void *_vctx, const common_au
return ret;
}
static int gssapi_auth_group(void *ctx, const char *suggested, char *groupname, int groupname_size)
static int gssapi_auth_group(void *ctx, const char *suggested, char *groupname,
int groupname_size)
{
struct gssapi_ctx_st *pctx = ctx;
return get_user_auth_group(pctx->username, suggested, groupname, groupname_size);
return get_user_auth_group(pctx->username, suggested, groupname,
groupname_size);
}
static int gssapi_auth_user(void *ctx, char *username, int username_size)
@@ -294,7 +317,8 @@ static int gssapi_auth_user(void *ctx, char *username, int username_size)
/* Returns 0 if the user is successfully authenticated, and sets the appropriate group name.
*/
static int gssapi_auth_pass(void *ctx, const char *spnego, unsigned spnego_len)
static int gssapi_auth_pass(void *ctx, const char *spnego,
unsigned int spnego_len)
{
struct gssapi_ctx_st *pctx = ctx;
OM_uint32 minor, flags, time;
@@ -308,15 +332,17 @@ static int gssapi_auth_pass(void *ctx, const char *spnego, unsigned spnego_len)
/* nothing to be done */
ret = oc_base64_decode_alloc(pctx, spnego, spnego_len, &raw, &raw_len);
if (ret == 0) {
oc_syslog(LOG_ERR, "gssapi: error in base64 decoding %s", __func__);
oc_syslog(LOG_ERR, "gssapi: error in base64 decoding %s",
__func__);
return ERR_AUTH_FAIL;
}
buf.value = raw;
buf.length = raw_len;
ret = gss_accept_sec_context(&minor, &pctx->gssctx, pctx->vctx->creds, &buf,
GSS_C_NO_CHANNEL_BINDINGS, &client, &mech_type, &pctx->msg,
&flags, &time, &pctx->delegated_creds);
ret = gss_accept_sec_context(&minor, &pctx->gssctx, pctx->vctx->creds,
&buf, GSS_C_NO_CHANNEL_BINDINGS, &client,
&mech_type, &pctx->msg, &flags, &time,
&pctx->delegated_creds);
talloc_free(raw);
if (ret == GSS_S_CONTINUE_NEEDED) {
@@ -340,15 +366,15 @@ static int gssapi_auth_msg(void *ctx, void *pool, passwd_msg_st *pst)
{
struct gssapi_ctx_st *pctx = ctx;
OM_uint32 min;
unsigned length;
unsigned int length;
/* our msg is our SPNEGO reply */
if (pctx->msg.value != NULL) {
length = BASE64_ENCODE_RAW_LENGTH(pctx->msg.length)+1;
length = BASE64_ENCODE_RAW_LENGTH(pctx->msg.length) + 1;
pst->msg_str = talloc_size(pool, length);
oc_base64_encode(pctx->msg.value, pctx->msg.length,
pst->msg_str, length);
pst->msg_str, length);
gss_release_buffer(&min, &pctx->msg);
pctx->msg.value = NULL;
@@ -367,7 +393,8 @@ static void gssapi_auth_deinit(void *ctx)
talloc_free(ctx);
}
static void gssapi_group_list(void *pool, void *_additional, char ***groupname, unsigned *groupname_size)
static void gssapi_group_list(void *pool, void *_additional, char ***groupname,
unsigned int *groupname_size)
{
gssapi_cfg_st *config = _additional;
gid_t min = 0;

View File

@@ -38,7 +38,7 @@
typedef struct oidc_vctx_st {
json_t *config;
json_t *jwks;
void * pool;
void *pool;
int minimum_jwk_refresh_time;
time_t last_jwks_load_time;
} oidc_vctx_st;
@@ -49,10 +49,10 @@ typedef struct oidc_ctx_st {
int token_verified;
} oidc_ctx_st;
static bool oidc_fetch_oidc_keys(oidc_vctx_st * vctx);
static bool oidc_verify_token(oidc_vctx_st * vctx, const char *token,
size_t token_length,
char user_name[MAX_USERNAME_SIZE]);
static bool oidc_fetch_oidc_keys(oidc_vctx_st *vctx);
static bool oidc_verify_token(oidc_vctx_st *vctx, const char *token,
size_t token_length,
char user_name[MAX_USERNAME_SIZE]);
static void oidc_vhost_init(void **vctx, void *pool, void *additional)
{
@@ -76,30 +76,35 @@ static void oidc_vhost_init(void **vctx, void *pool, void *additional)
vc->config = json_load_file(config, 0, &err);
if (vc->config == NULL) {
oc_syslog(LOG_ERR, "ocserv-oidc: failed to load config file: %s\n", config);
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to load config file: %s\n",
config);
exit(EXIT_FAILURE);
}
if (!json_object_get(vc->config, "openid_configuration_url")) {
oc_syslog(LOG_ERR,
"ocserv-oidc: config file missing openid_configuration_url\n");
oc_syslog(
LOG_ERR,
"ocserv-oidc: config file missing openid_configuration_url\n");
exit(EXIT_FAILURE);
}
if (!json_object_get(vc->config, "required_claims")) {
oc_syslog(LOG_ERR,
"ocserv-oidc: config file missing required_claims\n");
"ocserv-oidc: config file missing required_claims\n");
exit(EXIT_FAILURE);
}
if (!json_object_get(vc->config, "user_name_claim")) {
oc_syslog(LOG_ERR,
"ocserv-oidc: config file missing user_name_claim\n");
"ocserv-oidc: config file missing user_name_claim\n");
exit(EXIT_FAILURE);
}
if (json_object_get(vc->config, "minimum_jwk_refresh_time")) {
vc->minimum_jwk_refresh_time = json_integer_value(json_object_get(vc->config, "minimum_jwk_refresh_time"));
vc->minimum_jwk_refresh_time = json_integer_value(
json_object_get(vc->config,
"minimum_jwk_refresh_time"));
} else {
vc->minimum_jwk_refresh_time = MINIMUM_KEY_REFRESH_INTERVAL;
}
@@ -114,7 +119,7 @@ static void oidc_vhost_init(void **vctx, void *pool, void *additional)
static void oidc_vhost_deinit(void *ctx)
{
oidc_vctx_st *vctx = (oidc_vctx_st *) ctx;
oidc_vctx_st *vctx = (oidc_vctx_st *)ctx;
if (!vctx) {
return;
@@ -132,10 +137,11 @@ static void oidc_vhost_deinit(void *ctx)
}
static int oidc_auth_init(void **ctx, void *pool, void *vctx,
const common_auth_init_st * info)
const common_auth_init_st *info)
{
oidc_vctx_st *vt = (oidc_vctx_st *) vctx;
oidc_vctx_st *vt = (oidc_vctx_st *)vctx;
oidc_ctx_st *ct;
ct = talloc_zero(pool, struct oidc_ctx_st);
if (!ct) {
return ERR_AUTH_FAIL;
@@ -143,7 +149,8 @@ static int oidc_auth_init(void **ctx, void *pool, void *vctx,
ct->vctx_st = vt;
*ctx = (void *)ct;
if (oidc_verify_token(ct->vctx_st, info->username, strlen(info->username), ct->username)) {
if (oidc_verify_token(ct->vctx_st, info->username,
strlen(info->username), ct->username)) {
ct->token_verified = 1;
return 0;
} else {
@@ -153,7 +160,7 @@ static int oidc_auth_init(void **ctx, void *pool, void *vctx,
static int oidc_auth_user(void *ctx, char *username, int username_size)
{
oidc_ctx_st *ct = (oidc_ctx_st *) ctx;
oidc_ctx_st *ct = (oidc_ctx_st *)ctx;
if (ct->token_verified) {
strlcpy(username, ct->username, username_size);
@@ -162,14 +169,14 @@ static int oidc_auth_user(void *ctx, char *username, int username_size)
return ERR_AUTH_FAIL;
}
static int oidc_auth_pass(void *ctx, const char *pass, unsigned pass_len)
static int oidc_auth_pass(void *ctx, const char *pass, unsigned int pass_len)
{
return ERR_AUTH_FAIL;
}
static int oidc_auth_msg(void *ctx, void *pool, passwd_msg_st * pst)
static int oidc_auth_msg(void *ctx, void *pool, passwd_msg_st *pst)
{
pst->counter = 0; /* we support a single password */
pst->counter = 0; /* we support a single password */
/* use the default prompt */
return 0;
@@ -180,19 +187,17 @@ static void oidc_auth_deinit(void *ctx)
talloc_free(ctx);
}
const struct auth_mod_st oidc_auth_funcs = {
.type = AUTH_TYPE_OIDC,
.allows_retries = 1,
.vhost_init = oidc_vhost_init,
.vhost_deinit = oidc_vhost_deinit,
.auth_init = oidc_auth_init,
.auth_deinit = oidc_auth_deinit,
.auth_msg = oidc_auth_msg,
.auth_pass = oidc_auth_pass,
.auth_user = oidc_auth_user,
.auth_group = NULL,
.group_list = NULL
};
const struct auth_mod_st oidc_auth_funcs = { .type = AUTH_TYPE_OIDC,
.allows_retries = 1,
.vhost_init = oidc_vhost_init,
.vhost_deinit = oidc_vhost_deinit,
.auth_init = oidc_auth_init,
.auth_deinit = oidc_auth_deinit,
.auth_msg = oidc_auth_msg,
.auth_pass = oidc_auth_pass,
.auth_user = oidc_auth_user,
.auth_group = NULL,
.group_list = NULL };
// Key management
typedef struct oidc_json_parser_context {
@@ -204,10 +209,10 @@ typedef struct oidc_json_parser_context {
// Callback from CURL for each block as it is downloaded
static size_t oidc_json_parser_context_callback(char *ptr, size_t size,
size_t nmemb, void *userdata)
size_t nmemb, void *userdata)
{
oidc_json_parser_context *context =
(oidc_json_parser_context *) userdata;
(oidc_json_parser_context *)userdata;
size_t new_offset = context->offset + nmemb;
// Check for buffer overflow
@@ -217,7 +222,9 @@ static size_t oidc_json_parser_context_callback(char *ptr, size_t size,
if (context->offset + nmemb > context->length) {
size_t new_size = (nmemb + context->length) * 3 / 2;
void * new_buffer = talloc_realloc_size(context->pool, context->buffer, new_size);
void *new_buffer = talloc_realloc_size(
context->pool, context->buffer, new_size);
if (new_buffer) {
context->buffer = new_buffer;
context->length = new_size;
@@ -233,7 +240,7 @@ static size_t oidc_json_parser_context_callback(char *ptr, size_t size,
}
// Download a JSON file from the provided URI and return it in a jansson object
static json_t *oidc_fetch_json_from_uri(void * pool, const char *uri)
static json_t *oidc_fetch_json_from_uri(void *pool, const char *uri)
{
oidc_json_parser_context context = { pool, NULL, 0, 0 };
json_t *json = NULL;
@@ -250,55 +257,60 @@ static json_t *oidc_fetch_json_from_uri(void * pool, const char *uri)
curl = curl_easy_init();
if (!curl) {
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s\n",
uri);
oc_syslog(
LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s\n",
uri);
goto cleanup;
}
res = curl_easy_setopt(curl, CURLOPT_URL, uri);
if (res != CURLE_OK) {
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
oc_syslog(
LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
goto cleanup;
}
res =
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
oidc_json_parser_context_callback);
res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
oidc_json_parser_context_callback);
if (res != CURLE_OK) {
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
oc_syslog(
LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
goto cleanup;
}
res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &context);
if (res != CURLE_OK) {
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
oc_syslog(
LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
goto cleanup;
}
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
oc_syslog(
LOG_ERR,
"ocserv-oidc: failed to download JSON document: URI %s, CURLcode %d\n",
uri, res);
goto cleanup;
}
json = json_loadb(context.buffer, context.offset, 0, &err);
if (!json) {
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to parse JSON document: URI %s\n",
uri);
oc_syslog(
LOG_ERR,
"ocserv-oidc: failed to parse JSON document: URI %s\n",
uri);
goto cleanup;
}
cleanup:
cleanup:
if (context.buffer) {
talloc_free(context.buffer);
}
@@ -311,47 +323,50 @@ static json_t *oidc_fetch_json_from_uri(void * pool, const char *uri)
}
// Download and parse the JWT keys for this virtual server context
static bool oidc_fetch_oidc_keys(oidc_vctx_st * vctx)
static bool oidc_fetch_oidc_keys(oidc_vctx_st *vctx)
{
bool result = false;
json_t *jwks = NULL;
json_t *oidc_config = NULL;
json_t *openid_configuration_url =
json_object_get(vctx->config, "openid_configuration_url");
json_object_get(vctx->config, "openid_configuration_url");
json_t *array;
size_t index;
json_t *value;
if (!openid_configuration_url) {
oc_syslog(LOG_ERR,
"ocserv-oidc: openid_configuration_url missing from config\n");
oc_syslog(
LOG_ERR,
"ocserv-oidc: openid_configuration_url missing from config\n");
goto cleanup;
}
oidc_config =
oidc_fetch_json_from_uri(vctx->pool,
json_string_value
(openid_configuration_url));
oidc_config = oidc_fetch_json_from_uri(
vctx->pool, json_string_value(openid_configuration_url));
if (!oidc_config) {
oc_syslog(LOG_ERR,
"ocserv-oidc: Unable to fetch config doc from %s\n", json_string_value(openid_configuration_url));
"ocserv-oidc: Unable to fetch config doc from %s\n",
json_string_value(openid_configuration_url));
goto cleanup;
}
json_t *jwks_uri = json_object_get(oidc_config, "jwks_uri");
if (!jwks_uri || !json_string_value(jwks_uri)) {
oc_syslog(LOG_ERR,
"ocserv-oidc: jwks_uri missing from config doc\n");
"ocserv-oidc: jwks_uri missing from config doc\n");
goto cleanup;
}
jwks = oidc_fetch_json_from_uri(vctx->pool, json_string_value(jwks_uri));
jwks = oidc_fetch_json_from_uri(vctx->pool,
json_string_value(jwks_uri));
if (!jwks) {
oc_syslog(LOG_ERR,
"ocserv-oidc: failed to fetch keys from jwks_uri %s\n",
json_string_value(jwks_uri));
oc_syslog(
LOG_ERR,
"ocserv-oidc: failed to fetch keys from jwks_uri %s\n",
json_string_value(jwks_uri));
goto cleanup;
}
@@ -362,12 +377,12 @@ static bool oidc_fetch_oidc_keys(oidc_vctx_st * vctx)
}
// Log the keys obtained
json_array_foreach(array, index, value) {
json_array_foreach(array, index, value)
{
json_t *key_kid = json_object_get(value, "kid");
oc_syslog(LOG_INFO,
"ocserv-oidc: fetched new JWK %s\n",
json_string_value(key_kid)
);
oc_syslog(LOG_INFO, "ocserv-oidc: fetched new JWK %s\n",
json_string_value(key_kid));
}
if (vctx->jwks) {
@@ -380,7 +395,7 @@ static bool oidc_fetch_oidc_keys(oidc_vctx_st * vctx)
jwks = NULL;
result = true;
cleanup:
cleanup:
if (oidc_config) {
json_decref(oidc_config);
}
@@ -391,7 +406,7 @@ static bool oidc_fetch_oidc_keys(oidc_vctx_st * vctx)
return result;
}
static bool oidc_verify_lifetime(json_t * token_claims)
static bool oidc_verify_lifetime(json_t *token_claims)
{
bool result = false;
@@ -402,38 +417,42 @@ static bool oidc_verify_lifetime(json_t * token_claims)
time_t current_time = time(NULL);
if (!token_nbf || !json_integer_value(token_nbf)) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token missing 'nbf' claim\n");
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token missing 'nbf' claim\n");
goto cleanup;
}
if (!token_exp || !json_integer_value(token_exp)) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token missing 'exp' claim\n");
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token missing 'exp' claim\n");
goto cleanup;
}
if (!token_iat || !json_integer_value(token_iat)) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token missing 'iat' claim\n");
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token missing 'iat' claim\n");
goto cleanup;
}
// Check to ensure the token is within it's validity
if (json_integer_value(token_nbf) > current_time
|| json_integer_value(token_exp) < current_time) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token not within validity period NBF: %lld EXP: %lld Current: %ld\n",
json_integer_value(token_nbf),
json_integer_value(token_exp), current_time);
if (json_integer_value(token_nbf) > current_time ||
json_integer_value(token_exp) < current_time) {
oc_syslog(
LOG_NOTICE,
"ocserv-oidc: Token not within validity period NBF: %lld EXP: %lld Current: %ld\n",
json_integer_value(token_nbf),
json_integer_value(token_exp), current_time);
goto cleanup;
}
result = true;
cleanup:
cleanup:
return result;
}
static bool oidc_verify_required_claims(json_t * required_claims,
json_t * token_claims)
static bool oidc_verify_required_claims(json_t *required_claims,
json_t *token_claims)
{
bool result = false;
@@ -443,36 +462,38 @@ static bool oidc_verify_required_claims(json_t * required_claims,
// Ensure all the required claims are present in the token
json_object_foreach(required_claims, required_claim_name,
required_claim_value) {
required_claim_value)
{
token_claim_value =
json_object_get(token_claims, required_claim_name);
json_object_get(token_claims, required_claim_name);
if (!json_equal(required_claim_value, token_claim_value)) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Required claim not met. Claim: %s Expected Value: %s\n",
required_claim_name,
json_string_value(required_claim_value));
oc_syslog(
LOG_NOTICE,
"ocserv-oidc: Required claim not met. Claim: %s Expected Value: %s\n",
required_claim_name,
json_string_value(required_claim_value));
goto cleanup;
}
}
result = true;
cleanup:
cleanup:
return result;
}
static bool oidc_map_user_name(json_t * user_name_claim,
json_t * token_claims,
char user_name[MAX_USERNAME_SIZE])
static bool oidc_map_user_name(json_t *user_name_claim, json_t *token_claims,
char user_name[MAX_USERNAME_SIZE])
{
bool result = false;
// Pull the user name from the token
json_t *token_user_name_claim =
json_object_get(token_claims, json_string_value(user_name_claim));
if (!token_user_name_claim || !json_string_value(token_user_name_claim)) {
json_t *token_user_name_claim = json_object_get(
token_claims, json_string_value(user_name_claim));
if (!token_user_name_claim ||
!json_string_value(token_user_name_claim)) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token missing '%s' claim\n",
json_string_value(user_name_claim));
json_string_value(user_name_claim));
goto cleanup;
}
@@ -480,11 +501,11 @@ static bool oidc_map_user_name(json_t * user_name_claim,
MAX_USERNAME_SIZE);
result = true;
cleanup:
cleanup:
return result;
}
static json_t *oidc_extract_claims(cjose_jws_t * jws)
static json_t *oidc_extract_claims(cjose_jws_t *jws)
{
cjose_err err;
json_error_t json_err;
@@ -493,26 +514,27 @@ static json_t *oidc_extract_claims(cjose_jws_t * jws)
json_t *token_claims = NULL;
// Extract the claim portion from the token
if (!cjose_jws_get_plaintext(jws, &plain_text, &plain_text_size, &err)) {
if (!cjose_jws_get_plaintext(jws, &plain_text, &plain_text_size,
&err)) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Failed to get plain text from token\n");
"ocserv-oidc: Failed to get plain text from token\n");
goto cleanup;
}
// Parse the claim JSON
token_claims =
json_loadb((char *)plain_text, plain_text_size, 0, &json_err);
json_loadb((char *)plain_text, plain_text_size, 0, &json_err);
if (!token_claims) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Failed to get claims from token\n");
"ocserv-oidc: Failed to get claims from token\n");
goto cleanup;
}
cleanup:
cleanup:
return token_claims;
}
static bool oidc_verify_signature(oidc_vctx_st * vctx, cjose_jws_t * jws)
static bool oidc_verify_signature(oidc_vctx_st *vctx, cjose_jws_t *jws)
{
bool result = false;
@@ -540,26 +562,31 @@ static bool oidc_verify_signature(oidc_vctx_st * vctx, cjose_jws_t * jws)
token_header = cjose_jws_get_protected(jws);
if (token_header == NULL) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token malformed - no header\n");
"ocserv-oidc: Token malformed - no header\n");
goto cleanup;
}
// Get the kid of the key used to sign this token
token_kid = json_object_get(token_header, "kid");
if (token_kid == NULL || !json_string_value(token_kid)) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token malformed - no kid\n");
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token malformed - no kid\n");
goto cleanup;
}
token_typ = json_object_get(token_header, "typ");
if (token_typ == NULL || !json_string_value(token_typ) || strcmp(json_string_value(token_typ), "JWT")) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token malformed - wrong typ claim\n");
if (token_typ == NULL || !json_string_value(token_typ) ||
strcmp(json_string_value(token_typ), "JWT")) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token malformed - wrong typ claim\n");
goto cleanup;
}
// Find the signing key in the keys collection
json_array_foreach(array, index, value) {
json_array_foreach(array, index, value)
{
json_t *key_kid = json_object_get(value, "kid");
if (json_equal(key_kid, token_kid)) {
jwk = cjose_jwk_import_json(value, &err);
break;
@@ -568,16 +595,20 @@ static bool oidc_verify_signature(oidc_vctx_st * vctx, cjose_jws_t * jws)
if (jwk == NULL) {
time_t now;
oc_syslog(LOG_NOTICE, "ocserv-oidc: JWK with kid=%s not found\n",
json_string_value(token_kid));
oc_syslog(LOG_NOTICE, "ocserv-oidc: attempting to download new JWKs");
oc_syslog(LOG_NOTICE,
"ocserv-oidc: JWK with kid=%s not found\n",
json_string_value(token_kid));
oc_syslog(LOG_NOTICE,
"ocserv-oidc: attempting to download new JWKs");
now = time(NULL);
if ((now - vctx->last_jwks_load_time) > vctx->minimum_jwk_refresh_time) {
if ((now - vctx->last_jwks_load_time) >
vctx->minimum_jwk_refresh_time) {
oidc_fetch_oidc_keys(vctx);
}
else {
oc_syslog(LOG_NOTICE, "ocserv-oidc: skipping JWK refresh");
} else {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: skipping JWK refresh");
}
// Fail the request and let the client try again.
@@ -585,14 +616,15 @@ static bool oidc_verify_signature(oidc_vctx_st * vctx, cjose_jws_t * jws)
}
if (!cjose_jws_verify(jws, jwk, &err)) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token failed validation %s\n",
err.message);
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token failed validation %s\n",
err.message);
goto cleanup;
}
result = true;
cleanup:
cleanup:
if (jwk) {
cjose_jwk_release(jwk);
}
@@ -601,9 +633,9 @@ static bool oidc_verify_signature(oidc_vctx_st * vctx, cjose_jws_t * jws)
}
// Verify that the provided token is signed
static bool oidc_verify_token(oidc_vctx_st * vctx, const char *token,
size_t token_length,
char user_name[MAX_USERNAME_SIZE])
static bool oidc_verify_token(oidc_vctx_st *vctx, const char *token,
size_t token_length,
char user_name[MAX_USERNAME_SIZE])
{
bool result = false;
cjose_err err;
@@ -613,47 +645,49 @@ static bool oidc_verify_token(oidc_vctx_st * vctx, const char *token,
jws = cjose_jws_import(token, token_length, &err);
if (jws == NULL) {
oc_syslog(LOG_NOTICE, "ocserv-oidc: Token malformed - %s\n",
err.message);
err.message);
goto cleanup;
}
if (!oidc_verify_signature(vctx, jws)) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token signature validation failed\n");
"ocserv-oidc: Token signature validation failed\n");
goto cleanup;
}
token_claims = oidc_extract_claims(jws);
if (!token_claims) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Unable to access token claims\n");
"ocserv-oidc: Unable to access token claims\n");
goto cleanup;
}
if (!oidc_verify_lifetime(token_claims)) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token lifetime validation failed\n");
"ocserv-oidc: Token lifetime validation failed\n");
goto cleanup;
}
if (!oidc_verify_required_claims
(json_object_get(vctx->config, "required_claims"), token_claims)) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Token required claims validation failed\n");
if (!oidc_verify_required_claims(json_object_get(vctx->config,
"required_claims"),
token_claims)) {
oc_syslog(
LOG_NOTICE,
"ocserv-oidc: Token required claims validation failed\n");
goto cleanup;
}
if (!oidc_map_user_name
(json_object_get(vctx->config, "user_name_claim"), token_claims,
user_name)) {
if (!oidc_map_user_name(json_object_get(vctx->config,
"user_name_claim"),
token_claims, user_name)) {
oc_syslog(LOG_NOTICE,
"ocserv-oidc: Unable to map user name claim\n");
"ocserv-oidc: Unable to map user name claim\n");
goto cleanup;
}
result = true;
cleanup:
cleanup:
if (jws) {
cjose_jws_release(jws);
}

View File

@@ -48,7 +48,7 @@
#include "auth/pam.h"
#include "auth-unix.h"
#define PAM_STACK_SIZE (1024*1024)
#define PAM_STACK_SIZE (1024 * 1024)
#define MAX_REPLIES 2
@@ -59,10 +59,10 @@ enum {
};
static int ocserv_conv(int msg_size, const struct pam_message **msg,
struct pam_response **resp, void *uptr)
struct pam_response **resp, void *uptr)
{
struct pam_ctx_st * pctx = uptr;
unsigned i;
struct pam_ctx_st *pctx = uptr;
unsigned int i;
int ret;
if (msg_size == 0)
@@ -70,15 +70,16 @@ static int ocserv_conv(int msg_size, const struct pam_message **msg,
str_reset(&pctx->msg);
pctx->replies = calloc(1, msg_size*sizeof(*pctx->replies));
pctx->replies = calloc(1, msg_size * sizeof(*pctx->replies));
if (pctx->replies == NULL)
return PAM_BUF_ERR;
for (i=0;i<msg_size;i++) {
for (i = 0; i < msg_size; i++) {
switch (msg[i]->msg_style) {
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
oc_syslog(LOG_DEBUG, "PAM-auth conv info: %s", msg[i]->msg);
oc_syslog(LOG_DEBUG, "PAM-auth conv info: %s",
msg[i]->msg);
// That should never happen, but also not a big deal if we fail to add message here.
// coverity[check_return : FALSE]
@@ -87,7 +88,8 @@ static int ocserv_conv(int msg_size, const struct pam_message **msg,
ret = str_append_data(&pctx->msg, " ", 1);
if (ret < 0) {
oc_syslog(LOG_ERR, "Error in memory allocation in PAM");
oc_syslog(LOG_ERR,
"Error in memory allocation in PAM");
return PAM_BUF_ERR;
}
@@ -99,18 +101,24 @@ static int ocserv_conv(int msg_size, const struct pam_message **msg,
/* no message, just asking for password */
str_reset(&pctx->msg);
pctx->sent_msg = 1;
}
if (msg[i]->msg) {
ret = str_append_str(&pctx->msg, msg[i]->msg);
if (ret < 0) {
oc_syslog(LOG_ERR, "Error in memory allocation in PAM");
oc_syslog(
LOG_ERR,
"Error in memory allocation in PAM");
return PAM_BUF_ERR;
}
}
oc_syslog(LOG_DEBUG, "PAM-auth conv: echo-%s, msg: '%s'", (msg[i]->msg_style==PAM_PROMPT_ECHO_ON)?"on":"off", msg[i]->msg!=NULL?msg[i]->msg:"");
oc_syslog(LOG_DEBUG,
"PAM-auth conv: echo-%s, msg: '%s'",
(msg[i]->msg_style == PAM_PROMPT_ECHO_ON) ?
"on" :
"off",
msg[i]->msg != NULL ? msg[i]->msg : "");
pctx->state = PAM_S_WAIT_FOR_PASS;
pctx->cr_ret = PAM_SUCCESS;
@@ -120,13 +128,15 @@ static int ocserv_conv(int msg_size, const struct pam_message **msg,
if (pctx->password[0] != 0) {
pctx->replies[i].resp = strdup(pctx->password);
if (pctx->replies[i].resp == NULL) {
oc_syslog(LOG_ERR, "Error in memory allocation in PAM");
oc_syslog(
LOG_ERR,
"Error in memory allocation in PAM");
return PAM_BUF_ERR;
}
}
pctx->sent_msg = 0;
break;
}
}
}
*resp = pctx->replies;
@@ -134,16 +144,17 @@ static int ocserv_conv(int msg_size, const struct pam_message **msg,
return PAM_SUCCESS;
}
static void co_auth_user(void* data)
static void co_auth_user(void *data)
{
struct pam_ctx_st * pctx = data;
int pret;
struct pam_ctx_st *pctx = data;
int pret;
pctx->state = PAM_S_INIT;
pret = pam_authenticate(pctx->ph, 0);
if (pret != PAM_SUCCESS) {
oc_syslog(LOG_INFO, "PAM authenticate error for '%s': %s", pctx->username, pam_strerror(pctx->ph, pret));
oc_syslog(LOG_INFO, "PAM authenticate error for '%s': %s",
pctx->username, pam_strerror(pctx->ph, pret));
pctx->cr_ret = pret;
goto wait;
}
@@ -151,14 +162,18 @@ int pret;
pret = pam_acct_mgmt(pctx->ph, 0);
if (pret == PAM_NEW_AUTHTOK_REQD) {
/* change password */
oc_syslog(LOG_INFO, "Password for user '%s' is expired. Attempting to update...", pctx->username);
oc_syslog(
LOG_INFO,
"Password for user '%s' is expired. Attempting to update...",
pctx->username);
pctx->changing = 1;
pret = pam_chauthtok(pctx->ph, PAM_CHANGE_EXPIRED_AUTHTOK);
}
if (pret != PAM_SUCCESS) {
oc_syslog(LOG_INFO, "PAM acct-mgmt error for '%s': %s", pctx->username, pam_strerror(pctx->ph, pret));
oc_syslog(LOG_INFO, "PAM acct-mgmt error for '%s': %s",
pctx->username, pam_strerror(pctx->ph, pret));
pctx->cr_ret = pret;
goto wait;
}
@@ -166,21 +181,21 @@ int pret;
pctx->state = PAM_S_COMPLETE;
pctx->cr_ret = PAM_SUCCESS;
wait:
wait:
/* give control back to the main process */
while (1) {
co_resume();
}
}
static int pam_auth_init(void** ctx, void *pool, void *vctx, const common_auth_init_st *info)
static int pam_auth_init(void **ctx, void *pool, void *vctx,
const common_auth_init_st *info)
{
int pret;
struct pam_ctx_st * pctx;
int pret;
struct pam_ctx_st *pctx;
if (info->username == NULL || info->username[0] == 0) {
oc_syslog(LOG_NOTICE,
"pam-auth: no username present");
oc_syslog(LOG_NOTICE, "pam-auth: no username present");
return ERR_AUTH_FAIL;
}
@@ -194,7 +209,8 @@ struct pam_ctx_st * pctx;
pctx->dc.appdata_ptr = pctx;
pret = pam_start(PACKAGE, info->username, &pctx->dc, &pctx->ph);
if (pret != PAM_SUCCESS) {
oc_syslog(LOG_NOTICE, "PAM-auth init: %s", pam_strerror(pctx->ph, pret));
oc_syslog(LOG_NOTICE, "PAM-auth init: %s",
pam_strerror(pctx->ph, pret));
goto fail1;
}
@@ -218,10 +234,10 @@ fail1:
return -1;
}
static int pam_auth_msg(void* ctx, void *pool, passwd_msg_st *pst)
static int pam_auth_msg(void *ctx, void *pool, passwd_msg_st *pst)
{
struct pam_ctx_st * pctx = ctx;
size_t prompt_hash = 0;
struct pam_ctx_st *pctx = ctx;
size_t prompt_hash = 0;
if (pctx->state != PAM_S_INIT && pctx->state != PAM_S_WAIT_FOR_PASS) {
return 0;
@@ -233,22 +249,24 @@ size_t prompt_hash = 0;
co_call(pctx->cr);
if (pctx->cr_ret != PAM_SUCCESS) {
oc_syslog(LOG_NOTICE, "PAM-auth pam_auth_msg: %s", pam_strerror(pctx->ph, pctx->cr_ret));
oc_syslog(LOG_NOTICE, "PAM-auth pam_auth_msg: %s",
pam_strerror(pctx->ph, pctx->cr_ret));
return ERR_AUTH_FAIL;
}
}
if (pctx->msg.length == 0) {
if (pctx->changing)
pst->msg_str = talloc_strdup(pool, "Please enter the new password.");
/* else use the default prompt */
if (pctx->changing)
pst->msg_str = talloc_strdup(
pool, "Please enter the new password.");
/* else use the default prompt */
} else {
if (str_append_data(&pctx->msg, "\0", 1) < 0)
return -1;
prompt_hash = hash_any(pctx->msg.data, pctx->msg.length, 0);
pst->msg_str = talloc_strdup(pool, (char*)pctx->msg.data);
pst->msg_str = talloc_strdup(pool, (char *)pctx->msg.data);
}
pst->counter = pctx->passwd_counter;
@@ -265,15 +283,18 @@ size_t prompt_hash = 0;
/* Returns 0 if the user is successfully authenticated
*/
static int pam_auth_pass(void* ctx, const char* pass, unsigned pass_len)
static int pam_auth_pass(void *ctx, const char *pass, unsigned int pass_len)
{
struct pam_ctx_st * pctx = ctx;
struct pam_ctx_st *pctx = ctx;
if (pass == NULL || pass_len+1 > sizeof(pctx->password))
if (pass == NULL || pass_len + 1 > sizeof(pctx->password))
return -1;
if (pctx->state != PAM_S_WAIT_FOR_PASS) {
oc_syslog(LOG_NOTICE, "PAM auth: conversation left in wrong state (%d/expecting %d)", pctx->state, PAM_S_WAIT_FOR_PASS);
oc_syslog(
LOG_NOTICE,
"PAM auth: conversation left in wrong state (%d/expecting %d)",
pctx->state, PAM_S_WAIT_FOR_PASS);
return ERR_AUTH_FAIL;
}
@@ -284,7 +305,8 @@ struct pam_ctx_st * pctx = ctx;
co_call(pctx->cr);
if (pctx->cr_ret != PAM_SUCCESS) {
oc_syslog(LOG_NOTICE, "PAM-auth pam_auth_pass: %s", pam_strerror(pctx->ph, pctx->cr_ret));
oc_syslog(LOG_NOTICE, "PAM-auth pam_auth_pass: %s",
pam_strerror(pctx->ph, pctx->cr_ret));
return ERR_AUTH_FAIL;
}
@@ -296,18 +318,20 @@ struct pam_ctx_st * pctx = ctx;
/* Returns 0 if the user is successfully authenticated
*/
static int pam_auth_group(void* ctx, const char *suggested, char *groupname, int groupname_size)
static int pam_auth_group(void *ctx, const char *suggested, char *groupname,
int groupname_size)
{
struct pam_ctx_st * pctx = ctx;
struct pam_ctx_st *pctx = ctx;
return get_user_auth_group(pctx->username, suggested, groupname, groupname_size);
return get_user_auth_group(pctx->username, suggested, groupname,
groupname_size);
}
static int pam_auth_user(void* ctx, char *username, int username_size)
static int pam_auth_user(void *ctx, char *username, int username_size)
{
const char* user = NULL;
struct pam_ctx_st * pctx = ctx;
int pret;
const char *user = NULL;
struct pam_ctx_st *pctx = ctx;
int pret;
username[0] = 0;
@@ -326,9 +350,9 @@ int pret;
return -1;
}
static void pam_auth_deinit(void* ctx)
static void pam_auth_deinit(void *ctx)
{
struct pam_ctx_st * pctx = ctx;
struct pam_ctx_st *pctx = ctx;
pam_end(pctx->ph, pctx->cr_ret);
free(pctx->replies);
@@ -338,7 +362,8 @@ struct pam_ctx_st * pctx = ctx;
talloc_free(pctx);
}
static void pam_group_list(void *pool, void *_additional, char ***groupname, unsigned *groupname_size)
static void pam_group_list(void *pool, void *_additional, char ***groupname,
unsigned int *groupname_size)
{
struct pam_cfg_st *config = _additional;
gid_t min = 0;
@@ -349,15 +374,14 @@ static void pam_group_list(void *pool, void *_additional, char ***groupname, uns
unix_group_list(pool, min, groupname, groupname_size);
}
const struct auth_mod_st pam_auth_funcs = {
.type = AUTH_TYPE_PAM | AUTH_TYPE_USERNAME_PASS,
.auth_init = pam_auth_init,
.auth_deinit = pam_auth_deinit,
.auth_msg = pam_auth_msg,
.auth_pass = pam_auth_pass,
.auth_group = pam_auth_group,
.auth_user = pam_auth_user,
.group_list = pam_group_list
};
const struct auth_mod_st pam_auth_funcs = { .type = AUTH_TYPE_PAM |
AUTH_TYPE_USERNAME_PASS,
.auth_init = pam_auth_init,
.auth_deinit = pam_auth_deinit,
.auth_msg = pam_auth_msg,
.auth_pass = pam_auth_pass,
.auth_group = pam_auth_group,
.auth_user = pam_auth_user,
.group_list = pam_group_list };
#endif

View File

@@ -35,17 +35,17 @@ extern const struct auth_mod_st pam_auth_funcs;
struct pam_ctx_st {
char password[MAX_PASSWORD_SIZE];
char username[MAX_USERNAME_SIZE];
pam_handle_t * ph;
pam_handle_t *ph;
struct pam_conv dc;
coroutine_t cr;
int cr_ret;
unsigned changing; /* whether we are entering a new password */
unsigned int changing; /* whether we are entering a new password */
str_st msg;
str_st prompt;
unsigned sent_msg;
unsigned int sent_msg;
struct pam_response *replies; /* for safety */
unsigned state; /* PAM_S_ */
unsigned passwd_counter;
unsigned int state; /* PAM_S_ */
unsigned int passwd_counter;
size_t prev_prompt_hash;
};

View File

@@ -31,12 +31,12 @@
#include <ccan/htable/htable.h>
#include <ccan/hash/hash.h>
#ifdef HAVE_LIBOATH
# include <liboath/oath.h>
#include <liboath/oath.h>
#endif
#ifdef HAVE_CRYPT_H
/* libcrypt in Fedora28 does not provide prototype
/* libcrypt in Fedora28 does not provide prototype
* in unistd.h */
# include <crypt.h>
#include <crypt.h>
#endif
#include "log.h"
@@ -45,14 +45,14 @@
struct plain_ctx_st {
char username[MAX_USERNAME_SIZE];
char cpass[MAX_CPASS_SIZE]; /* crypt() passwd */
char cpass[MAX_CPASS_SIZE]; /* crypt() passwd */
char *groupnames[MAX_GROUPS];
unsigned groupnames_size;
unsigned int groupnames_size;
const char *pass_msg;
unsigned retries;
unsigned failed; /* non-zero if the username is wrong */
unsigned int retries;
unsigned int failed; /* non-zero if the username is wrong */
const struct plain_cfg_st *config;
};
@@ -68,7 +68,7 @@ static void plain_vhost_init(void **vctx, void *pool, void *additional)
exit(EXIT_FAILURE);
}
*vctx = (void*)config;
*vctx = (void *)config;
#ifdef HAVE_LIBOATH
oath_init();
@@ -78,13 +78,13 @@ static void plain_vhost_init(void **vctx, void *pool, void *additional)
/* Breaks a list of "xxx", "yyy", to a character array, of
* MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
*/
static void
break_group_list(void *pool, char *text,
char *broken_text[MAX_GROUPS], unsigned *elements)
static void break_group_list(void *pool, char *text,
char *broken_text[MAX_GROUPS],
unsigned int *elements)
{
char *p = talloc_strdup(pool, text);
char *p2;
unsigned len;
unsigned int len;
*elements = 0;
@@ -98,16 +98,16 @@ break_group_list(void *pool, char *text,
p = strchr(p, ',');
if (p) {
*p = 0;
len = p - broken_text[*elements-1];
len = p - broken_text[*elements - 1];
/* remove any trailing space */
p2 = p-1;
p2 = p - 1;
while (isspace(*p2)) {
*p2 = 0;
p2--;
}
p++; /* move to next entry and skip white
p++; /* move to next entry and skip white
* space.
*/
while (isspace(*p))
@@ -118,7 +118,7 @@ break_group_list(void *pool, char *text,
(*elements)--;
}
} else {
p2 = strrchr(broken_text[(*elements)-1], ' ');
p2 = strrchr(broken_text[(*elements) - 1], ' ');
if (p2 != NULL) {
while (isspace(*p2)) {
*p2 = 0;
@@ -126,13 +126,12 @@ break_group_list(void *pool, char *text,
}
}
if (strlen(broken_text[(*elements)-1]) == 1) {
if (strlen(broken_text[(*elements) - 1]) == 1) {
/* skip the group */
(*elements)--;
}
}
}
while (p != NULL && *elements < MAX_GROUPS);
} while (p != NULL && *elements < MAX_GROUPS);
}
/* Returns 0 if the user is successfully authenticated, and sets the appropriate group name.
@@ -155,13 +154,13 @@ static int read_auth_pass(struct plain_ctx_st *pctx)
fp = fopen(pctx->config->passwd, "r");
if (fp == NULL) {
oc_syslog(LOG_ERR,
"error in plain authentication; cannot open: %s",
pctx->config->passwd);
"error in plain authentication; cannot open: %s",
pctx->config->passwd);
return -1;
}
line[sizeof(line)-1] = 0;
while ((p=fgets(line, sizeof(line)-1, fp)) != NULL) {
line[sizeof(line) - 1] = 0;
while ((p = fgets(line, sizeof(line) - 1, fp)) != NULL) {
ll = strlen(p);
if (ll <= 4)
@@ -182,11 +181,13 @@ static int read_auth_pass(struct plain_ctx_st *pctx)
if (p != NULL && strcmp(pctx->username, p) == 0) {
p = strsep(&sp, ":");
if (p != NULL) {
break_group_list(pctx, p, pctx->groupnames, &pctx->groupnames_size);
break_group_list(pctx, p, pctx->groupnames,
&pctx->groupnames_size);
p = strsep(&sp, ":");
if (p != NULL) {
strlcpy(pctx->cpass, p, sizeof(pctx->cpass));
strlcpy(pctx->cpass, p,
sizeof(pctx->cpass));
pctx->failed = 0;
ret = 0;
goto exit;
@@ -200,11 +201,13 @@ static int read_auth_pass(struct plain_ctx_st *pctx)
if (p != NULL && strcmp(pctx->username, p) == 0) {
p = strtok_r(NULL, ":", &sp);
if (p != NULL) {
break_group_list(pctx, p, pctx->groupnames, &pctx->groupnames_size);
break_group_list(pctx, p, pctx->groupnames,
&pctx->groupnames_size);
p = strtok_r(NULL, ":", &sp);
if (p != NULL) {
strlcpy(pctx->cpass, p, sizeof(pctx->cpass));
strlcpy(pctx->cpass, p,
sizeof(pctx->cpass));
pctx->failed = 0;
ret = 0;
goto exit;
@@ -216,20 +219,20 @@ static int read_auth_pass(struct plain_ctx_st *pctx)
/* always succeed */
ret = 0;
exit:
exit:
safe_memset(line, 0, sizeof(line));
fclose(fp);
return ret;
}
static int plain_auth_init(void **ctx, void *pool, void *vctx, const common_auth_init_st *info)
static int plain_auth_init(void **ctx, void *pool, void *vctx,
const common_auth_init_st *info)
{
struct plain_ctx_st *pctx;
int ret;
if (info->username == NULL || info->username[0] == 0) {
oc_syslog(LOG_ERR,
"plain-auth: no username present");
oc_syslog(LOG_ERR, "plain-auth: no username present");
return ERR_AUTH_FAIL;
}
@@ -262,26 +265,29 @@ static int plain_auth_init(void **ctx, void *pool, void *vctx, const common_auth
return ERR_AUTH_CONTINUE;
}
static int plain_auth_group(void *ctx, const char *suggested, char *groupname, int groupname_size)
static int plain_auth_group(void *ctx, const char *suggested, char *groupname,
int groupname_size)
{
struct plain_ctx_st *pctx = ctx;
unsigned i, found = 0;
unsigned int i, found = 0;
groupname[0] = 0;
if (suggested != NULL) {
for (i=0;i<pctx->groupnames_size;i++) {
for (i = 0; i < pctx->groupnames_size; i++) {
if (strcmp(suggested, pctx->groupnames[i]) == 0) {
strlcpy(groupname, pctx->groupnames[i], groupname_size);
strlcpy(groupname, pctx->groupnames[i],
groupname_size);
found = 1;
break;
}
}
if (found == 0) {
oc_syslog(LOG_NOTICE,
"user '%s' requested group '%s' but is not a member",
pctx->username, suggested);
oc_syslog(
LOG_NOTICE,
"user '%s' requested group '%s' but is not a member",
pctx->username, suggested);
return -1;
}
}
@@ -300,7 +306,7 @@ static int plain_auth_user(void *ctx, char *username, int username_size)
/* Returns 0 if the user is successfully authenticated, and sets the appropriate group name.
*/
static int plain_auth_pass(void *ctx, const char *pass, unsigned pass_len)
static int plain_auth_pass(void *ctx, const char *pass, unsigned int pass_len)
{
struct plain_ctx_st *pctx = ctx;
const char *p;
@@ -314,21 +320,22 @@ static int plain_auth_pass(void *ctx, const char *pass, unsigned pass_len)
}
if (pctx->failed) {
if (pctx->retries++ < MAX_PASSWORD_TRIES-1) {
if (pctx->retries++ < MAX_PASSWORD_TRIES - 1) {
pctx->pass_msg = pass_msg_failed;
return ERR_AUTH_CONTINUE;
} else {
oc_syslog(LOG_NOTICE,
"plain-auth: error authenticating user '%s'",
pctx->username);
"plain-auth: error authenticating user '%s'",
pctx->username);
return ERR_AUTH_FAIL;
}
}
if (pctx->cpass[0] == 0 && pctx->config->otp_file == NULL) {
oc_syslog(LOG_NOTICE,
"plain-auth: user '%s' has empty password and no OTP file configured",
pctx->username);
oc_syslog(
LOG_NOTICE,
"plain-auth: user '%s' has empty password and no OTP file configured",
pctx->username);
return ERR_AUTH_FAIL;
}
@@ -344,12 +351,13 @@ static int plain_auth_pass(void *ctx, const char *pass, unsigned pass_len)
}
/* no primary password -> check OTP */
ret = oath_authenticate_usersfile(pctx->config->otp_file, pctx->username,
pass, HOTP_WINDOW, NULL, &last);
ret = oath_authenticate_usersfile(pctx->config->otp_file,
pctx->username, pass,
HOTP_WINDOW, NULL, &last);
if (ret != OATH_OK) {
oc_syslog(LOG_NOTICE,
"plain-auth: OTP auth failed for '%s': %s",
pctx->username, oath_strerror(ret));
"plain-auth: OTP auth failed for '%s': %s",
pctx->username, oath_strerror(ret));
return ERR_AUTH_FAIL;
}
}
@@ -381,10 +389,11 @@ static void plain_auth_deinit(void *ctx)
static size_t rehash(const void *_e, void *unused)
{
const char *e = _e;
return hash_any(e, strlen(e), 0);
}
static bool str_cmp(const void* _c1, void* _c2)
static bool str_cmp(const void *_c1, void *_c2)
{
const char *c1 = _c1, *c2 = _c2;
@@ -393,17 +402,18 @@ static bool str_cmp(const void* _c1, void* _c2)
return 0;
}
static void plain_group_list(void *pool, void *additional, char ***groupname, unsigned *groupname_size)
static void plain_group_list(void *pool, void *additional, char ***groupname,
unsigned int *groupname_size)
{
FILE *fp;
char line[512];
ssize_t ll;
char *p, *sp;
unsigned i;
unsigned int i;
size_t hval;
struct htable_iter iter;
char *tgroup[MAX_GROUPS];
unsigned tgroup_size;
unsigned int tgroup_size;
struct htable hash;
struct plain_cfg_st *config = additional;
@@ -413,13 +423,13 @@ static void plain_group_list(void *pool, void *additional, char ***groupname, un
fp = fopen(config->passwd, "r");
if (fp == NULL) {
oc_syslog(LOG_NOTICE,
"error in plain authentication; cannot open: %s",
(char*)config->passwd);
"error in plain authentication; cannot open: %s",
(char *)config->passwd);
return;
}
line[sizeof(line)-1] = 0;
while ((p=fgets(line, sizeof(line)-1, fp)) != NULL) {
line[sizeof(line) - 1] = 0;
while ((p = fgets(line, sizeof(line) - 1, fp)) != NULL) {
ll = strlen(p);
if (ll <= 4)
@@ -449,12 +459,15 @@ static void plain_group_list(void *pool, void *additional, char ***groupname, un
if (p != NULL) {
break_group_list(pool, p, tgroup, &tgroup_size);
for (i=0;i<tgroup_size;i++) {
for (i = 0; i < tgroup_size; i++) {
hval = rehash(tgroup[i], NULL);
if (htable_get(&hash, hval, str_cmp, tgroup[i]) == NULL) {
if (htable_get(&hash, hval, str_cmp,
tgroup[i]) == NULL) {
if (strlen(tgroup[i]) > 1)
(void)htable_add(&hash, hval, tgroup[i]);
(void)htable_add(
&hash, hval,
tgroup[i]);
}
}
}
@@ -462,7 +475,7 @@ static void plain_group_list(void *pool, void *additional, char ***groupname, un
}
*groupname_size = 0;
*groupname = talloc_size(pool, sizeof(char*)*MAX_GROUPS);
*groupname = talloc_size(pool, sizeof(char *) * MAX_GROUPS);
if (*groupname == NULL) {
goto exit;
}
@@ -475,21 +488,20 @@ static void plain_group_list(void *pool, void *additional, char ***groupname, un
}
/* always succeed */
exit:
exit:
htable_clear(&hash);
safe_memset(line, 0, sizeof(line));
fclose(fp);
}
const struct auth_mod_st plain_auth_funcs = {
.type = AUTH_TYPE_PLAIN | AUTH_TYPE_USERNAME_PASS,
.allows_retries = 1,
.vhost_init = plain_vhost_init,
.auth_init = plain_auth_init,
.auth_deinit = plain_auth_deinit,
.auth_msg = plain_auth_msg,
.auth_pass = plain_auth_pass,
.auth_user = plain_auth_user,
.auth_group = plain_auth_group,
.group_list = plain_group_list
};
const struct auth_mod_st plain_auth_funcs = { .type = AUTH_TYPE_PLAIN |
AUTH_TYPE_USERNAME_PASS,
.allows_retries = 1,
.vhost_init = plain_vhost_init,
.auth_init = plain_auth_init,
.auth_deinit = plain_auth_deinit,
.auth_msg = plain_auth_msg,
.auth_pass = plain_auth_pass,
.auth_user = plain_auth_user,
.auth_group = plain_auth_group,
.group_list = plain_group_list };

View File

@@ -36,39 +36,40 @@
#include "common-config.h"
#ifdef LEGACY_RADIUS
# include <freeradius-client.h>
#include <freeradius-client.h>
#else
# include <radcli/radcli.h>
#include <radcli/radcli.h>
#endif
#ifndef VENDOR_BIT_SIZE
# define VENDOR_BIT_SIZE 16
# define VENDOR_MASK 0xffff
#define VENDOR_BIT_SIZE 16
#define VENDOR_MASK 0xffff
#else
# define VENDOR_MASK 0xffffffff
#define VENDOR_MASK 0xffffffff
#endif
#define VATTRID_SET(a,v) ((a)|((uint64_t)((v)&VENDOR_MASK)) << VENDOR_BIT_SIZE)
#define VATTRID_SET(a, v) \
((a) | ((uint64_t)((v) & VENDOR_MASK)) << VENDOR_BIT_SIZE)
#define RAD_GROUP_NAME PW_CLASS
/* Microsoft - RFC 2548 */
#define MS_PRIMARY_DNS_SERVER VATTRID_SET(28, 311)
#define MS_SECONDARY_DNS_SERVER VATTRID_SET(29, 311)
/* Roaring Penguin */
#define RP_UPSTREAM_SPEED_LIMIT VATTRID_SET(1, 10055)
#define RP_UPSTREAM_SPEED_LIMIT VATTRID_SET(1, 10055)
#define RP_DOWNSTREAM_SPEED_LIMIT VATTRID_SET(2, 10055)
#if defined(LEGACY_RADIUS)
# ifndef PW_DELEGATED_IPV6_PREFIX
# define PW_DELEGATED_IPV6_PREFIX 123
# endif
# ifndef PW_ACCT_INTERIM_INTERVAL
# define PW_ACCT_INTERIM_INTERVAL 85
# endif
#ifndef PW_DELEGATED_IPV6_PREFIX
#define PW_DELEGATED_IPV6_PREFIX 123
#endif
#ifndef PW_ACCT_INTERIM_INTERVAL
#define PW_ACCT_INTERIM_INTERVAL 85
#endif
#endif
#if RADCLI_VERSION_NUMBER < 0x010207
# define CHALLENGE_RC 3
#define CHALLENGE_RC 3
#endif
#define MAX_CHALLENGES 16
@@ -91,19 +92,21 @@ static void radius_vhost_init(void **_vctx, void *pool, void *additional)
}
if (config->nas_identifier) {
strlcpy(vctx->nas_identifier, config->nas_identifier, sizeof(vctx->nas_identifier));
strlcpy(vctx->nas_identifier, config->nas_identifier,
sizeof(vctx->nas_identifier));
} else {
vctx->nas_identifier[0] = 0;
}
if (rc_read_dictionary(vctx->rh, rc_conf_str(vctx->rh, "dictionary")) != 0) {
if (rc_read_dictionary(vctx->rh, rc_conf_str(vctx->rh, "dictionary")) !=
0) {
fprintf(stderr, "error reading the radius dictionary\n");
exit(EXIT_FAILURE);
}
*_vctx = vctx;
return;
fail:
fail:
fprintf(stderr, "radius initialization error\n");
exit(EXIT_FAILURE);
}
@@ -116,15 +119,15 @@ static void radius_vhost_deinit(void *_vctx)
rc_destroy(vctx->rh);
}
static int radius_auth_init(void **ctx, void *pool, void *_vctx, const common_auth_init_st *info)
static int radius_auth_init(void **ctx, void *pool, void *_vctx,
const common_auth_init_st *info)
{
struct radius_ctx_st *pctx;
char *default_realm;
struct radius_vhost_ctx *vctx = _vctx;
if (info->username == NULL || info->username[0] == 0) {
oc_syslog(LOG_NOTICE,
"radius-auth: no username present");
oc_syslog(LOG_NOTICE, "radius-auth: no username present");
return ERR_AUTH_FAIL;
}
@@ -145,38 +148,43 @@ static int radius_auth_init(void **ctx, void *pool, void *_vctx, const common_au
if ((strchr(info->username, '@') == NULL) && default_realm &&
default_realm[0] != 0) {
snprintf(pctx->username, sizeof(pctx->username), "%s@%s", info->username, default_realm);
snprintf(pctx->username, sizeof(pctx->username), "%s@%s",
info->username, default_realm);
} else {
strlcpy(pctx->username, info->username, sizeof(pctx->username));
}
pctx->id = info->id;
if (info->user_agent)
strlcpy(pctx->user_agent, info->user_agent, sizeof(pctx->user_agent));
strlcpy(pctx->user_agent, info->user_agent,
sizeof(pctx->user_agent));
*ctx = pctx;
return ERR_AUTH_CONTINUE;
}
static int radius_auth_group(void *ctx, const char *suggested, char *groupname, int groupname_size)
static int radius_auth_group(void *ctx, const char *suggested, char *groupname,
int groupname_size)
{
struct radius_ctx_st *pctx = ctx;
unsigned i;
unsigned int i;
groupname[0] = 0;
if (suggested != NULL) {
for (i=0;i<pctx->groupnames_size;i++) {
for (i = 0; i < pctx->groupnames_size; i++) {
if (strcmp(suggested, pctx->groupnames[i]) == 0) {
strlcpy(groupname, pctx->groupnames[i], groupname_size);
strlcpy(groupname, pctx->groupnames[i],
groupname_size);
return 0;
}
}
oc_syslog(LOG_NOTICE,
"radius-auth: user '%s' requested group '%s' but is not a member",
pctx->username, suggested);
oc_syslog(
LOG_NOTICE,
"radius-auth: user '%s' requested group '%s' but is not a member",
pctx->username, suggested);
return -1;
}
@@ -193,13 +201,15 @@ static int radius_auth_user(void *ctx, char *username, int username_size)
return -1;
}
static void append_route(struct radius_ctx_st *pctx, const char *route, unsigned len)
static void append_route(struct radius_ctx_st *pctx, const char *route,
unsigned int len)
{
unsigned i;
unsigned int i;
char *p;
/* accept route/mask */
if ((p=strchr(route, '/')) == 0)
p = strchr(route, '/');
if (p == 0)
return;
p = strchr(p, ' ');
@@ -208,10 +218,11 @@ static void append_route(struct radius_ctx_st *pctx, const char *route, unsigned
}
if (pctx->routes_size == 0) {
pctx->routes = talloc_size(pctx, sizeof(char*));
pctx->routes = talloc_size(pctx, sizeof(char *));
} else {
pctx->routes = talloc_realloc_size(pctx, pctx->routes,
(pctx->routes_size+1)*sizeof(char*));
(pctx->routes_size + 1) *
sizeof(char *));
}
if (pctx->routes != NULL) {
@@ -228,11 +239,13 @@ static void parse_groupnames(struct radius_ctx_st *pctx, const char *full)
char *p, *p2;
if (pctx->groupnames_size >= MAX_GROUPS) {
oc_syslog(LOG_WARNING,
"radius-auth: cannot handle more than %d groups, ignoring group string %s",
MAX_GROUPS, full);
oc_syslog(
LOG_WARNING,
"radius-auth: cannot handle more than %d groups, ignoring group string %s",
MAX_GROUPS, full);
} else if (strncmp(full, "OU=", 3) == 0) {
oc_syslog(LOG_DEBUG, "radius-auth: found group string %s", full);
oc_syslog(LOG_DEBUG, "radius-auth: found group string %s",
full);
full += 3;
p = talloc_strdup(pctx, full);
@@ -249,14 +262,16 @@ static void parse_groupnames(struct radius_ctx_st *pctx, const char *full)
if (pctx->groupnames_size == MAX_GROUPS) {
if (p2)
oc_syslog(LOG_WARNING,
"radius-auth: cannot handle more than %d groups, ignoring trailing group(s) %s",
MAX_GROUPS, p2);
oc_syslog(
LOG_WARNING,
"radius-auth: cannot handle more than %d groups, ignoring trailing group(s) %s",
MAX_GROUPS, p2);
break;
}
}
} else {
oc_syslog(LOG_DEBUG, "radius-auth: found group string %s", full);
oc_syslog(LOG_DEBUG, "radius-auth: found group string %s",
full);
p = talloc_strdup(pctx, full);
if (p == NULL)
return;
@@ -266,7 +281,7 @@ static void parse_groupnames(struct radius_ctx_st *pctx, const char *full)
/* Returns 0 if the user is successfully authenticated, and sets the appropriate group name.
*/
static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
static int radius_auth_pass(void *ctx, const char *pass, unsigned int pass_len)
{
struct radius_ctx_st *pctx = ctx;
VALUE_PAIR *send = NULL, *recvd = NULL;
@@ -277,18 +292,24 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
int ret;
/* send Access-Request */
oc_syslog(LOG_DEBUG, "radius-auth: communicating username (%s) and password", pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_USER_NAME, pctx->username, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
oc_syslog(LOG_DEBUG,
"radius-auth: communicating username (%s) and password",
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_USER_NAME, pctx->username,
-1, 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
return ERR_AUTH_FAIL;
}
if (rc_avpair_add(pctx->vctx->rh, &send, PW_USER_PASSWORD, (char*)pass, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_USER_PASSWORD, (char *)pass,
-1, 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
@@ -299,18 +320,24 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
if (inet_pton(AF_INET, pctx->our_ip, &in) != 0) {
in.s_addr = ntohl(in.s_addr);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_NAS_IP_ADDRESS, (char*)&in, sizeof(struct in_addr), 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send,
PW_NAS_IP_ADDRESS, (char *)&in,
sizeof(struct in_addr), 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
} else if (inet_pton(AF_INET6, pctx->our_ip, &in6) != 0) {
if (rc_avpair_add(pctx->vctx->rh, &send, PW_NAS_IPV6_ADDRESS, (char*)&in6, sizeof(struct in6_addr), 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send,
PW_NAS_IPV6_ADDRESS, (char *)&in6,
sizeof(struct in6_addr), 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
@@ -318,56 +345,68 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
}
if (pctx->vctx->nas_identifier[0] != 0) {
if (rc_avpair_add(pctx->vctx->rh, &send, PW_NAS_IDENTIFIER, pctx->vctx->nas_identifier, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_NAS_IDENTIFIER,
pctx->vctx->nas_identifier, -1, 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
}
if (rc_avpair_add(pctx->vctx->rh, &send, PW_CALLING_STATION_ID, pctx->remote_ip, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_CALLING_STATION_ID,
pctx->remote_ip, -1, 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
if (pctx->user_agent[0] != 0) {
if (rc_avpair_add(pctx->vctx->rh, &send, PW_CONNECT_INFO, pctx->user_agent, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_CONNECT_INFO,
pctx->user_agent, -1, 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
}
service = PW_AUTHENTICATE_ONLY;
if (rc_avpair_add(pctx->vctx->rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_SERVICE_TYPE, &service, -1,
0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
service = PW_ASYNC;
if (rc_avpair_add(pctx->vctx->rh, &send, PW_NAS_PORT_TYPE, &service, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_NAS_PORT_TYPE, &service, -1,
0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
if (pctx->state != NULL) {
if (rc_avpair_add(pctx->vctx->rh, &send, PW_STATE, pctx->state, -1, 0) == NULL) {
oc_syslog(LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'", __func__, __LINE__,
pctx->username);
if (rc_avpair_add(pctx->vctx->rh, &send, PW_STATE, pctx->state,
-1, 0) == NULL) {
oc_syslog(
LOG_ERR,
"%s:%u: error in constructing radius message for user '%s'",
__func__, __LINE__, pctx->username);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
@@ -376,7 +415,8 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
}
pctx->pass_msg[0] = 0;
ret = rc_aaa(pctx->vctx->rh, 0, send, &recvd, pctx->pass_msg, 0, PW_ACCESS_REQUEST);
ret = rc_aaa(pctx->vctx->rh, 0, send, &recvd, pctx->pass_msg, 0,
PW_ACCESS_REQUEST);
if (ret == OK_RC) {
uint32_t ipv4;
@@ -385,90 +425,144 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
vp = recvd;
while (vp != NULL) {
if (vp->attribute == PW_SERVICE_TYPE && vp->lvalue != PW_FRAMED) {
oc_syslog(LOG_ERR,
"%s:%u: unknown radius service type '%d'", __func__, __LINE__,
(int)vp->lvalue);
if (vp->attribute == PW_SERVICE_TYPE &&
vp->lvalue != PW_FRAMED) {
oc_syslog(
LOG_ERR,
"%s:%u: unknown radius service type '%d'",
__func__, __LINE__, (int)vp->lvalue);
goto fail;
} else if (vp->attribute == RAD_GROUP_NAME && vp->type == PW_TYPE_STRING) {
} else if (vp->attribute == RAD_GROUP_NAME &&
vp->type == PW_TYPE_STRING) {
/* Group-Name */
parse_groupnames(pctx, vp->strvalue);
} else if (vp->attribute == PW_FRAMED_IPV6_ADDRESS && vp->type == PW_TYPE_IPV6ADDR) {
} else if (vp->attribute == PW_FRAMED_IPV6_ADDRESS &&
vp->type == PW_TYPE_IPV6ADDR) {
/* Framed-IPv6-Address */
if (inet_ntop(AF_INET6, vp->strvalue, pctx->ipv6, sizeof(pctx->ipv6)) != NULL) {
if (inet_ntop(AF_INET6, vp->strvalue,
pctx->ipv6,
sizeof(pctx->ipv6)) != NULL) {
pctx->ipv6_subnet_prefix = 64;
strlcpy(pctx->ipv6_net, pctx->ipv6, sizeof(pctx->ipv6_net));
strlcpy(pctx->ipv6_net, pctx->ipv6,
sizeof(pctx->ipv6_net));
}
} else if (vp->attribute == PW_DELEGATED_IPV6_PREFIX && vp->type == PW_TYPE_IPV6PREFIX) {
} else if (vp->attribute == PW_DELEGATED_IPV6_PREFIX &&
vp->type == PW_TYPE_IPV6PREFIX) {
/* Delegated-IPv6-Prefix */
if (inet_ntop(AF_INET6, vp->strvalue, pctx->ipv6, sizeof(pctx->ipv6)) != NULL) {
if (inet_ntop(AF_INET6, vp->strvalue,
pctx->ipv6,
sizeof(pctx->ipv6)) != NULL) {
memset(ipv6, 0, sizeof(ipv6));
memcpy(ipv6, vp->strvalue+2, vp->lvalue-2);
if (inet_ntop(AF_INET6, ipv6, pctx->ipv6, sizeof(pctx->ipv6)) != NULL) {
pctx->ipv6_subnet_prefix = (unsigned)(unsigned char)vp->strvalue[1];
memcpy(ipv6, vp->strvalue + 2,
vp->lvalue - 2);
if (inet_ntop(AF_INET6, ipv6,
pctx->ipv6,
sizeof(pctx->ipv6)) !=
NULL) {
pctx->ipv6_subnet_prefix =
(unsigned int)(unsigned char)
vp->strvalue[1];
}
}
} else if (vp->attribute == PW_FRAMED_IPV6_PREFIX && vp->type == PW_TYPE_IPV6PREFIX) {
} else if (vp->attribute == PW_FRAMED_IPV6_PREFIX &&
vp->type == PW_TYPE_IPV6PREFIX) {
if (vp->lvalue > 2 && vp->lvalue <= 18) {
/* Framed-IPv6-Prefix */
memset(ipv6, 0, sizeof(ipv6));
memcpy(ipv6, vp->strvalue+2, vp->lvalue-2);
if (inet_ntop(AF_INET6, ipv6, txt, sizeof(txt)) != NULL) {
snprintf(route, sizeof(route), "%s/%u", txt, (unsigned)(unsigned char)vp->strvalue[1]);
append_route(pctx, vp->strvalue, vp->lvalue);
memcpy(ipv6, vp->strvalue + 2,
vp->lvalue - 2);
if (inet_ntop(AF_INET6, ipv6, txt,
sizeof(txt)) != NULL) {
snprintf(
route, sizeof(route),
"%s/%u", txt,
(unsigned int)(unsigned char)
vp->strvalue[1]);
append_route(pctx, vp->strvalue,
vp->lvalue);
}
}
} else if (vp->attribute == PW_DNS_SERVER_IPV6_ADDRESS && vp->type == PW_TYPE_IPV6ADDR) {
} else if (vp->attribute ==
PW_DNS_SERVER_IPV6_ADDRESS &&
vp->type == PW_TYPE_IPV6ADDR) {
/* DNS-Server-IPv6-Address */
if (pctx->ipv6_dns1[0] == 0)
inet_ntop(AF_INET6, vp->strvalue, pctx->ipv6_dns1, sizeof(pctx->ipv6_dns1));
inet_ntop(AF_INET6, vp->strvalue,
pctx->ipv6_dns1,
sizeof(pctx->ipv6_dns1));
else if (pctx->ipv6_dns2[0] == 0)
inet_ntop(AF_INET6, vp->strvalue, pctx->ipv6_dns2, sizeof(pctx->ipv6_dns2));
inet_ntop(AF_INET6, vp->strvalue,
pctx->ipv6_dns2,
sizeof(pctx->ipv6_dns2));
else {
char dst[MAX_IP_STR];
inet_ntop(AF_INET6, vp->strvalue, dst, sizeof(dst));
oc_syslog(LOG_NOTICE, "radius-auth: cannot handle more than 2 DNS servers, ignoring additional DNS server from RADIUS: %s", dst);
inet_ntop(AF_INET6, vp->strvalue, dst,
sizeof(dst));
oc_syslog(
LOG_NOTICE,
"radius-auth: cannot handle more than 2 DNS servers, ignoring additional DNS server from RADIUS: %s",
dst);
}
} else if (vp->attribute == PW_FRAMED_IP_ADDRESS && vp->type == PW_TYPE_IPADDR) {
} else if (vp->attribute == PW_FRAMED_IP_ADDRESS &&
vp->type == PW_TYPE_IPADDR) {
/* Framed-IP-Address */
if (vp->lvalue != 0xffffffff && vp->lvalue != 0xfffffffe) {
if (vp->lvalue != 0xffffffff &&
vp->lvalue != 0xfffffffe) {
/* According to RFC2865 the values above (fe) instruct the
* server to assign an address from the pool of the server,
* and (ff) to assign address as negotiated with the client.
* We don't negotiate with clients.
*/
ipv4 = htonl(vp->lvalue);
inet_ntop(AF_INET, &ipv4, pctx->ipv4, sizeof(pctx->ipv4));
inet_ntop(AF_INET, &ipv4, pctx->ipv4,
sizeof(pctx->ipv4));
}
} else if (vp->attribute == PW_FRAMED_IP_NETMASK && vp->type == PW_TYPE_IPADDR) {
} else if (vp->attribute == PW_FRAMED_IP_NETMASK &&
vp->type == PW_TYPE_IPADDR) {
/* Framed-IP-Netmask */
ipv4 = htonl(vp->lvalue);
inet_ntop(AF_INET, &ipv4, pctx->ipv4_mask, sizeof(pctx->ipv4_mask));
} else if (vp->attribute == MS_PRIMARY_DNS_SERVER && vp->type == PW_TYPE_IPADDR) {
inet_ntop(AF_INET, &ipv4, pctx->ipv4_mask,
sizeof(pctx->ipv4_mask));
} else if (vp->attribute == MS_PRIMARY_DNS_SERVER &&
vp->type == PW_TYPE_IPADDR) {
/* MS-Primary-DNS-Server */
ipv4 = htonl(vp->lvalue);
inet_ntop(AF_INET, &ipv4, pctx->ipv4_dns1, sizeof(pctx->ipv4_dns1));
} else if (vp->attribute == MS_SECONDARY_DNS_SERVER && vp->type == PW_TYPE_IPADDR) {
inet_ntop(AF_INET, &ipv4, pctx->ipv4_dns1,
sizeof(pctx->ipv4_dns1));
} else if (vp->attribute == MS_SECONDARY_DNS_SERVER &&
vp->type == PW_TYPE_IPADDR) {
/* MS-Secondary-DNS-Server */
ipv4 = htonl(vp->lvalue);
inet_ntop(AF_INET, &ipv4, pctx->ipv4_dns2, sizeof(pctx->ipv4_dns2));
} else if (vp->attribute == PW_FRAMED_ROUTE && vp->type == PW_TYPE_STRING) {
inet_ntop(AF_INET, &ipv4, pctx->ipv4_dns2,
sizeof(pctx->ipv4_dns2));
} else if (vp->attribute == PW_FRAMED_ROUTE &&
vp->type == PW_TYPE_STRING) {
/* Framed-Route */
append_route(pctx, vp->strvalue, vp->lvalue);
} else if (vp->attribute == PW_FRAMED_IPV6_ROUTE && vp->type == PW_TYPE_STRING) {
} else if (vp->attribute == PW_FRAMED_IPV6_ROUTE &&
vp->type == PW_TYPE_STRING) {
/* Framed-IPv6-Route */
append_route(pctx, vp->strvalue, vp->lvalue);
} else if (vp->attribute == PW_ACCT_INTERIM_INTERVAL && vp->type == PW_TYPE_INTEGER) {
} else if (vp->attribute == PW_ACCT_INTERIM_INTERVAL &&
vp->type == PW_TYPE_INTEGER) {
pctx->interim_interval_secs = vp->lvalue;
} else if (vp->attribute == PW_SESSION_TIMEOUT && vp->type == PW_TYPE_INTEGER) {
} else if (vp->attribute == PW_SESSION_TIMEOUT &&
vp->type == PW_TYPE_INTEGER) {
pctx->session_timeout_secs = vp->lvalue;
} else if (vp->attribute == RP_UPSTREAM_SPEED_LIMIT && vp->type == PW_TYPE_INTEGER) {
} else if (vp->attribute == RP_UPSTREAM_SPEED_LIMIT &&
vp->type == PW_TYPE_INTEGER) {
pctx->rx_per_sec = vp->lvalue;
} else if (vp->attribute == RP_DOWNSTREAM_SPEED_LIMIT && vp->type == PW_TYPE_INTEGER) {
} else if (vp->attribute == RP_DOWNSTREAM_SPEED_LIMIT &&
vp->type == PW_TYPE_INTEGER) {
pctx->tx_per_sec = vp->lvalue;
} else {
oc_syslog(LOG_DEBUG, "radius-auth: ignoring server's attribute (%u,%u) of type %u",
(unsigned)ATTRID(vp->attribute), (unsigned)VENDOR(vp->attribute), (unsigned)vp->type);
oc_syslog(
LOG_DEBUG,
"radius-auth: ignoring server's attribute (%u,%u) of type %u",
(unsigned int)ATTRID(vp->attribute),
(unsigned int)VENDOR(vp->attribute),
(unsigned int)vp->type);
}
vp = vp->next;
}
@@ -476,47 +570,58 @@ static int radius_auth_pass(void *ctx, const char *pass, unsigned pass_len)
ret = 0;
goto cleanup;
} else if (ret == CHALLENGE_RC) {
vp = recvd;
while (vp != NULL) {
if (vp->attribute == PW_STATE && vp->type == PW_TYPE_STRING) {
if (vp->attribute == PW_STATE &&
vp->type == PW_TYPE_STRING) {
/* State */
if (vp->lvalue > 0)
pctx->state = talloc_strdup(pctx, vp->strvalue);
pctx->state = talloc_strdup(
pctx, vp->strvalue);
pctx->id++;
oc_syslog(LOG_DEBUG, "radius-auth: Access-Challenge response stage %u, State %s", pctx->passwd_counter, vp->strvalue);
oc_syslog(
LOG_DEBUG,
"radius-auth: Access-Challenge response stage %u, State %s",
pctx->passwd_counter, vp->strvalue);
ret = ERR_AUTH_CONTINUE;
}
vp = vp->next;
}
/* PW_STATE or PW_REPLY_MESSAGE is empty or MAX_CHALLENGES limit exceeded */
if ((pctx->pass_msg[0] == 0) || (pctx->state == NULL) || (pctx->passwd_counter >= MAX_CHALLENGES)) {
strlcpy(pctx->pass_msg, pass_msg_failed, sizeof(pctx->pass_msg));
oc_syslog(LOG_ERR, "radius-auth: Access-Challenge with invalid State or Reply-Message, or max number of password requests exceeded");
if ((pctx->pass_msg[0] == 0) || (pctx->state == NULL) ||
(pctx->passwd_counter >= MAX_CHALLENGES)) {
strlcpy(pctx->pass_msg, pass_msg_failed,
sizeof(pctx->pass_msg));
oc_syslog(
LOG_ERR,
"radius-auth: Access-Challenge with invalid State or Reply-Message, or max number of password requests exceeded");
ret = ERR_AUTH_FAIL;
}
goto cleanup;
} else {
fail:
fail:
if (pctx->pass_msg[0] == 0)
strlcpy(pctx->pass_msg, pass_msg_failed, sizeof(pctx->pass_msg));
strlcpy(pctx->pass_msg, pass_msg_failed,
sizeof(pctx->pass_msg));
if (pctx->retries++ < MAX_PASSWORD_TRIES-1 && pctx->passwd_counter == 0) {
if (pctx->retries++ < MAX_PASSWORD_TRIES - 1 &&
pctx->passwd_counter == 0) {
ret = ERR_AUTH_CONTINUE;
goto cleanup;
}
oc_syslog(LOG_NOTICE,
"radius-auth: error authenticating user '%s' (code %d)",
pctx->username, ret);
oc_syslog(
LOG_NOTICE,
"radius-auth: error authenticating user '%s' (code %d)",
pctx->username, ret);
ret = ERR_AUTH_FAIL;
goto cleanup;
}
cleanup:
cleanup:
if (send != NULL)
rc_avpair_free(send);
if (recvd != NULL)
@@ -533,11 +638,11 @@ static int radius_auth_msg(void *ctx, void *pool, passwd_msg_st *pst)
pst->msg_str = talloc_strdup(pool, pctx->pass_msg);
if (pctx->state != NULL) {
/* differentiate password prompts, if the hash of the prompt
* is different.
*/
prompt_hash = hash_any(pctx->pass_msg, strlen(pctx->pass_msg), 0);
prompt_hash =
hash_any(pctx->pass_msg, strlen(pctx->pass_msg), 0);
if (pctx->prev_prompt_hash != prompt_hash)
pctx->passwd_counter++;
pctx->prev_prompt_hash = prompt_hash;
@@ -551,6 +656,7 @@ static int radius_auth_msg(void *ctx, void *pool, passwd_msg_st *pst)
static void radius_auth_deinit(void *ctx)
{
struct radius_ctx_st *pctx = ctx;
talloc_free(pctx);
}

View File

@@ -19,18 +19,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef RADIUS_H
# define RADIUS_H
#define RADIUS_H
# include <sec-mod-auth.h>
# include "common/common.h"
#include <sec-mod-auth.h>
#include "common/common.h"
# ifdef HAVE_RADIUS
#ifdef HAVE_RADIUS
# ifdef LEGACY_RADIUS
# include <freeradius-client.h>
# else
# include <radcli/radcli.h>
# endif
#ifdef LEGACY_RADIUS
#include <freeradius-client.h>
#else
#include <radcli/radcli.h>
#endif
struct radius_vhost_ctx {
rc_handle *rh;
@@ -38,16 +38,16 @@ struct radius_vhost_ctx {
};
struct radius_ctx_st {
char username[MAX_USERNAME_SIZE*2];
char username[MAX_USERNAME_SIZE * 2];
char user_agent[MAX_AGENT_NAME];
char *groupnames[MAX_GROUPS];
unsigned groupnames_size;
unsigned int groupnames_size;
char remote_ip[MAX_IP_STR];
char our_ip[MAX_IP_STR];
unsigned interim_interval_secs;
unsigned session_timeout_secs;
unsigned int interim_interval_secs;
unsigned int session_timeout_secs;
/* variables for configuration */
char ipv4[MAX_IP_STR];
@@ -65,19 +65,19 @@ struct radius_ctx_st {
uint32_t tx_per_sec;
char **routes;
unsigned routes_size;
unsigned int routes_size;
char pass_msg[PW_MAX_MSG_SIZE];
unsigned retries;
unsigned id;
unsigned int retries;
unsigned int id;
struct radius_vhost_ctx *vctx;
char *state;
unsigned passwd_counter;
unsigned int passwd_counter;
size_t prev_prompt_hash;
};
extern const struct auth_mod_st radius_auth_funcs;
# endif
#endif
#endif

View File

@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_COMMON_CONFIG_H
# define OC_COMMON_CONFIG_H
#define OC_COMMON_CONFIG_H
#include <config.h>
#include <vpn.h>
@@ -27,8 +27,9 @@
char *sanitize_config_value(void *pool, const char *value);
int _add_multi_line_val(void *pool, char ***varname, size_t *num,
const char *val);
int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const char *str);
const char *val);
int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports,
const char *str);
#define MAX_SUBOPTIONS 5
@@ -39,7 +40,7 @@ typedef struct subcfg_val_st {
typedef struct gssapi_cfg_st {
char *keytab;
unsigned no_local_map;
unsigned int no_local_map;
time_t ticket_freshness_secs;
int gid_min;
} gssapi_cfg_st;
@@ -58,17 +59,27 @@ typedef struct pam_cfg_st {
int gid_min;
} pam_cfg_st;
#define CHECK_TRUE(str) ((str != NULL && (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0))?1:0)
#define CHECK_TRUE(str) \
((str != NULL && \
(strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0)) ? \
1 : \
0)
struct perm_cfg_st;
void *get_brackets_string1(void *pool, const char *str);
void *gssapi_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str);
void *radius_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str);
void *pam_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str);
void *plain_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str);
void *oidc_get_brackets_string(void * pool, struct perm_cfg_st *config, const char *str);
void *gssapi_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str);
void *radius_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str);
void *pam_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str);
void *plain_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str);
void *oidc_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str);
void parse_kkdcp_string(char *str, int *socktype, char **_port, char **_server, char **_path, char **_realm);
void parse_kkdcp_string(char *str, int *socktype, char **_port, char **_server,
char **_path, char **_realm);
#endif

View File

@@ -22,21 +22,20 @@
#include <talloc.h>
#include "base64-helper.h"
void oc_base64_encode (const char *in, size_t inlen,
char *out, size_t outlen)
void oc_base64_encode(const char *in, size_t inlen, char *out, size_t outlen)
{
unsigned raw = BASE64_ENCODE_RAW_LENGTH(inlen);
if (outlen < raw+1) {
unsigned int raw = BASE64_ENCODE_RAW_LENGTH(inlen);
if (outlen < raw + 1) {
snprintf(out, outlen, "(too long data)");
return;
}
base64_encode_raw((void*)out, inlen, (uint8_t*)in);
base64_encode_raw((void *)out, inlen, (uint8_t *)in);
out[raw] = 0;
}
int
oc_base64_decode(const uint8_t *src, unsigned src_length,
uint8_t *dst, size_t *dst_length)
int oc_base64_decode(const uint8_t *src, unsigned int src_length, uint8_t *dst,
size_t *dst_length)
{
struct base64_decode_ctx ctx;
int ret;
@@ -46,12 +45,14 @@ oc_base64_decode(const uint8_t *src, unsigned src_length,
#ifdef NETTLE_OLD_BASE64_API
{
unsigned int len = *dst_length;
ret = base64_decode_update(&ctx, &len, dst, src_length, src);
if (ret != 0)
*dst_length = len;
}
#else
ret = base64_decode_update(&ctx, dst_length, dst, src_length, (void*)src);
ret = base64_decode_update(&ctx, dst_length, dst, src_length,
(void *)src);
#endif
if (ret == 0)
@@ -60,8 +61,8 @@ oc_base64_decode(const uint8_t *src, unsigned src_length,
return base64_decode_final(&ctx);
}
int oc_base64_decode_alloc(void *pool, const char *in, size_t inlen,
char **out, size_t *outlen)
int oc_base64_decode_alloc(void *pool, const char *in, size_t inlen, char **out,
size_t *outlen)
{
int len, ret;
void *tmp;
@@ -73,7 +74,7 @@ int oc_base64_decode_alloc(void *pool, const char *in, size_t inlen,
return 0;
*outlen = len;
ret = oc_base64_decode((void*)in, inlen, tmp, outlen);
ret = oc_base64_decode((void *)in, inlen, tmp, outlen);
if (ret == 0) {
talloc_free(tmp);
return 0;

View File

@@ -19,20 +19,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef BASE64_HELPER_H
# define BASE64_HELPER_H
#define BASE64_HELPER_H
#include <nettle/base64.h>
/* Prototypes compatible with the gnulib's */
int
oc_base64_decode(const uint8_t *src, unsigned src_length,
uint8_t *dst, size_t *dst_length);
int oc_base64_decode(const uint8_t *src, unsigned int src_length, uint8_t *dst,
size_t *dst_length);
int oc_base64_decode_alloc(void *pool, const char *in, size_t inlen,
char **out, size_t *outlen);
int oc_base64_decode_alloc(void *pool, const char *in, size_t inlen, char **out,
size_t *outlen);
void oc_base64_encode (const char *in, size_t inlen,
char *out, size_t outlen);
void oc_base64_encode(const char *in, size_t inlen, char *out, size_t outlen);
#endif

View File

@@ -35,49 +35,44 @@
open or pipe2 that accept flags like O_CLOEXEC to create DESC
non-inheritable in the first place. */
int
set_cloexec_flag (int desc, bool value)
int set_cloexec_flag(int desc, bool value)
{
#ifdef F_SETFD
int flags = fcntl (desc, F_GETFD, 0);
int flags = fcntl(desc, F_GETFD, 0);
if (0 <= flags)
{
int newflags = (value ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC);
if (flags >= 0) {
int newflags =
(value ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC);
if (flags == newflags
|| fcntl (desc, F_SETFD, newflags) != -1)
return 0;
}
if (flags == newflags || fcntl(desc, F_SETFD, newflags) != -1)
return 0;
}
return -1;
return -1;
#else /* !F_SETFD */
/* Use dup2 to reject invalid file descriptors; the cloexec flag
/* Use dup2 to reject invalid file descriptors; the cloexec flag
will be unaffected. */
if (desc < 0)
{
errno = EBADF;
return -1;
}
if (dup2 (desc, desc) < 0)
/* errno is EBADF here. */
return -1;
if (desc < 0) {
errno = EBADF;
return -1;
}
if (dup2(desc, desc) < 0)
/* errno is EBADF here. */
return -1;
/* There is nothing we can do on this kind of platform. Punt. */
return 0;
/* There is nothing we can do on this kind of platform. Punt. */
return 0;
#endif /* !F_SETFD */
}
/* Duplicates a file handle FD, while marking the copy to be closed
prior to exec or spawn. Returns -1 and sets errno if FD could not
be duplicated. */
int
dup_cloexec (int fd)
int dup_cloexec(int fd)
{
return fcntl (fd, F_DUPFD_CLOEXEC, 0);
return fcntl(fd, F_DUPFD_CLOEXEC, 0);
}

View File

@@ -18,7 +18,7 @@
*/
#ifndef CLOEXEC_H
# define CLOEXEC_H
#define CLOEXEC_H
#include <stdbool.h>
@@ -32,12 +32,12 @@
open or pipe2 that accept flags like O_CLOEXEC to create DESC
non-inheritable in the first place. */
int set_cloexec_flag (int desc, bool value);
int set_cloexec_flag(int desc, bool value);
/* Duplicates a file handle FD, while marking the copy to be closed
prior to exec or spawn. Returns -1 and sets errno if FD could not
be duplicated. */
int dup_cloexec (int fd);
int dup_cloexec(int fd);
#endif /* CLOEXEC_H */

View File

@@ -37,8 +37,8 @@
#include "common/base64-helper.h"
#include "log.h"
int saved_argc = 0;
char **saved_argv = NULL;
int saved_argc;
char **saved_argv;
const char *_vhost_prefix(const char *name)
{
@@ -50,7 +50,8 @@ const char *_vhost_prefix(const char *name)
/* A hash of the input, to a 20-byte output. The goal is one-wayness.
*/
static void safe_hash(const uint8_t *data, unsigned data_size, uint8_t output[20])
static void safe_hash(const uint8_t *data, unsigned int data_size,
uint8_t output[20])
{
struct sha1_ctx ctx;
@@ -60,13 +61,13 @@ static void safe_hash(const uint8_t *data, unsigned data_size, uint8_t output[20
sha1_digest(&ctx, 20, output);
}
char *calc_safe_id(const uint8_t *data, unsigned size, char *output, unsigned output_size)
char *calc_safe_id(const uint8_t *data, unsigned int size, char *output,
unsigned int output_size)
{
uint8_t safe_id[20];
safe_hash(data, size, safe_id);
oc_base64_encode((char*)safe_id, 20, output, output_size);
oc_base64_encode((char *)safe_id, 20, output, output_size);
return output;
}
@@ -74,7 +75,7 @@ char *calc_safe_id(const uint8_t *data, unsigned size, char *output, unsigned ou
/* Note that meaning slightly changes depending on whether we are
* referring to the cookie or the session itself.
*/
const char *ps_status_to_str(int status, unsigned cookie)
const char *ps_status_to_str(int status, unsigned int cookie)
{
switch (status) {
case PS_AUTH_COMPLETED:
@@ -94,7 +95,7 @@ const char *ps_status_to_str(int status, unsigned cookie)
}
}
const char *cmd_request_to_str(unsigned _cmd)
const char *cmd_request_to_str(unsigned int _cmd)
{
cmd_request_t cmd = _cmd;
static char tmp[32];
@@ -172,7 +173,7 @@ const char *cmd_request_to_str(unsigned _cmd)
}
}
const char *discon_reason_to_str(unsigned reason)
const char *discon_reason_to_str(unsigned int reason)
{
static char tmp[32];
@@ -271,7 +272,7 @@ ssize_t force_read(int sockfd, void *buf, size_t len)
return len;
}
ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned sec)
ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned int sec)
{
int left = len;
int ret;
@@ -325,6 +326,7 @@ void set_non_block(int fd)
* https://patchwork.kernel.org/project/qemu-devel/patch/20200331133536.3328-1-linus.walleij@linaro.org/
*/
int e = errno;
oc_syslog(LOG_ERR, "set_non_block: %s", strerror(e));
}
}
@@ -337,11 +339,12 @@ void set_block(int fd)
ret = fcntl(fd, F_SETFL, val & (~O_NONBLOCK));
if (ret == -1) {
int e = errno;
oc_syslog(LOG_ERR, "set_non_block: %s", strerror(e));
}
}
ssize_t recv_timeout(int sockfd, void *buf, size_t len, unsigned sec)
ssize_t recv_timeout(int sockfd, void *buf, size_t len, unsigned int sec)
{
int ret;
struct pollfd pfd;
@@ -362,8 +365,8 @@ ssize_t recv_timeout(int sockfd, void *buf, size_t len, unsigned sec)
return recv(sockfd, buf, len, 0);
}
ssize_t recvmsg_timeout(int sockfd, struct msghdr * msg, int flags,
unsigned sec)
ssize_t recvmsg_timeout(int sockfd, struct msghdr *msg, int flags,
unsigned int sec)
{
int ret;
@@ -391,7 +394,8 @@ ssize_t recvmsg_timeout(int sockfd, struct msghdr * msg, int flags,
return ret;
}
int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout)
int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd,
unsigned int timeout)
{
struct iovec iov[3];
char data[5];
@@ -414,8 +418,9 @@ int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsign
ret = recvmsg_timeout(ifd, &hdr, 0, timeout);
if (ret == -1) {
int e = errno;
oc_syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
strerror(e));
return ERR_BAD_COMMAND;
}
@@ -425,7 +430,7 @@ int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsign
if (rcmd != icmd) {
oc_syslog(LOG_ERR, "%s:%u: expected %d, received %d", __FILE__,
__LINE__, (int)rcmd, (int)icmd);
__LINE__, (int)rcmd, (int)icmd);
return ERR_BAD_COMMAND;
}
@@ -436,7 +441,7 @@ int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsign
ret = force_write(ofd, data, 5);
if (ret != 5) {
oc_syslog(LOG_ERR, "%s:%u: cannot send headers: %s", __FILE__,
__LINE__, strerror(errno));
__LINE__, strerror(errno));
return ERR_BAD_COMMAND;
}
@@ -449,15 +454,17 @@ int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsign
if (ret == -1 || ret == 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
oc_syslog(LOG_ERR, "%s:%u: cannot send between descriptors: %s", __FILE__,
__LINE__, strerror(errno));
oc_syslog(LOG_ERR,
"%s:%u: cannot send between descriptors: %s",
__FILE__, __LINE__, strerror(errno));
return ERR_BAD_COMMAND;
}
ret = force_write(ofd, buf, ret);
if (ret == -1 || ret == 0) {
oc_syslog(LOG_ERR, "%s:%u: cannot send between descriptors: %s", __FILE__,
__LINE__, strerror(errno));
oc_syslog(LOG_ERR,
"%s:%u: cannot send between descriptors: %s",
__FILE__, __LINE__, strerror(errno));
return ERR_BAD_COMMAND;
}
@@ -468,9 +475,8 @@ int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsign
}
/* Sends message + socketfd */
int send_socket_msg(void *pool, int fd, uint8_t cmd,
int socketfd, const void *msg,
pack_size_func get_size, pack_func pack)
int send_socket_msg(void *pool, int fd, uint8_t cmd, int socketfd,
const void *msg, pack_size_func get_size, pack_func pack)
{
struct iovec iov[3];
struct msghdr hdr;
@@ -506,7 +512,7 @@ int send_socket_msg(void *pool, int fd, uint8_t cmd,
packed = talloc_size(pool, length);
if (packed == NULL) {
oc_syslog(LOG_ERR, "%s:%u: memory error", __FILE__,
__LINE__);
__LINE__);
return -1;
}
@@ -516,7 +522,7 @@ int send_socket_msg(void *pool, int fd, uint8_t cmd,
ret = pack(msg, packed);
if (ret == 0) {
oc_syslog(LOG_ERR, "%s:%u: packing error", __FILE__,
__LINE__);
__LINE__);
ret = -1;
goto cleanup;
}
@@ -540,17 +546,19 @@ int send_socket_msg(void *pool, int fd, uint8_t cmd,
} while (ret == -1 && errno == EINTR);
if (ret < 0) {
int e = errno;
oc_syslog(LOG_ERR, "%s:%u: %s", __FILE__, __LINE__, strerror(e));
oc_syslog(LOG_ERR, "%s:%u: %s", __FILE__, __LINE__,
strerror(e));
}
cleanup:
cleanup:
if (length > 0)
safe_memset(packed, 0, length);
talloc_free(packed);
return ret;
}
int recv_msg_headers(int fd, uint8_t *cmd, unsigned timeout)
int recv_msg_headers(int fd, uint8_t *cmd, unsigned int timeout)
{
struct iovec iov[3];
char buffer[5];
@@ -568,8 +576,9 @@ int recv_msg_headers(int fd, uint8_t *cmd, unsigned timeout)
ret = recvmsg_timeout(fd, &hdr, 0, timeout);
if (ret == -1) {
int e = errno;
oc_syslog(LOG_WARNING, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
strerror(e));
return ERR_BAD_COMMAND;
}
@@ -612,8 +621,9 @@ int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size,
ret = recvmsg_timeout(fd, &hdr, 0, MAIN_SEC_MOD_TIMEOUT);
if (ret == -1) {
int e = errno;
oc_syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
strerror(e));
return ERR_BAD_COMMAND;
}
@@ -625,24 +635,28 @@ int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size,
if (received_fd != NULL) {
*received_fd = -1;
if ((cmptr = CMSG_FIRSTHDR(&hdr)) != NULL
&& cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET
|| cmptr->cmsg_type != SCM_RIGHTS) {
oc_syslog(LOG_ERR,
"%s:%u: recvmsg returned invalid msg type",
__FILE__, __LINE__);
if ((cmptr = CMSG_FIRSTHDR(&hdr)) != NULL &&
cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET ||
cmptr->cmsg_type != SCM_RIGHTS) {
oc_syslog(
LOG_ERR,
"%s:%u: recvmsg returned invalid msg type",
__FILE__, __LINE__);
return ERR_BAD_COMMAND;
}
if (CMSG_DATA(cmptr))
memcpy(received_fd, CMSG_DATA(cmptr), sizeof(int));
memcpy(received_fd, CMSG_DATA(cmptr),
sizeof(int));
}
}
if (l32 > data_size) {
oc_syslog(LOG_ERR, "%s:%u: recv_msg_data: received more data than expected", __FILE__,
__LINE__);
oc_syslog(
LOG_ERR,
"%s:%u: recv_msg_data: received more data than expected",
__FILE__, __LINE__);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
@@ -650,15 +664,16 @@ int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size,
ret = force_read_timeout(fd, data, l32, MAIN_SEC_MOD_TIMEOUT);
if (ret < l32) {
int e = errno;
oc_syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__,
__LINE__, strerror(e));
oc_syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
ret = ERR_BAD_COMMAND;
goto cleanup;
}
ret = l32;
cleanup:
cleanup:
if (ret < 0 && received_fd != NULL && *received_fd != -1) {
close(*received_fd);
*received_fd = -1;
@@ -666,9 +681,8 @@ int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size,
return ret;
}
int recv_socket_msg(void *pool, int fd, uint8_t cmd,
int *socketfd, void **msg, unpack_func unpack,
unsigned timeout)
int recv_socket_msg(void *pool, int fd, uint8_t cmd, int *socketfd, void **msg,
unpack_func unpack, unsigned int timeout)
{
struct iovec iov[3];
uint32_t length;
@@ -681,6 +695,7 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
} control_un;
struct cmsghdr *cmptr;
int ret;
PROTOBUF_ALLOCATOR(pa, pool);
iov[0].iov_base = &rcmd;
@@ -699,8 +714,9 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
ret = recvmsg_timeout(fd, &hdr, 0, timeout);
if (ret == -1) {
int e = errno;
oc_syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
strerror(e));
return ERR_BAD_COMMAND;
}
@@ -710,19 +726,20 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
if (rcmd != cmd) {
oc_syslog(LOG_ERR, "%s:%u: expected %d, received %d", __FILE__,
__LINE__, (int)rcmd, (int)cmd);
__LINE__, (int)rcmd, (int)cmd);
return ERR_BAD_COMMAND;
}
/* try to receive socket (if any) */
if (socketfd != NULL) {
if ((cmptr = CMSG_FIRSTHDR(&hdr)) != NULL
&& cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET
|| cmptr->cmsg_type != SCM_RIGHTS) {
oc_syslog(LOG_ERR,
"%s:%u: recvmsg returned invalid msg type",
__FILE__, __LINE__);
if ((cmptr = CMSG_FIRSTHDR(&hdr)) != NULL &&
cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET ||
cmptr->cmsg_type != SCM_RIGHTS) {
oc_syslog(
LOG_ERR,
"%s:%u: recvmsg returned invalid msg type",
__FILE__, __LINE__);
return ERR_BAD_COMMAND;
}
@@ -745,8 +762,9 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
ret = force_read_timeout(fd, data, length, timeout);
if (ret < length) {
int e = errno;
oc_syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__,
__LINE__, strerror(e));
__LINE__, strerror(e));
ret = ERR_BAD_COMMAND;
goto cleanup;
}
@@ -754,7 +772,7 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
*msg = unpack(&pa, length, data);
if (*msg == NULL) {
oc_syslog(LOG_ERR, "%s:%u: unpacking error", __FILE__,
__LINE__);
__LINE__);
ret = ERR_MEM;
goto cleanup;
}
@@ -762,7 +780,7 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
ret = 0;
cleanup:
cleanup:
talloc_free(data);
if (ret < 0 && socketfd != NULL && *socketfd != -1) {
close(*socketfd);
@@ -771,7 +789,6 @@ int recv_socket_msg(void *pool, int fd, uint8_t cmd,
return ret;
}
void _talloc_free2(void *ctx, void *ptr)
{
talloc_free(ptr);
@@ -788,8 +805,8 @@ void *_talloc_size2(void *ctx, size_t size)
* in our_addr.
*/
ssize_t oc_recvfrom_at(int sockfd, void *buf, size_t len, int flags,
struct sockaddr * src_addr, socklen_t * addrlen,
struct sockaddr * our_addr, socklen_t * our_addrlen,
struct sockaddr *src_addr, socklen_t *addrlen,
struct sockaddr *our_addr, socklen_t *our_addrlen,
int def_port)
{
int ret;
@@ -816,13 +833,13 @@ ssize_t oc_recvfrom_at(int sockfd, void *buf, size_t len, int flags,
for (cmsg = CMSG_FIRSTHDR(&mh); cmsg != NULL;
cmsg = CMSG_NXTHDR(&mh, cmsg)) {
#if defined(IP_PKTINFO)
if (cmsg->cmsg_level == IPPROTO_IP
&& cmsg->cmsg_type == IP_PKTINFO) {
if (cmsg->cmsg_level == IPPROTO_IP &&
cmsg->cmsg_type == IP_PKTINFO) {
struct in_pktinfo *pi = (void *)CMSG_DATA(cmsg);
struct sockaddr_in *a = (struct sockaddr_in *)our_addr;
if (*our_addrlen < sizeof(struct sockaddr_in)
|| pi == NULL)
if (*our_addrlen < sizeof(struct sockaddr_in) ||
pi == NULL)
return -1;
a->sin_family = AF_INET;
@@ -833,13 +850,13 @@ ssize_t oc_recvfrom_at(int sockfd, void *buf, size_t len, int flags,
break;
}
#elif defined(IP_RECVDSTADDR)
if (cmsg->cmsg_level == IPPROTO_IP
&& cmsg->cmsg_type == IP_RECVDSTADDR) {
if (cmsg->cmsg_level == IPPROTO_IP &&
cmsg->cmsg_type == IP_RECVDSTADDR) {
struct in_addr *pi = (void *)CMSG_DATA(cmsg);
struct sockaddr_in *a = (struct sockaddr_in *)our_addr;
if (*our_addrlen < sizeof(struct sockaddr_in)
|| pi == NULL)
if (*our_addrlen < sizeof(struct sockaddr_in) ||
pi == NULL)
return -1;
a->sin_family = AF_INET;
@@ -851,14 +868,14 @@ ssize_t oc_recvfrom_at(int sockfd, void *buf, size_t len, int flags,
}
#endif
#ifdef IPV6_RECVPKTINFO
if (cmsg->cmsg_level == IPPROTO_IPV6
&& cmsg->cmsg_type == IPV6_PKTINFO) {
if (cmsg->cmsg_level == IPPROTO_IPV6 &&
cmsg->cmsg_type == IPV6_PKTINFO) {
struct in6_pktinfo *pi = (void *)CMSG_DATA(cmsg);
struct sockaddr_in6 *a =
(struct sockaddr_in6 *)our_addr;
(struct sockaddr_in6 *)our_addr;
if (*our_addrlen < sizeof(struct sockaddr_in6)
|| pi == NULL)
if (*our_addrlen < sizeof(struct sockaddr_in6) ||
pi == NULL)
return -1;
a->sin6_family = AF_INET6;
@@ -917,11 +934,12 @@ size_t oc_strlcpy(char *dst, char const *src, size_t siz)
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++) ;
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return (s - src - 1); /* count does not include NUL */
return (s - src - 1); /* count does not include NUL */
}
#endif

View File

@@ -20,7 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef COMMON_H
# define COMMON_H
#define COMMON_H
#include <sys/socket.h>
#include <netinet/in.h>
@@ -40,15 +40,17 @@ void *_talloc_size2(void *ctx, size_t size);
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define PROTOBUF_ALLOCATOR(name, pool) \
ProtobufCAllocator name = {.alloc = _talloc_size2, .free = _talloc_free2, .allocator_data = pool}
#define PROTOBUF_ALLOCATOR(name, pool) \
ProtobufCAllocator name = { .alloc = _talloc_size2, \
.free = _talloc_free2, \
.allocator_data = pool }
#ifndef MIN
# define MIN(x,y) (((x)<(y))?(x):(y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
# define MAX(x,y) (((x)>(y))?(x):(y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
void set_non_block(int fd);
@@ -56,56 +58,53 @@ void set_block(int fd);
ssize_t force_write(int sockfd, const void *buf, size_t len);
ssize_t force_read(int sockfd, void *buf, size_t len);
ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned sec);
ssize_t recv_timeout(int sockfd, void *buf, size_t len, unsigned sec);
ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned int sec);
ssize_t recv_timeout(int sockfd, void *buf, size_t len, unsigned int sec);
typedef size_t (*pack_func)(const void*, uint8_t *);
typedef size_t (*pack_size_func)(const void*);
typedef size_t (*pack_func)(const void *, uint8_t *);
typedef size_t (*pack_size_func)(const void *);
typedef void* (*unpack_func)(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
typedef void *(*unpack_func)(ProtobufCAllocator *allocator, size_t len,
const uint8_t *data);
int send_socket_msg(void *pool, int fd, uint8_t cmd,
int socketfd,
const void* msg, pack_size_func get_size, pack_func pack);
int send_socket_msg(void *pool, int fd, uint8_t cmd, int socketfd,
const void *msg, pack_size_func get_size, pack_func pack);
int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout);
int forward_msg(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd,
unsigned int timeout);
inline static
int send_msg(void *pool, int fd, uint8_t cmd,
const void *msg, pack_size_func get_size, pack_func pack)
inline static int send_msg(void *pool, int fd, uint8_t cmd, const void *msg,
pack_size_func get_size, pack_func pack)
{
return send_socket_msg(pool, fd, cmd, -1, msg, get_size, pack);
}
int recv_socket_msg(void *pool, int fd, uint8_t cmd, int *socketfd, void **msg,
unpack_func, unsigned int timeout);
int recv_socket_msg(void *pool, int fd, uint8_t cmd,
int *socketfd, void** msg, unpack_func, unsigned timeout);
inline static int recv_msg(void *pool, int fd, uint8_t cmd,
void **msg, unpack_func unpack, unsigned timeout)
inline static int recv_msg(void *pool, int fd, uint8_t cmd, void **msg,
unpack_func unpack, unsigned int timeout)
{
return recv_socket_msg(pool, fd, cmd, NULL, msg, unpack, timeout);
}
int recv_msg_headers(int fd, uint8_t *cmd, unsigned timeout);
int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size, int *received_fd);
int recv_msg_headers(int fd, uint8_t *cmd, unsigned int timeout);
int recv_msg_data(int fd, uint8_t *cmd, uint8_t *data, size_t data_size,
int *received_fd);
const char* cmd_request_to_str(unsigned cmd);
const char* discon_reason_to_str(unsigned reason);
unsigned int discon_reason_to_log_level(unsigned reason);
const char *cmd_request_to_str(unsigned int cmd);
const char *discon_reason_to_str(unsigned int reason);
unsigned int discon_reason_to_log_level(unsigned int reason);
ssize_t oc_recvfrom_at(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen,
struct sockaddr *our_addr, socklen_t *our_addrlen,
int def_port);
struct sockaddr *src_addr, socklen_t *addrlen,
struct sockaddr *our_addr, socklen_t *our_addrlen,
int def_port);
inline static
void safe_memset(void *data, int c, size_t size)
inline static void safe_memset(void *data, int c, size_t size)
{
volatile unsigned volatile_zero = 0;
volatile char *vdata = (volatile char*)data;
volatile char *vdata = (volatile char *)data;
/* This is based on a nice trick for safe memset,
* sent by David Jacobson in the openssl-dev mailing list.
@@ -117,8 +116,7 @@ void safe_memset(void *data, int c, size_t size)
} while (vdata[volatile_zero] != c);
}
inline static
void ms_sleep(unsigned ms)
inline static void ms_sleep(unsigned int ms)
{
struct timespec tv;
int ret;
@@ -136,17 +134,18 @@ void ms_sleep(unsigned ms)
} while (ret == -1 && errno == EINTR);
}
const char *ps_status_to_str(int status, unsigned cookie);
const char *ps_status_to_str(int status, unsigned int cookie);
const char *_vhost_prefix(const char *name);
#ifndef HAVE_STRLCPY
size_t oc_strlcpy(char *dst, char const *src, size_t siz);
# define strlcpy oc_strlcpy
#define strlcpy oc_strlcpy
#endif
#define SAFE_ID_SIZE (BASE64_ENCODE_RAW_LENGTH(20)+1)
char *calc_safe_id(const uint8_t *data, unsigned size, char *output, unsigned output_size);
#define SAFE_ID_SIZE (BASE64_ENCODE_RAW_LENGTH(20) + 1)
char *calc_safe_id(const uint8_t *data, unsigned int size, char *output,
unsigned int output_size);
extern int saved_argc;
extern char **saved_argv;

View File

@@ -30,13 +30,14 @@
#include <hmac.h>
#include <stdbool.h>
bool hmac_init_key(size_t key_length, uint8_t * key)
bool hmac_init_key(size_t key_length, uint8_t *key)
{
return gnutls_rnd(GNUTLS_RND_RANDOM, key, key_length) == 0;
}
void generate_hmac(size_t key_length, const uint8_t * key, size_t component_count,
const hmac_component_st * components, uint8_t digest[HMAC_DIGEST_SIZE])
void generate_hmac(size_t key_length, const uint8_t *key,
size_t component_count, const hmac_component_st *components,
uint8_t digest[HMAC_DIGEST_SIZE])
{
struct hmac_sha256_ctx ctx;
size_t i;
@@ -44,10 +45,8 @@ void generate_hmac(size_t key_length, const uint8_t * key, size_t component_coun
hmac_sha256_set_key(&ctx, key_length, key);
for (i = 0; i < component_count; i++) {
if (components[i].data) {
hmac_sha256_update(&ctx,
components[i].length,
hmac_sha256_update(&ctx, components[i].length,
(const uint8_t *)components[i].data);
}
}

View File

@@ -19,21 +19,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef HMAC_H
#define HMAC_H
#include <stdbool.h>
#define HMAC_DIGEST_SIZE 32
bool hmac_init_key(size_t key_length, uint8_t * key);
bool hmac_init_key(size_t key_length, uint8_t *key);
typedef struct hmac_component_st {
typedef struct hmac_component_st {
size_t length;
void * data;
void *data;
} hmac_component_st;
void generate_hmac(size_t key_length, const uint8_t * key, size_t component_count,
const hmac_component_st * components, uint8_t digest[HMAC_DIGEST_SIZE]);
void generate_hmac(size_t key_length, const uint8_t *key,
size_t component_count, const hmac_component_st *components,
uint8_t digest[HMAC_DIGEST_SIZE]);
#endif

View File

@@ -61,7 +61,8 @@ static size_t snapshot_hash_filename(const char *file_name)
static size_t snapshot_rehash(const void *elem, void *priv)
{
snapshot_entry_t *entry = (snapshot_entry_t *) elem;
snapshot_entry_t *entry = (snapshot_entry_t *)elem;
return snapshot_hash_filename(entry->name);
}
@@ -71,6 +72,7 @@ static snapshot_entry_t *snapshot_find(struct snapshot_t *snapshot,
struct htable_iter iter;
size_t hash = snapshot_hash_filename(filename);
snapshot_entry_t *entry = htable_firstval(&snapshot->ht, &iter, hash);
while (entry != NULL) {
if (strcmp(entry->name, filename) == 0) {
break;
@@ -84,6 +86,7 @@ static int snapshot_file_name_from_fd(int fd, char *file_name,
size_t file_name_length)
{
int ret = snprintf(file_name, file_name_length, "/proc/self/fd/%d", fd);
if (ret >= file_name_length) {
return -1;
} else {
@@ -91,29 +94,28 @@ static int snapshot_file_name_from_fd(int fd, char *file_name,
}
}
static int snapshot_add_entry(snapshot_t * snapshot, const char *filename,
static int snapshot_add_entry(snapshot_t *snapshot, const char *filename,
int fd)
{
int retval = -1;
snapshot_entry_t *entry = NULL;
size_t file_name_length = strlen(filename) + 1;
entry =
(snapshot_entry_t *) talloc_zero_array(snapshot->pool, char,
sizeof(uint32_t) +
file_name_length);
entry = (snapshot_entry_t *)talloc_zero_array(
snapshot->pool, char, sizeof(uint32_t) + file_name_length);
if (entry == NULL)
goto cleanup;
entry->fd = fd;
strlcpy((char *)entry->name, filename, file_name_length);
if (!htable_add
(&snapshot->ht, snapshot_hash_filename(entry->name), entry))
if (!htable_add(&snapshot->ht, snapshot_hash_filename(entry->name),
entry))
goto cleanup;
entry = NULL;
retval = 0;
cleanup:
cleanup:
if (entry)
talloc_free(entry);
@@ -138,12 +140,11 @@ int snapshot_init(void *pool, struct snapshot_t **snapshot, const char *prefix)
new_snapshot->pool = pool;
new_snapshot->tmp_filename_template =
talloc_array(pool, char, tmp_filename_template_length);
talloc_array(pool, char, tmp_filename_template_length);
if (snprintf
((char *)new_snapshot->tmp_filename_template,
tmp_filename_template_length, "%sXXXXXX",
prefix) >= tmp_filename_template_length)
if (snprintf((char *)new_snapshot->tmp_filename_template,
tmp_filename_template_length, "%sXXXXXX",
prefix) >= tmp_filename_template_length)
goto cleanup;
htable_init(&new_snapshot->ht, snapshot_rehash, new_snapshot);
@@ -151,11 +152,11 @@ int snapshot_init(void *pool, struct snapshot_t **snapshot, const char *prefix)
*snapshot = new_snapshot;
new_snapshot = NULL;
cleanup:
cleanup:
if (new_snapshot != NULL) {
if (new_snapshot->tmp_filename_template != NULL)
talloc_free((char *)new_snapshot->
tmp_filename_template);
talloc_free(
(char *)new_snapshot->tmp_filename_template);
talloc_free(new_snapshot);
}
@@ -170,6 +171,7 @@ void snapshot_terminate(struct snapshot_t *snapshot)
{
struct htable_iter iter;
snapshot_entry_t *entry = htable_first(&snapshot->ht, &iter);
while (entry != NULL) {
htable_delval(&snapshot->ht, &iter);
close(entry->fd);
@@ -203,6 +205,7 @@ int snapshot_create(struct snapshot_t *snapshot, const char *filename)
fd_out = mkstemp(tmp_file_name);
if (fd_out == -1) {
int err = errno;
fprintf(stderr, ERRSTR "cannot create temp file '%s' : %s\n",
tmp_file_name, strerror(err));
goto cleanup;
@@ -213,10 +216,12 @@ int snapshot_create(struct snapshot_t *snapshot, const char *filename)
for (;;) {
int byteRead = read(fd_in, buffer, sizeof(buffer));
int bytesWritten;
if (byteRead == 0) {
break;
} else if (byteRead == -1) {
int err = errno;
fprintf(stderr, ERRSTR " reading %s failed %s\n",
filename, strerror(err));
goto cleanup;
@@ -224,6 +229,7 @@ int snapshot_create(struct snapshot_t *snapshot, const char *filename)
bytesWritten = write(fd_out, buffer, byteRead);
if (bytesWritten != byteRead) {
int err = errno;
fprintf(stderr,
ERRSTR " writing %s failed %s\n",
tmp_file_name, strerror(err));
@@ -250,7 +256,7 @@ int snapshot_create(struct snapshot_t *snapshot, const char *filename)
ret = 0;
entry = NULL;
cleanup:
cleanup:
if (fd_in != -1)
close(fd_in);
@@ -264,6 +270,7 @@ int snapshot_first(struct snapshot_t *snapshot, struct htable_iter *iter,
int *fd, const char **file_name)
{
snapshot_entry_t *entry = htable_first(&snapshot->ht, iter);
if (entry == NULL) {
return -1;
} else {
@@ -277,6 +284,7 @@ int snapshot_next(struct snapshot_t *snapshot, struct htable_iter *iter,
int *fd, const char **file_name)
{
snapshot_entry_t *entry = htable_next(&snapshot->ht, iter);
if (entry == NULL) {
return -1;
} else {
@@ -290,13 +298,14 @@ int snapshot_restore_entry(struct snapshot_t *snapshot, int fd,
const char *file_name)
{
int ret = snapshot_add_entry(snapshot, file_name, fd);
if (ret < 0)
return ret;
return 0;
}
size_t snapshot_entry_count(struct snapshot_t * snapshot)
size_t snapshot_entry_count(struct snapshot_t *snapshot)
{
struct htable_iter iter;
size_t count = 0;
@@ -317,6 +326,7 @@ int snapshot_lookup_filename(struct snapshot_t *snapshot, const char *file_name,
char fd_path[128];
char *new_file_name = NULL;
snapshot_entry_t *entry = snapshot_find(snapshot, file_name);
if (entry == NULL)
goto cleanup;
@@ -332,7 +342,7 @@ int snapshot_lookup_filename(struct snapshot_t *snapshot, const char *file_name,
ret = 0;
cleanup:
cleanup:
if (new_file_name != NULL)
talloc_free(new_file_name);

View File

@@ -37,32 +37,23 @@
static int send_query(int fd, int inode, int states, int show)
{
int err;
struct sockaddr_nl nladdr = {
.nl_family = AF_NETLINK
};
struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
struct {
struct nlmsghdr nlh;
struct unix_diag_req udr;
} req = {
.nlh = {
.nlmsg_len = sizeof(req),.nlmsg_type =
SOCK_DIAG_BY_FAMILY,.nlmsg_flags =
NLM_F_REQUEST | (inode ? 0 : NLM_F_DUMP)
}
,.udr = {
.sdiag_family = AF_UNIX,.udiag_states =
states,.udiag_show = show,.udiag_ino = inode}
};
struct iovec iov = {
.iov_base = &req,
.iov_len = sizeof(req)
};
struct msghdr msg = {
.msg_name = (void *)&nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
};
} req = { .nlh = { .nlmsg_len = sizeof(req),
.nlmsg_type = SOCK_DIAG_BY_FAMILY,
.nlmsg_flags = NLM_F_REQUEST |
(inode ? 0 : NLM_F_DUMP) },
.udr = { .sdiag_family = AF_UNIX,
.udiag_states = states,
.udiag_show = show,
.udiag_ino = inode } };
struct iovec iov = { .iov_base = &req, .iov_len = sizeof(req) };
struct msghdr msg = { .msg_name = (void *)&nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1 };
for (;;) {
if (sendmsg(fd, &msg, 0) < 0) {
@@ -78,7 +69,7 @@ static int send_query(int fd, int inode, int states, int show)
}
}
typedef int (*process_response)(const struct unix_diag_msg * diag,
typedef int (*process_response)(const struct unix_diag_msg *diag,
unsigned int len, void *context);
struct match_name_context {
@@ -95,12 +86,12 @@ static int match_name(const struct unix_diag_msg *diag, unsigned int len,
struct rtattr *attr;
unsigned int rta_len = len - NLMSG_LENGTH(sizeof(*diag));
size_t path_len = 0;
char path[sizeof(((struct sockaddr_un *) 0)->sun_path) + 1];
char path[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
struct unix_diag_rqlen rqlen;
int rqlen_valid = 0;
for (attr = (struct rtattr *)(diag + 1);
RTA_OK(attr, rta_len); attr = RTA_NEXT(attr, rta_len)) {
for (attr = (struct rtattr *)(diag + 1); RTA_OK(attr, rta_len);
attr = RTA_NEXT(attr, rta_len)) {
switch (attr->rta_type) {
case UNIX_DIAG_NAME:
if (!path_len) {
@@ -142,22 +133,15 @@ static int receive_responses(int fd, process_response process, void *context)
{
int err;
long buf[8192 / sizeof(long)];
struct sockaddr_nl nladdr = {
.nl_family = AF_NETLINK
};
struct iovec iov = {
.iov_base = buf,
.iov_len = sizeof(buf)
};
struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) };
int flags = 0;
for (;;) {
struct msghdr msg = {
.msg_name = (void *)&nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1
};
struct msghdr msg = { .msg_name = (void *)&nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1 };
ssize_t ret = recvmsg(fd, &msg, flags);
@@ -191,12 +175,14 @@ static int receive_responses(int fd, process_response process, void *context)
const struct nlmsgerr *err = NLMSG_DATA(h);
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) {
oc_syslog(LOG_ERR,
"nlmsg_type NLMSG_ERROR has short nlmsg_len %d",
h->nlmsg_len);
oc_syslog(
LOG_ERR,
"nlmsg_type NLMSG_ERROR has short nlmsg_len %d",
h->nlmsg_len);
} else {
oc_syslog(LOG_ERR, "NLM query failed %s",
strerror(-err->error));
oc_syslog(LOG_ERR,
"NLM query failed %s",
strerror(-err->error));
}
return -1;
@@ -204,22 +190,23 @@ static int receive_responses(int fd, process_response process, void *context)
if (h->nlmsg_type != SOCK_DIAG_BY_FAMILY) {
oc_syslog(LOG_ERR, "unexpected nlmsg_type %u\n",
(unsigned)h->nlmsg_type);
(unsigned int)h->nlmsg_type);
return -1;
}
diag = (const struct unix_diag_msg *)NLMSG_DATA(h);
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*diag))) {
oc_syslog(LOG_ERR,
"nlmsg_type SOCK_DIAG_BY_FAMILY has short nlmsg_len %d",
h->nlmsg_len);
oc_syslog(
LOG_ERR,
"nlmsg_type SOCK_DIAG_BY_FAMILY has short nlmsg_len %d",
h->nlmsg_len);
return -1;
}
if (diag->udiag_family != AF_UNIX) {
oc_syslog(LOG_ERR, "unexpected family %u\n",
diag->udiag_family);
diag->udiag_family);
return -1;
}
@@ -235,10 +222,7 @@ int sockdiag_query_unix_domain_socket_queue_length(const char *socket_name,
{
int err;
int ret = -1;
struct match_name_context ctx = {
.name = socket_name,
.inode = 0
};
struct match_name_context ctx = { .name = socket_name, .inode = 0 };
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
@@ -248,8 +232,8 @@ int sockdiag_query_unix_domain_socket_queue_length(const char *socket_name,
goto cleanup;
}
if (send_query
(fd, 0, 1 << TCP_LISTEN, UDIAG_SHOW_NAME | UDIAG_SHOW_RQLEN))
if (send_query(fd, 0, 1 << TCP_LISTEN,
UDIAG_SHOW_NAME | UDIAG_SHOW_RQLEN))
goto cleanup;
if (receive_responses(fd, match_name, &ctx))
@@ -260,7 +244,7 @@ int sockdiag_query_unix_domain_socket_queue_length(const char *socket_name,
ret = 0;
cleanup:
cleanup:
if (fd >= 0) {
close(fd);
}

View File

@@ -24,6 +24,8 @@
#include <config.h>
int sockdiag_query_unix_domain_socket_queue_length(const char * socket_name, int * sock_rqueue, int * sock_wqueue);
int sockdiag_query_unix_domain_socket_queue_length(const char *socket_name,
int *sock_rqueue,
int *sock_wqueue);
#endif

View File

@@ -21,7 +21,7 @@
#include <system.h>
#include <unistd.h>
#ifdef __linux__
# include <sys/prctl.h>
#include <sys/prctl.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
@@ -47,8 +47,9 @@ void pr_set_undumpable(const char *mod)
#ifdef __linux__
if (prctl(PR_SET_DUMPABLE, 0) == -1) {
int e = errno;
oc_syslog(LOG_ERR, "%s: prctl(PR_SET_DUMPABLE) failed %s",
mod, strerror(e));
oc_syslog(LOG_ERR, "%s: prctl(PR_SET_DUMPABLE) failed %s", mod,
strerror(e));
}
#endif
}
@@ -60,17 +61,18 @@ SIGHANDLER_T ocsignal(int signum, SIGHANDLER_T handler)
memset(&new_action, 0, sizeof(new_action));
new_action.sa_handler = handler;
sigemptyset (&new_action.sa_mask);
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (signum, &new_action, &old_action);
sigaction(signum, &new_action, &old_action);
return old_action.sa_handler;
}
/* Checks whether the peer in a socket has the expected @uid and @gid.
* Returns zero on success.
*/
int check_upeer_id(const char *mod, int debug, int cfd, uid_t uid, uid_t gid, uid_t *ruid, pid_t *pid)
int check_upeer_id(const char *mod, int debug, int cfd, uid_t uid, uid_t gid,
uid_t *ruid, pid_t *pid)
{
int e, ret;
#if defined(SO_PEERCRED) && defined(HAVE_STRUCT_UCRED)
@@ -85,15 +87,15 @@ int check_upeer_id(const char *mod, int debug, int cfd, uid_t uid, uid_t gid, ui
ret = getsockopt(cfd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len);
if (ret == -1) {
e = errno;
oc_syslog(LOG_ERR, "%s: getsockopt SO_PEERCRED error: %s",
mod, strerror(e));
oc_syslog(LOG_ERR, "%s: getsockopt SO_PEERCRED error: %s", mod,
strerror(e));
return -1;
}
if (debug >= OCLOG_DEBUG)
oc_syslog(LOG_DEBUG,
"%s: received request from pid %u and uid %u",
mod, (unsigned)cr.pid, (unsigned)cr.uid);
"%s: received request from pid %u and uid %u", mod,
(unsigned int)cr.pid, (unsigned int)cr.uid);
if (ruid)
*ruid = cr.uid;
@@ -102,10 +104,11 @@ int check_upeer_id(const char *mod, int debug, int cfd, uid_t uid, uid_t gid, ui
*pid = cr.pid;
if (cr.uid != 0 && (cr.uid != uid || cr.gid != gid)) {
oc_syslog(LOG_ERR,
"%s: received unauthorized request from pid %u and uid %u",
mod, (unsigned)cr.pid, (unsigned)cr.uid);
return -1;
oc_syslog(
LOG_ERR,
"%s: received unauthorized request from pid %u and uid %u",
mod, (unsigned int)cr.pid, (unsigned int)cr.uid);
return -1;
}
#elif defined(HAVE_GETPEEREID)
uid_t euid;
@@ -115,8 +118,8 @@ int check_upeer_id(const char *mod, int debug, int cfd, uid_t uid, uid_t gid, ui
if (ret == -1) {
e = errno;
oc_syslog(LOG_DEBUG, "%s: getpeereid error: %s",
mod, strerror(e));
oc_syslog(LOG_DEBUG, "%s: getpeereid error: %s", mod,
strerror(e));
return -1;
}
@@ -128,14 +131,15 @@ int check_upeer_id(const char *mod, int debug, int cfd, uid_t uid, uid_t gid, ui
if (debug >= OCLOG_DEBUG)
oc_syslog(LOG_DEBUG,
"%s: received request from a processes with uid %u",
mod, (unsigned)euid);
"%s: received request from a processes with uid %u",
mod, (unsigned int)euid);
if (euid != 0 && (euid != uid || egid != gid)) {
oc_syslog(LOG_ERR,
"%s: received unauthorized request from a process with uid %u",
mod, (unsigned)euid);
return -1;
oc_syslog(
LOG_ERR,
"%s: received unauthorized request from a process with uid %u",
mod, (unsigned int)euid);
return -1;
}
#else
#error "Unsupported UNIX variant"

View File

@@ -19,30 +19,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef DIE_H
# define DIE_H
#define DIE_H
# include <config.h>
# include <signal.h>
# include <unistd.h>
#include <config.h>
#include <signal.h>
#include <unistd.h>
#ifdef HAVE_SIGHANDLER_T
# define SIGHANDLER_T sighandler_t
#define SIGHANDLER_T sighandler_t
#elif HAVE_SIG_T
# define SIGHANDLER_T sig_t
#define SIGHANDLER_T sig_t
#elif HAVE___SIGHANDLER_T
# define SIGHANDLER_T __sighandler_t
#define SIGHANDLER_T __sighandler_t
#else
typedef void (*sighandler_t)(int);
# define SIGHANDLER_T sighandler_t
#define SIGHANDLER_T sighandler_t
#endif
void pr_set_undumpable(const char* mod);
void pr_set_undumpable(const char *mod);
void kill_on_parent_kill(int sig);
SIGHANDLER_T ocsignal(int signum, SIGHANDLER_T handler);
int check_upeer_id(const char *mod, int debug, int cfg, uid_t uid, uid_t gid, uid_t *ruid, pid_t *pid);
int check_upeer_id(const char *mod, int debug, int cfg, uid_t uid, uid_t gid,
uid_t *ruid, pid_t *pid);
#endif

View File

@@ -38,7 +38,8 @@ static char *find_space(char *str)
return NULL;
}
void parse_kkdcp_string(char *str, int *socktype, char **_port, char **_server, char **_path, char **_realm)
void parse_kkdcp_string(char *str, int *socktype, char **_port, char **_server,
char **_path, char **_realm)
{
char *path, *server, *port, *realm, *p;
@@ -73,7 +74,7 @@ void parse_kkdcp_string(char *str, int *socktype, char **_port, char **_server,
*socktype = SOCK_STREAM;
} else {
fprintf(stderr, "cannot handle protocol %s\n", server);
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
server += 4;
@@ -86,7 +87,7 @@ void parse_kkdcp_string(char *str, int *socktype, char **_port, char **_server,
*p = 0;
p = strchr(server, '[');
if (p)
server = p+1;
server = p + 1;
}
}

View File

@@ -27,11 +27,13 @@
#include <vpn.h>
static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, int port, fw_proto_t proto, unsigned negate)
static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports,
int port, fw_proto_t proto, unsigned int negate)
{
FwPortSt *current;
*fw_ports = talloc_realloc(pool, *fw_ports, FwPortSt*, (*n_fw_ports)+1);
*fw_ports =
talloc_realloc(pool, *fw_ports, FwPortSt *, (*n_fw_ports) + 1);
if (*fw_ports == NULL)
return -1;
@@ -56,10 +58,11 @@ static int append_port(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, int
/* Parse strings of the format tcp(443), udp(111), and fill in
* allowed_tcp_ports and allowed_udp_ports.
*/
int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const char *str)
int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports,
const char *str)
{
const char *p, *p2;
unsigned finish = 0;
unsigned int finish = 0;
int port, ret;
fw_proto_t proto;
int negate = 0, bracket_start = 0;
@@ -82,13 +85,14 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
}
if (bracket_start == 0) {
oc_syslog(LOG_ERR, "no bracket following negation at %d '%s'", (int)(ptrdiff_t)(p-str), str);
oc_syslog(LOG_ERR,
"no bracket following negation at %d '%s'",
(int)(ptrdiff_t)(p - str), str);
return -1;
}
}
do {
while (isspace(*p))
p++;
@@ -111,7 +115,10 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
proto = PROTO_ESP;
p += 3;
} else {
oc_syslog(LOG_ERR, "unknown protocol on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p-str), str);
oc_syslog(
LOG_ERR,
"unknown protocol on restrict-user-to-ports at %d '%s'",
(int)(ptrdiff_t)(p - str), str);
return -1;
}
@@ -119,14 +126,18 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
p++;
if (*p != '(') {
oc_syslog(LOG_ERR, "expected parenthesis on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p-str), str);
oc_syslog(
LOG_ERR,
"expected parenthesis on restrict-user-to-ports at %d '%s'",
(int)(ptrdiff_t)(p - str), str);
return -1;
}
p++;
port = atoi(p);
ret = append_port(pool, fw_ports, n_fw_ports, port, proto, negate);
ret = append_port(pool, fw_ports, n_fw_ports, port, proto,
negate);
if (ret < 0) {
oc_syslog(LOG_ERR, "memory error");
return -1;
@@ -134,7 +145,10 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
p2 = strchr(p, ')');
if (p2 == NULL) {
oc_syslog(LOG_ERR, "expected closing parenthesis on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p-str), str);
oc_syslog(
LOG_ERR,
"expected closing parenthesis on restrict-user-to-ports at %d '%s'",
(int)(ptrdiff_t)(p - str), str);
return -1;
}
@@ -145,10 +159,13 @@ int cfg_parse_ports(void *pool, FwPortSt ***fw_ports, size_t *n_fw_ports, const
if (*p2 == 0 || (negate != 0 && *p2 == ')')) {
finish = 1;
} else if (*p2 != ',') {
oc_syslog(LOG_ERR, "expected comma or end of line on restrict-user-to-ports at %d '%s'", (int)(ptrdiff_t)(p2-str), str);
oc_syslog(
LOG_ERR,
"expected comma or end of line on restrict-user-to-ports at %d '%s'",
(int)(ptrdiff_t)(p2 - str), str);
return -1;
}
p=p2;
p = p2;
p++;
} while (finish == 0);

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,6 @@
#define LOG_TRANSFER_DEBUG 2049
#define LOG_SENSITIVE 2050
/* User Disconnect reasons (must be > 0) */
#define REASON_ANY 1
#define REASON_USER_DISCONNECT 2
@@ -46,12 +45,12 @@
/* Debug definitions for logger */
#define OCLOG_BASIC 1
#define OCLOG_INFO 2
#define OCLOG_INFO 2
#define OCLOG_DEBUG 3
#define OCLOG_HTTP 4
#define OCLOG_HTTP 4
#define OCLOG_TRANSFERRED 5
#define OCLOG_SENSITIVE 8
#define OCLOG_TLS 9
#define OCLOG_TLS 9
/* Authentication states */
enum {
@@ -90,7 +89,7 @@ typedef enum {
CMD_SEC_CLI_STATS,
/* from main to sec-mod and vice versa */
MIN_SECM_CMD=239,
MIN_SECM_CMD = 239,
CMD_SECM_SESSION_OPEN, /* sync: reply is CMD_SECM_SESSION_REPLY */
CMD_SECM_SESSION_CLOSE, /* sync: reply is CMD_SECM_CLI_STATS */
CMD_SECM_SESSION_REPLY,

View File

@@ -28,49 +28,43 @@
/* emulate gnulib's gettime using gettimeofday to avoid linking to
* librt */
inline static void
gettime (struct timespec *t)
inline static void gettime(struct timespec *t)
{
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME_COARSE)
clock_gettime (CLOCK_REALTIME_COARSE, t);
clock_gettime(CLOCK_REALTIME_COARSE, t);
#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
clock_gettime (CLOCK_REALTIME, t);
clock_gettime(CLOCK_REALTIME, t);
#else
struct timeval tv;
gettimeofday (&tv, NULL);
t->tv_sec = tv.tv_sec;
t->tv_nsec = tv.tv_usec * 1000;
struct timeval tv;
gettimeofday(&tv, NULL);
t->tv_sec = tv.tv_sec;
t->tv_nsec = tv.tv_usec * 1000;
#endif
}
inline static void
gettime_realtime (struct timespec *t)
inline static void gettime_realtime(struct timespec *t)
{
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
clock_gettime (CLOCK_REALTIME, t);
clock_gettime(CLOCK_REALTIME, t);
#else
struct timeval tv;
gettimeofday (&tv, NULL);
t->tv_sec = tv.tv_sec;
t->tv_nsec = tv.tv_usec * 1000;
struct timeval tv;
gettimeofday(&tv, NULL);
t->tv_sec = tv.tv_sec;
t->tv_nsec = tv.tv_usec * 1000;
#endif
}
inline static
unsigned int
timespec_sub_ms (struct timespec *a, struct timespec *b)
inline static unsigned int timespec_sub_ms(struct timespec *a,
struct timespec *b)
{
return (a->tv_sec * 1000 + a->tv_nsec / (1000 * 1000) -
(b->tv_sec * 1000 + b->tv_nsec / (1000 * 1000)));
return (a->tv_sec * 1000 + a->tv_nsec / (1000 * 1000) -
(b->tv_sec * 1000 + b->tv_nsec / (1000 * 1000)));
}
inline static
uint64_t
timespec_sub_us (struct timespec *a, struct timespec *b)
inline static uint64_t timespec_sub_us(struct timespec *a, struct timespec *b)
{
return (a->tv_sec * 1000000ULL + a->tv_nsec / (1000) -
(b->tv_sec * 1000000ULL + b->tv_nsec / (1000)));
return (a->tv_sec * 1000000ULL + a->tv_nsec / (1000) -
(b->tv_sec * 1000000ULL + b->tv_nsec / (1000)));
}
#endif

View File

@@ -29,18 +29,19 @@
#include "html.h"
#include "log.h"
char *unescape_html(void *pool, const char *html, unsigned len, unsigned *out_len)
char *unescape_html(void *pool, const char *html, unsigned int len,
unsigned int *out_len)
{
char *msg;
int pos;
unsigned i;
unsigned int i;
msg = talloc_size(pool, len + 1);
if (msg == NULL)
return NULL;
for (i = pos = 0; i < len;) {
if (len-pos < 1) {
if (len - pos < 1) {
goto fail;
}
@@ -68,28 +69,31 @@ char *unescape_html(void *pool, const char *html, unsigned len, unsigned *out_le
char *endptr = NULL;
long val;
if (p[2]=='x') {
if (p[2] == 'x') {
p += 3;
val = strtol(p, &endptr, 16);
} else {
p += 2;
val = strtol(p, &endptr, 10);
}
if (endptr == NULL || *endptr != ';' || val > WCHAR_MAX) {
if (endptr == NULL || *endptr != ';' ||
val > WCHAR_MAX) {
/* skip */
msg[pos++] = html[i++];
} else {
char tmpmb[MB_CUR_MAX];
wchar_t ch = val;
mbstate_t ps;
memset(&ps, 0, sizeof(ps));
i += (ptrdiff_t)(1+endptr-(&html[i]));
i += (ptrdiff_t)(1 + endptr -
(&html[i]));
val = wcrtomb(tmpmb, ch, &ps);
if (val == -1)
goto fail;
if (len-pos > val)
if (len - pos > val)
memcpy(&msg[pos], tmpmb, val);
else
goto fail;
@@ -106,16 +110,17 @@ char *unescape_html(void *pool, const char *html, unsigned len, unsigned *out_le
*out_len = pos;
return msg;
fail:
fail:
talloc_free(msg);
return NULL;
}
char *unescape_url(void *pool, const char *url, unsigned len, unsigned *out_len)
char *unescape_url(void *pool, const char *url, unsigned int len,
unsigned int *out_len)
{
char *msg;
int pos;
unsigned i;
unsigned int i;
msg = talloc_size(pool, len + 1);
if (msg == NULL)
@@ -132,7 +137,8 @@ char *unescape_url(void *pool, const char *url, unsigned len, unsigned *out_len)
if (sscanf(b, "%02x", &u) <= 0) {
talloc_free(msg);
oc_syslog(LOG_ERR, "%s: error parsing URL: %s", __func__, url);
oc_syslog(LOG_ERR, "%s: error parsing URL: %s",
__func__, url);
return NULL;
}
@@ -152,25 +158,28 @@ char *unescape_url(void *pool, const char *url, unsigned len, unsigned *out_len)
return msg;
}
char *escape_url(void *pool, const char *url, unsigned len, unsigned *out_len)
char *escape_url(void *pool, const char *url, unsigned int len,
unsigned int *out_len)
{
char *msg;
int pos;
unsigned i;
unsigned int i;
msg = talloc_size(pool, 3*len + 1);
msg = talloc_size(pool, 3 * len + 1);
if (msg == NULL)
return NULL;
for (i = pos = 0; i < len;) {
if (isalnum(url[i]) || url[i]=='-' || url[i]=='_' || url[i]=='.' || url[i]=='~') {
if (isalnum(url[i]) || url[i] == '-' || url[i] == '_' ||
url[i] == '.' || url[i] == '~') {
msg[pos++] = url[i++];
} else if (url[i] == ' ') {
msg[pos++] = '+';
i++;
} else {
snprintf(&msg[pos], 4, "%%%02X", (unsigned)url[i++]);
pos+=3;
snprintf(&msg[pos], 4, "%%%02X",
(unsigned int)url[i++]);
pos += 3;
}
}
msg[pos] = 0;

View File

@@ -19,10 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_HTML_H
# define OC_HTML_H
#define OC_HTML_H
char* unescape_html(void *pool, const char *html, unsigned len, unsigned *out_len);
char *unescape_url(void *pool, const char *url, unsigned len, unsigned *out_len);
char *escape_url(void *pool, const char *url, unsigned len, unsigned *out_len);
char *unescape_html(void *pool, const char *html, unsigned int len,
unsigned int *out_len);
char *unescape_url(void *pool, const char *url, unsigned int len,
unsigned int *out_len);
char *escape_url(void *pool, const char *url, unsigned int len,
unsigned int *out_len);
#endif

View File

@@ -74,7 +74,7 @@
#include <main.h>
#include <net/if.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
# include <netinet/in_systm.h>
#include <netinet/in_systm.h>
#endif
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
@@ -89,11 +89,11 @@
#include <poll.h>
#ifndef ICMP_DEST_UNREACH
# ifdef ICMP_UNREACH
# define ICMP_DEST_UNREACH ICMP_UNREACH
# else
# define ICMP_DEST_UNREACH 3
# endif
#ifdef ICMP_UNREACH
#define ICMP_DEST_UNREACH ICMP_UNREACH
#else
#define ICMP_DEST_UNREACH 3
#endif
#endif
/* I see RENUMBERED constants in bits/in.h - !!?
@@ -110,7 +110,7 @@ enum {
MAXPACKET = 65468,
MAX_DUP_CHK = (8 * 128),
MAXWAIT = 10,
PINGINTERVAL = 1, /* 1 second */
PINGINTERVAL = 1, /* 1 second */
};
/* common routines */
@@ -128,7 +128,7 @@ static int in_cksum(unsigned short *buf, int sz)
}
if (nleft == 1) {
*(unsigned char *) (&ans) = *(unsigned char *) w;
*(unsigned char *)(&ans) = *(unsigned char *)w;
sum += ans;
}
@@ -148,29 +148,26 @@ inline static int retry(int e)
#define PING_TIMEOUT 3
static
ssize_t recvfrom_timeout(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t * addrlen)
static ssize_t recvfrom_timeout(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
{
int ret;
struct pollfd pfd;
struct pollfd pfd;
pfd.fd = sockfd;
pfd.events = POLLIN;
pfd.revents = 0;
pfd.fd = sockfd;
pfd.events = POLLIN;
pfd.revents = 0;
ret = poll(&pfd, 1, 250);
ret = poll(&pfd, 1, 250);
if (ret == -1)
return -1;
else if (ret > 0)
return recvfrom(sockfd, buf, len, 0, src_addr, addrlen);
else
return -1;
}
int icmp_ping4(main_server_st * s, struct sockaddr_in *addr1)
int icmp_ping4(main_server_st *s, struct sockaddr_in *addr1)
{
struct icmp *pkt;
int pingsock, c, e;
@@ -178,14 +175,15 @@ int icmp_ping4(main_server_st * s, struct sockaddr_in *addr1)
char buf1[64];
time_t now;
uint16_t id1;
unsigned gotreply = 0, unreachable = 0;
unsigned int gotreply = 0, unreachable = 0;
if (GETCONFIG(s)->ping_leases == 0)
return 0;
if ((e=gnutls_rnd(GNUTLS_RND_NONCE, &id1, sizeof(id1))) < 0) {
mslog(s, NULL, LOG_ERR,
"error in the random generator: %s", gnutls_strerror(e));
e = gnutls_rnd(GNUTLS_RND_NONCE, &id1, sizeof(id1));
if (e < 0) {
mslog(s, NULL, LOG_ERR, "error in the random generator: %s",
gnutls_strerror(e));
return 0;
}
@@ -197,47 +195,51 @@ int icmp_ping4(main_server_st * s, struct sockaddr_in *addr1)
return 0;
}
pkt = (struct icmp *) packet1;
pkt = (struct icmp *)packet1;
memset(pkt, 0, sizeof(packet1));
pkt->icmp_type = ICMP_ECHO;
pkt->icmp_id = id1;
pkt->icmp_cksum =
in_cksum((unsigned short *) pkt, sizeof(packet1));
pkt->icmp_cksum = in_cksum((unsigned short *)pkt, sizeof(packet1));
while (sendto(pingsock, packet1, DEFDATALEN + ICMP_MINLEN, 0,
(struct sockaddr *) addr1,
sizeof(*addr1) == -1) && retry(errno));
(struct sockaddr *)addr1, sizeof(*addr1) == -1) &&
retry(errno))
;
/* listen for replies */
now = time(NULL);
while (time(NULL) - now < PING_TIMEOUT
&& (unreachable + gotreply) < 2) {
while (time(NULL) - now < PING_TIMEOUT &&
(unreachable + gotreply) < 2) {
struct sockaddr_in from;
socklen_t fromlen = sizeof(from);
c = recvfrom_timeout(pingsock, packet1, sizeof(packet1), 0,
(struct sockaddr *) &from, &fromlen);
(struct sockaddr *)&from, &fromlen);
if (c < 0) {
continue;
} else if (c >= 76 && fromlen == sizeof(struct sockaddr_in)) { /* icmp6_hdr */
if (memcmp
(SA_IN_P(&from), SA_IN_P(addr1),
SA_IN_SIZE(sizeof(*addr1))) == 0) {
} else if (c >= 76 &&
fromlen ==
sizeof(struct sockaddr_in)) { /* icmp6_hdr */
if (memcmp(SA_IN_P(&from), SA_IN_P(addr1),
SA_IN_SIZE(sizeof(*addr1))) == 0) {
#ifdef HAVE_STRUCT_IPHDR_IHL
struct iphdr *iphdr =
(struct iphdr *) packet1;
pkt = (struct icmp *) (packet1 + (iphdr->ihl << 2)); /* skip ip hdr */
struct iphdr *iphdr = (struct iphdr *)packet1;
pkt = (struct icmp *)(packet1 +
(iphdr->ihl
<< 2)); /* skip ip hdr */
#else
pkt = (struct icmp *) (packet1 + ((packet1[0] & 0x0f) << 2)); /* skip ip hdr */
pkt = (struct icmp *)(packet1 +
((packet1[0] & 0x0f)
<< 2)); /* skip ip hdr */
#endif
if (pkt->icmp_id == id1) {
if (pkt->icmp_type == ICMP_ECHOREPLY)
gotreply++;
else if (pkt->icmp_type == ICMP_DEST_UNREACH)
else if (pkt->icmp_type ==
ICMP_DEST_UNREACH)
unreachable++;
}
}
}
}
}
@@ -245,24 +247,19 @@ int icmp_ping4(main_server_st * s, struct sockaddr_in *addr1)
close(pingsock);
if (gotreply > 0) {
mslog(s, NULL, LOG_INFO,
"pinged %s and is in use",
human_addr((void *) addr1,
sizeof(struct sockaddr_in), buf1,
sizeof(buf1)));
mslog(s, NULL, LOG_INFO, "pinged %s and is in use",
human_addr((void *)addr1, sizeof(struct sockaddr_in),
buf1, sizeof(buf1)));
return gotreply;
} else {
mslog(s, NULL, LOG_INFO,
"pinged %s and is not in use",
human_addr((void *) addr1,
sizeof(struct sockaddr_in), buf1,
sizeof(buf1)));
mslog(s, NULL, LOG_INFO, "pinged %s and is not in use",
human_addr((void *)addr1, sizeof(struct sockaddr_in),
buf1, sizeof(buf1)));
return 0;
}
}
int icmp_ping6(main_server_st * s,
struct sockaddr_in6 *addr1)
int icmp_ping6(main_server_st *s, struct sockaddr_in6 *addr1)
{
struct icmp6_hdr *pkt;
char buf1[64];
@@ -272,15 +269,16 @@ int icmp_ping6(main_server_st * s,
#endif
char packet1[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
uint16_t id1;
unsigned gotreply = 0, unreachable = 0;
unsigned int gotreply = 0, unreachable = 0;
time_t now;
if (GETCONFIG(s)->ping_leases == 0)
return 0;
if ((e=gnutls_rnd(GNUTLS_RND_NONCE, &id1, sizeof(id1))) < 0) {
mslog(s, NULL, LOG_ERR,
"error in the random generator: %s", gnutls_strerror(e));
e = gnutls_rnd(GNUTLS_RND_NONCE, &id1, sizeof(id1));
if (e < 0) {
mslog(s, NULL, LOG_ERR, "error in the random generator: %s",
gnutls_strerror(e));
return 0;
}
@@ -292,43 +290,42 @@ int icmp_ping6(main_server_st * s,
return 0;
}
pkt = (struct icmp6_hdr *) packet1;
pkt = (struct icmp6_hdr *)packet1;
memset(pkt, 0, sizeof(packet1));
pkt->icmp6_type = ICMP6_ECHO_REQUEST;
pkt->icmp6_id = id1;
#if defined(SOL_RAW) && defined(IPV6_CHECKSUM)
sockopt = offsetof(struct icmp6_hdr, icmp6_cksum);
setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM,
&sockopt, sizeof(sockopt));
setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt));
#endif
while (sendto(pingsock, packet1,
DEFDATALEN + sizeof(struct icmp6_hdr), 0,
(struct sockaddr *) addr1,
sizeof(*addr1) == -1) && retry(errno));
while (sendto(pingsock, packet1, DEFDATALEN + sizeof(struct icmp6_hdr),
0, (struct sockaddr *)addr1, sizeof(*addr1) == -1) &&
retry(errno))
;
/* listen for replies */
now = time(NULL);
while (time(NULL) - now < PING_TIMEOUT
&& (unreachable + gotreply) < 2) {
while (time(NULL) - now < PING_TIMEOUT &&
(unreachable + gotreply) < 2) {
struct sockaddr_in6 from;
socklen_t fromlen = sizeof(from);
c = recvfrom_timeout(pingsock, packet1,
sizeof(packet1), 0,
(struct sockaddr *)
&from, &fromlen);
c = recvfrom_timeout(pingsock, packet1, sizeof(packet1), 0,
(struct sockaddr *)&from, &fromlen);
if (c < 0) {
continue;
} else if (c >= 8 && fromlen == sizeof(struct sockaddr_in6)) { /* icmp6_hdr */
if (memcmp
(SA_IN6_P(&from), SA_IN6_P(addr1),
SA_IN_SIZE(sizeof(*addr1))) == 0) {
pkt = (struct icmp6_hdr *) packet1;
} else if (c >= 8 &&
fromlen ==
sizeof(struct sockaddr_in6)) { /* icmp6_hdr */
if (memcmp(SA_IN6_P(&from), SA_IN6_P(addr1),
SA_IN_SIZE(sizeof(*addr1))) == 0) {
pkt = (struct icmp6_hdr *)packet1;
if (pkt->icmp6_id == id1) {
if (pkt->icmp6_type == ICMP6_ECHO_REPLY)
gotreply++;
else if (pkt->icmp6_type == ICMP6_DST_UNREACH)
else if (pkt->icmp6_type ==
ICMP6_DST_UNREACH)
unreachable++;
}
}
@@ -338,18 +335,14 @@ int icmp_ping6(main_server_st * s,
close(pingsock);
if (gotreply > 0) {
mslog(s, NULL, LOG_INFO,
"pinged %s and is in use",
human_addr((void *) addr1,
sizeof(struct sockaddr_in6), buf1,
sizeof(buf1)));
mslog(s, NULL, LOG_INFO, "pinged %s and is in use",
human_addr((void *)addr1, sizeof(struct sockaddr_in6),
buf1, sizeof(buf1)));
return gotreply;
} else {
mslog(s, NULL, LOG_INFO,
"pinged %s and is not in use",
human_addr((void *) addr1,
sizeof(struct sockaddr_in6), buf1,
sizeof(buf1)));
mslog(s, NULL, LOG_INFO, "pinged %s and is not in use",
human_addr((void *)addr1, sizeof(struct sockaddr_in6),
buf1, sizeof(buf1)));
return 0;
}
}

View File

@@ -19,13 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_ICMP_PING_H
# define OC_ICMP_PING_H
#define OC_ICMP_PING_H
#include <main.h>
/* returns the number of positive replies received or
* 0 if no host with this IP exists. */
int icmp_ping4(main_server_st* s, struct sockaddr_in* addr1);
int icmp_ping6(main_server_st* s, struct sockaddr_in6* addr1);
int icmp_ping4(main_server_st *s, struct sockaddr_in *addr1);
int icmp_ping6(main_server_st *s, struct sockaddr_in6 *addr1);
#endif

View File

@@ -27,8 +27,8 @@
#include <icmp-ping.h>
#include <arpa/inet.h>
static void ip_from_seed(uint8_t *seed, unsigned seed_size,
void *ip, size_t ip_size)
static void ip_from_seed(uint8_t *seed, unsigned int seed_size, void *ip,
size_t ip_size)
{
uint8_t digest[20];
int ret;
@@ -45,13 +45,12 @@ static void ip_from_seed(uint8_t *seed, unsigned seed_size,
}
memcpy(ip, digest, ip_size);
}
void ip_lease_deinit(struct ip_lease_db_st* db)
void ip_lease_deinit(struct ip_lease_db_st *db)
{
struct ip_lease_st * cache;
struct htable_iter iter;
struct ip_lease_st *cache;
struct htable_iter iter;
cache = htable_first(&db->ht, &iter);
while (cache != NULL) {
@@ -64,44 +63,46 @@ struct htable_iter iter;
htable_clear(&db->ht);
}
static size_t rehash(const void* _e, void* unused)
static size_t rehash(const void *_e, void *unused)
{
const struct ip_lease_st * e = _e;
const struct ip_lease_st *e = _e;
return hash_any(SA_IN_P_GENERIC(&e->sig, e->sig_len), SA_IN_SIZE(e->sig_len), 0);
return hash_any(SA_IN_P_GENERIC(&e->sig, e->sig_len),
SA_IN_SIZE(e->sig_len), 0);
}
void ip_lease_init(struct ip_lease_db_st* db)
void ip_lease_init(struct ip_lease_db_st *db)
{
htable_init(&db->ht, rehash, NULL);
}
static bool ip_lease_cmp(const void* _c1, void* _c2)
static bool ip_lease_cmp(const void *_c1, void *_c2)
{
const struct ip_lease_st* c1 = _c1;
struct ip_lease_st* c2 = _c2;
const struct ip_lease_st *c1 = _c1;
struct ip_lease_st *c2 = _c2;
if (c1->sig_len == c2->sig_len &&
ip_cmp(&c1->sig, &c2->sig) == 0)
if (c1->sig_len == c2->sig_len && ip_cmp(&c1->sig, &c2->sig) == 0)
return 1;
return 0;
}
static int ip_lease_exists(main_server_st* s, struct sockaddr_storage* ip, size_t sockaddrlen)
static int ip_lease_exists(main_server_st *s, struct sockaddr_storage *ip,
size_t sockaddrlen)
{
struct ip_lease_st t;
struct ip_lease_st t;
t.sig_len = sockaddrlen;
memcpy(&t.sig, ip, sizeof(*ip));
if (htable_get(&s->ip_leases.ht, rehash(&t, NULL), ip_lease_cmp, &t) != 0)
if (htable_get(&s->ip_leases.ht, rehash(&t, NULL), ip_lease_cmp, &t) !=
0)
return 1;
return 0;
}
void steal_ip_leases(struct proc_st* proc, struct proc_st *thief)
void steal_ip_leases(struct proc_st *proc, struct proc_st *thief)
{
/* here we reset the old tun device, and assign the old addresses
* to a new device. We cannot reuse the old device because the
@@ -120,9 +121,12 @@ void steal_ip_leases(struct proc_st* proc, struct proc_st *thief)
if (proc->ipv4 != NULL) {
proc->ipv4->rip_len = thief->ipv4->rip_len;
proc->ipv4->lip_len = thief->ipv4->lip_len;
memcpy(&proc->ipv4->rip, &thief->ipv4->rip, thief->ipv4->rip_len);
memcpy(&proc->ipv4->lip, &thief->ipv4->lip, thief->ipv4->lip_len);
memcpy(&proc->ipv4->sig, &thief->ipv4->sig, thief->ipv4->sig_len);
memcpy(&proc->ipv4->rip, &thief->ipv4->rip,
thief->ipv4->rip_len);
memcpy(&proc->ipv4->lip, &thief->ipv4->lip,
thief->ipv4->lip_len);
memcpy(&proc->ipv4->sig, &thief->ipv4->sig,
thief->ipv4->sig_len);
}
}
@@ -133,14 +137,19 @@ void steal_ip_leases(struct proc_st* proc, struct proc_st *thief)
proc->ipv6->prefix = thief->ipv6->prefix;
proc->ipv6->rip_len = thief->ipv6->rip_len;
proc->ipv6->lip_len = thief->ipv6->lip_len;
memcpy(&proc->ipv6->rip, &thief->ipv6->rip, thief->ipv6->rip_len);
memcpy(&proc->ipv6->lip, &thief->ipv6->lip, thief->ipv6->lip_len);
memcpy(&proc->ipv6->sig, &thief->ipv6->sig, thief->ipv6->sig_len);
memcpy(&proc->ipv6->rip, &thief->ipv6->rip,
thief->ipv6->rip_len);
memcpy(&proc->ipv6->lip, &thief->ipv6->lip,
thief->ipv6->lip_len);
memcpy(&proc->ipv6->sig, &thief->ipv6->sig,
thief->ipv6->sig_len);
}
}
}
static int is_ipv6_ok(main_server_st *s, struct sockaddr_storage *ip, struct sockaddr_storage *tun, struct sockaddr_storage *subnet)
static int is_ipv6_ok(main_server_st *s, struct sockaddr_storage *ip,
struct sockaddr_storage *tun,
struct sockaddr_storage *subnet)
{
/* check that IP & mask don't match tun IP */
if (ip_cmp(subnet, tun) == 0) {
@@ -155,19 +164,20 @@ static int is_ipv6_ok(main_server_st *s, struct sockaddr_storage *ip, struct soc
return 1;
}
static int is_ipv4_ok(main_server_st *s, struct sockaddr_storage *ip, struct sockaddr_storage *net, struct sockaddr_storage *mask)
static int is_ipv4_ok(main_server_st *s, struct sockaddr_storage *ip,
struct sockaddr_storage *net,
struct sockaddr_storage *mask)
{
struct sockaddr_storage broadcast;
unsigned i;
unsigned int i;
memcpy(&broadcast, net, sizeof(broadcast));
for (i=0;i<sizeof(struct in_addr);i++) {
for (i = 0; i < sizeof(struct in_addr); i++) {
SA_IN_U8_P(&broadcast)[i] |= ~(SA_IN_U8_P(mask)[i]);
}
if (ip_lease_exists(s, ip, sizeof(struct sockaddr_in)) != 0 ||
ip_cmp(ip, net) == 0 ||
ip_cmp(ip, &broadcast) == 0) {
ip_cmp(ip, net) == 0 || ip_cmp(ip, &broadcast) == 0) {
return 0;
}
return 1;
@@ -176,13 +186,11 @@ static int is_ipv4_ok(main_server_st *s, struct sockaddr_storage *ip, struct soc
#define MAX_IP_TRIES 16
#define FIXED_IPS 5
static
int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
static int get_ipv4_lease(main_server_st *s, struct proc_st *proc)
{
struct sockaddr_storage tmp, mask, network, rnd;
unsigned i;
unsigned max_loops = MAX_IP_TRIES;
unsigned int i;
unsigned int max_loops = MAX_IP_TRIES;
int ret;
const char *c_network, *c_netmask;
char buf[64];
@@ -195,7 +203,8 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
c_netmask = proc->config->ipv4_netmask;
} else {
c_network = proc->vhost->perm_config.config->network.ipv4;
c_netmask = proc->vhost->perm_config.config->network.ipv4_netmask;
c_netmask =
proc->vhost->perm_config.config->network.ipv4_netmask;
}
if (c_network == NULL || c_netmask == NULL) {
@@ -203,32 +212,31 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
return 0;
}
ret =
inet_pton(AF_INET, c_network, SA_IN_P(&network));
ret = inet_pton(AF_INET, c_network, SA_IN_P(&network));
if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading IP: %s", c_network);
return -1;
}
ret =
inet_pton(AF_INET, c_netmask, SA_IN_P(&mask));
ret = inet_pton(AF_INET, c_netmask, SA_IN_P(&mask));
if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading mask: %s", c_netmask);
return -1;
}
/* mask the network (just in case it is wrong) */
for (i=0;i<sizeof(struct in_addr);i++)
for (i = 0; i < sizeof(struct in_addr); i++)
SA_IN_U8_P(&network)[i] &= (SA_IN_U8_P(&mask)[i]);
((struct sockaddr_in*)&network)->sin_family = AF_INET;
((struct sockaddr_in*)&network)->sin_port = 0;
((struct sockaddr_in *)&network)->sin_family = AF_INET;
((struct sockaddr_in *)&network)->sin_port = 0;
if (proc->config->explicit_ipv4) {
ret =
inet_pton(AF_INET, proc->config->explicit_ipv4, SA_IN_P(&tmp));
ret = inet_pton(AF_INET, proc->config->explicit_ipv4,
SA_IN_P(&tmp));
if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading explicit IP: %s", proc->config->explicit_ipv4);
mslog(s, NULL, LOG_ERR, "error reading explicit IP: %s",
proc->config->explicit_ipv4);
return -1;
}
@@ -236,16 +244,19 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
if (proc->ipv4 == NULL)
return ERR_MEM;
((struct sockaddr_in*)&tmp)->sin_family = AF_INET;
((struct sockaddr_in*)&tmp)->sin_port = 0;
((struct sockaddr_in *)&tmp)->sin_family = AF_INET;
((struct sockaddr_in *)&tmp)->sin_port = 0;
memcpy(&proc->ipv4->rip, &tmp, sizeof(struct sockaddr_in));
proc->ipv4->rip_len = sizeof(struct sockaddr_in);
memcpy(&proc->ipv4->sig, &tmp, sizeof(struct sockaddr_in));
if (is_ipv4_ok(s, &proc->ipv4->rip, &network, &mask) == 0) {
mslog(s, proc, LOG_DEBUG, "cannot assign explicit IP %s; it is in use or invalid",
human_addr((void*)&tmp, sizeof(struct sockaddr_in), buf, sizeof(buf)));
mslog(s, proc, LOG_DEBUG,
"cannot assign explicit IP %s; it is in use or invalid",
human_addr((void *)&tmp,
sizeof(struct sockaddr_in), buf,
sizeof(buf)));
ret = ERR_NO_IP;
goto fail;
}
@@ -256,7 +267,9 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
SA_IN_U8_P(&proc->ipv4->lip)[3] |= 1;
if (ip_cmp(&proc->ipv4->lip, &proc->ipv4->rip) == 0) {
mslog(s, NULL, LOG_ERR, "cannot assign explicit IP %s; network: %s", proc->config->explicit_ipv4, c_network);
mslog(s, NULL, LOG_ERR,
"cannot assign explicit IP %s; network: %s",
proc->config->explicit_ipv4, c_network);
ret = ERR_NO_IP;
goto fail;
}
@@ -271,49 +284,59 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
proc->ipv4->db = &s->ip_leases;
memcpy(&tmp, &network, sizeof(tmp));
((struct sockaddr_in*)&tmp)->sin_family = AF_INET;
((struct sockaddr_in*)&tmp)->sin_port = 0;
((struct sockaddr_in *)&tmp)->sin_family = AF_INET;
((struct sockaddr_in *)&tmp)->sin_port = 0;
memset(&rnd, 0, sizeof(rnd));
((struct sockaddr_in*)&rnd)->sin_family = AF_INET;
((struct sockaddr_in*)&rnd)->sin_port = 0;
((struct sockaddr_in *)&rnd)->sin_family = AF_INET;
((struct sockaddr_in *)&rnd)->sin_port = 0;
do {
if (max_loops == 0) {
mslog(s, proc, LOG_ERR, "could not figure out a valid IPv4 IP");
mslog(s, proc, LOG_ERR,
"could not figure out a valid IPv4 IP");
ret = ERR_NO_IP;
goto fail;
}
if (max_loops == MAX_IP_TRIES) {
memcpy(SA_IN_U8_P(&rnd), proc->ipv4_seed, 4);
} else {
if (max_loops < MAX_IP_TRIES-FIXED_IPS) {
ret = gnutls_rnd(GNUTLS_RND_NONCE, SA_IN_U8_P(&rnd), sizeof(struct in_addr));
if (max_loops < MAX_IP_TRIES - FIXED_IPS) {
ret = gnutls_rnd(GNUTLS_RND_NONCE,
SA_IN_U8_P(&rnd),
sizeof(struct in_addr));
if (ret < 0) {
mslog(s, proc, LOG_ERR, "error in the random generator: %s", gnutls_strerror(ret));
mslog(s, proc, LOG_ERR,
"error in the random generator: %s",
gnutls_strerror(ret));
ret = ERR_NO_IP;
goto fail;
}
} else {
ip_from_seed(SA_IN_U8_P(&rnd), sizeof(struct in_addr),
SA_IN_U8_P(&rnd), sizeof(struct in_addr));
ip_from_seed(SA_IN_U8_P(&rnd),
sizeof(struct in_addr),
SA_IN_U8_P(&rnd),
sizeof(struct in_addr));
}
}
max_loops--;
/* Mask the random number with the netmask */
for (i=0;i<sizeof(struct in_addr);i++) {
for (i = 0; i < sizeof(struct in_addr); i++) {
SA_IN_U8_P(&rnd)[i] &= ~(SA_IN_U8_P(&mask)[i]);
}
/* Now add the IP to the masked random number */
for (i=0;i<sizeof(struct in_addr);i++)
for (i = 0; i < sizeof(struct in_addr); i++)
SA_IN_U8_P(&rnd)[i] |= (SA_IN_U8_P(&network)[i]);
/* check if it exists in the hash table */
if (is_ipv4_ok(s, &rnd, &network, &mask) == 0) {
mslog(s, proc, LOG_DEBUG, "cannot assign remote IP %s; it is in use or invalid",
human_addr((void*)&rnd, sizeof(struct sockaddr_in), buf, sizeof(buf)));
mslog(s, proc, LOG_DEBUG,
"cannot assign remote IP %s; it is in use or invalid",
human_addr((void *)&rnd,
sizeof(struct sockaddr_in), buf,
sizeof(buf)));
continue;
}
@@ -327,34 +350,35 @@ int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
proc->ipv4->lip_len = sizeof(struct sockaddr_in);
SA_IN_U8_P(&proc->ipv4->lip)[3] |= 1;
if (memcmp(SA_IN_U8_P(&proc->ipv4->lip), SA_IN_U8_P(&proc->ipv4->rip), sizeof(struct in_addr)) == 0) {
if (memcmp(SA_IN_U8_P(&proc->ipv4->lip),
SA_IN_U8_P(&proc->ipv4->rip),
sizeof(struct in_addr)) == 0) {
continue;
}
mslog(s, proc, LOG_DEBUG, "selected IP: %s",
human_addr((void*)&proc->ipv4->rip, proc->ipv4->rip_len, buf, sizeof(buf)));
human_addr((void *)&proc->ipv4->rip, proc->ipv4->rip_len,
buf, sizeof(buf)));
if (icmp_ping4(s, (void*)&proc->ipv4->rip) == 0)
if (icmp_ping4(s, (void *)&proc->ipv4->rip) == 0)
break;
} while (1);
return 0;
fail:
fail:
talloc_free(proc->ipv4);
proc->ipv4 = NULL;
return ret;
}
static
int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
static int get_ipv6_lease(main_server_st *s, struct proc_st *proc)
{
struct sockaddr_storage tmp, mask, network, rnd, subnet_mask;
unsigned i, max_loops = MAX_IP_TRIES;
const char* c_network = NULL;
unsigned prefix, subnet_prefix ;
unsigned int i, max_loops = MAX_IP_TRIES;
const char *c_network = NULL;
unsigned int prefix, subnet_prefix;
int ret;
char buf[64];
@@ -365,7 +389,8 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
} else {
c_network = proc->vhost->perm_config.config->network.ipv6;
prefix = proc->vhost->perm_config.config->network.ipv6_prefix;
subnet_prefix = proc->vhost->perm_config.config->network.ipv6_subnet_prefix;
subnet_prefix = proc->vhost->perm_config.config->network
.ipv6_subnet_prefix;
}
if (c_network == NULL || prefix == 0 || subnet_prefix == 0) {
@@ -380,21 +405,21 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
ret = ipv6_prefix_to_mask(SA_IN6_P(&subnet_mask), subnet_prefix);
if (ret == 0) {
mslog(s, NULL, LOG_ERR, "error reading prefix: %u", subnet_prefix);
mslog(s, NULL, LOG_ERR, "error reading prefix: %u",
subnet_prefix);
return -1;
}
ret =
inet_pton(AF_INET6, c_network, SA_IN6_P(&network));
ret = inet_pton(AF_INET6, c_network, SA_IN6_P(&network));
if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading IP: %s", c_network);
return -1;
}
/* mask the network */
((struct sockaddr_in6*)&network)->sin6_family = AF_INET6;
((struct sockaddr_in6*)&network)->sin6_port = 0;
for (i=0;i<sizeof(struct in6_addr);i++)
((struct sockaddr_in6 *)&network)->sin6_family = AF_INET6;
((struct sockaddr_in6 *)&network)->sin6_port = 0;
for (i = 0; i < sizeof(struct in6_addr); i++)
SA_IN6_U8_P(&network)[i] &= (SA_IN6_U8_P(&mask)[i]);
proc->ipv6 = talloc_zero(proc, struct ip_lease_st);
@@ -409,26 +434,34 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
if (proc->config->explicit_ipv6) {
memset(&tmp, 0, sizeof(tmp));
ret =
inet_pton(AF_INET6, proc->config->explicit_ipv6, SA_IN6_P(&tmp));
ret = inet_pton(AF_INET6, proc->config->explicit_ipv6,
SA_IN6_P(&tmp));
if (ret != 1) {
mslog(s, NULL, LOG_ERR, "error reading explicit IP %s", proc->config->explicit_ipv6);
mslog(s, NULL, LOG_ERR, "error reading explicit IP %s",
proc->config->explicit_ipv6);
ret = ERR_NO_IP;
goto fail;
}
((struct sockaddr_in6*)&tmp)->sin6_family = AF_INET6;
((struct sockaddr_in6 *)&tmp)->sin6_family = AF_INET6;
memcpy(&proc->ipv6->rip, &tmp, sizeof(struct sockaddr_in6));
proc->ipv6->rip_len = sizeof(struct sockaddr_in6);
/* create our sig */
for (i=0;i<sizeof(struct in6_addr);i++)
SA_IN6_U8_P(&proc->ipv6->sig)[i] = SA_IN6_U8_P(&proc->ipv6->rip)[i] & SA_IN6_U8_P(&subnet_mask)[i];
for (i = 0; i < sizeof(struct in6_addr); i++) {
uint8_t *p = SA_IN6_U8_P(&proc->ipv6->sig);
p[i] = (SA_IN6_U8_P(&proc->ipv6->rip)[i]) &
SA_IN6_U8_P(&subnet_mask)[i];
}
if (is_ipv6_ok(s, &tmp, &proc->ipv6->lip, &proc->ipv6->sig) == 0) {
mslog(s, proc, LOG_DEBUG, "cannot assign explicit IP %s; it is in use or invalid",
human_addr((void*)&tmp, sizeof(struct sockaddr_in6), buf, sizeof(buf)));
if (is_ipv6_ok(s, &tmp, &proc->ipv6->lip, &proc->ipv6->sig) ==
0) {
mslog(s, proc, LOG_DEBUG,
"cannot assign explicit IP %s; it is in use or invalid",
human_addr((void *)&tmp,
sizeof(struct sockaddr_in6), buf,
sizeof(buf)));
ret = ERR_NO_IP;
goto fail;
}
@@ -440,56 +473,70 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
proc->ipv6->db = &s->ip_leases;
memcpy(&tmp, &network, sizeof(tmp));
((struct sockaddr_in6*)&tmp)->sin6_family = AF_INET6;
((struct sockaddr_in6*)&tmp)->sin6_port = 0;
((struct sockaddr_in6 *)&tmp)->sin6_family = AF_INET6;
((struct sockaddr_in6 *)&tmp)->sin6_port = 0;
do {
if (max_loops == 0) {
mslog(s, NULL, LOG_ERR, "could not figure out a valid IPv6 IP");
mslog(s, NULL, LOG_ERR,
"could not figure out a valid IPv6 IP");
ret = ERR_NO_IP;
goto fail;
}
memset(&rnd, 0, sizeof(rnd));
((struct sockaddr_in6*)&rnd)->sin6_family = AF_INET6;
((struct sockaddr_in6 *)&rnd)->sin6_family = AF_INET6;
if (max_loops == MAX_IP_TRIES) {
ip_from_seed(proc->ipv4_seed, 4,
SA_IN6_U8_P(&rnd), sizeof(struct in6_addr));
ip_from_seed(proc->ipv4_seed, 4, SA_IN6_U8_P(&rnd),
sizeof(struct in6_addr));
} else {
if (max_loops < MAX_IP_TRIES-FIXED_IPS) {
ret = gnutls_rnd(GNUTLS_RND_NONCE, SA_IN_U8_P(&rnd), sizeof(struct in6_addr));
if (max_loops < MAX_IP_TRIES - FIXED_IPS) {
ret = gnutls_rnd(GNUTLS_RND_NONCE,
SA_IN_U8_P(&rnd),
sizeof(struct in6_addr));
if (ret < 0) {
mslog(s, proc, LOG_ERR, "error in the random generator: %s", gnutls_strerror(ret));
mslog(s, proc, LOG_ERR,
"error in the random generator: %s",
gnutls_strerror(ret));
ret = ERR_NO_IP;
goto fail;
}
} else {
ip_from_seed(SA_IN6_U8_P(&rnd), sizeof(struct in6_addr),
SA_IN6_U8_P(&rnd), sizeof(struct in6_addr));
ip_from_seed(SA_IN6_U8_P(&rnd),
sizeof(struct in6_addr),
SA_IN6_U8_P(&rnd),
sizeof(struct in6_addr));
}
}
max_loops--;
/* Mask the random number with the netmask */
for (i=0;i<sizeof(struct in6_addr);i++)
for (i = 0; i < sizeof(struct in6_addr); i++)
SA_IN6_U8_P(&rnd)[i] &= ~(SA_IN6_U8_P(&mask)[i]);
/* Now add the network to the masked random number */
for (i=0;i<sizeof(struct in6_addr);i++)
for (i = 0; i < sizeof(struct in6_addr); i++)
SA_IN6_U8_P(&rnd)[i] |= (SA_IN6_U8_P(&network)[i]);
/* make the sig of our subnet */
((struct sockaddr_in6*)&proc->ipv6->sig)->sin6_family = AF_INET6;
((struct sockaddr_in6*)&proc->ipv6->sig)->sin6_port = 0;
for (i=0;i<sizeof(struct in6_addr);i++) {
SA_IN6_U8_P(&proc->ipv6->sig)[i] = SA_IN6_U8_P(&rnd)[i] & SA_IN6_U8_P(&subnet_mask)[i];
((struct sockaddr_in6 *)&proc->ipv6->sig)->sin6_family =
AF_INET6;
((struct sockaddr_in6 *)&proc->ipv6->sig)->sin6_port = 0;
for (i = 0; i < sizeof(struct in6_addr); i++) {
SA_IN6_U8_P(&proc->ipv6->sig)
[i] = SA_IN6_U8_P(&rnd)[i] &
SA_IN6_U8_P(&subnet_mask)[i];
}
/* check if it exists in the hash table */
if (is_ipv6_ok(s, &rnd, &proc->ipv6->lip, &proc->ipv6->sig) == 0) {
mslog(s, proc, LOG_DEBUG, "cannot assign IP %s; it is in use or invalid",
human_addr((void*)&rnd, sizeof(struct sockaddr_in6), buf, sizeof(buf)));
if (is_ipv6_ok(s, &rnd, &proc->ipv6->lip, &proc->ipv6->sig) ==
0) {
mslog(s, proc, LOG_DEBUG,
"cannot assign IP %s; it is in use or invalid",
human_addr((void *)&rnd,
sizeof(struct sockaddr_in6), buf,
sizeof(buf)));
continue;
}
@@ -497,26 +544,26 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
memcpy(&proc->ipv6->rip, &rnd, proc->ipv6->rip_len);
mslog(s, proc, LOG_DEBUG, "selected IP: %s",
human_addr((void*)&proc->ipv6->rip, proc->ipv6->rip_len, buf, sizeof(buf)));
human_addr((void *)&proc->ipv6->rip, proc->ipv6->rip_len,
buf, sizeof(buf)));
if (proc->ipv6->prefix != 128 || icmp_ping6(s, (void*)&proc->ipv6->rip) == 0)
if (proc->ipv6->prefix != 128 ||
icmp_ping6(s, (void *)&proc->ipv6->rip) == 0)
break;
} while (1);
finish:
finish:
proc->ipv6->prefix = subnet_prefix;
return 0;
fail:
fail:
talloc_free(proc->ipv6);
proc->ipv6 = NULL;
return ret;
}
static
int unref_ip_lease(struct ip_lease_st *lease)
static int unref_ip_lease(struct ip_lease_st *lease)
{
if (lease->db) {
htable_del(&lease->db->ht, rehash(lease, NULL), lease);
@@ -527,8 +574,8 @@ int unref_ip_lease(struct ip_lease_st *lease)
int get_ip_leases(main_server_st *s, struct proc_st *proc)
{
int ret;
char buf[128];
int ret;
char buf[128];
if (proc->ipv4 == NULL) {
ret = get_ipv4_lease(s, proc);
@@ -536,8 +583,11 @@ char buf[128];
return ret;
if (proc->ipv4 && proc->ipv4->db) {
if (htable_add(&s->ip_leases.ht, rehash(proc->ipv4, NULL), proc->ipv4) == 0) {
mslog(s, proc, LOG_ERR, "could not add IPv4 lease to hash table");
if (htable_add(&s->ip_leases.ht,
rehash(proc->ipv4, NULL),
proc->ipv4) == 0) {
mslog(s, proc, LOG_ERR,
"could not add IPv4 lease to hash table");
return -1;
}
talloc_set_destructor(proc->ipv4, unref_ip_lease);
@@ -550,8 +600,11 @@ char buf[128];
return ret;
if (proc->ipv6 && proc->ipv6->db) {
if (htable_add(&s->ip_leases.ht, rehash(proc->ipv6, NULL), proc->ipv6) == 0) {
mslog(s, proc, LOG_ERR, "could not add IPv6 lease to hash table");
if (htable_add(&s->ip_leases.ht,
rehash(proc->ipv6, NULL),
proc->ipv6) == 0) {
mslog(s, proc, LOG_ERR,
"could not add IPv6 lease to hash table");
return -1;
}
talloc_set_destructor(proc->ipv6, unref_ip_lease);
@@ -559,23 +612,26 @@ char buf[128];
}
if (proc->ipv4 == 0 && proc->ipv6 == 0) {
mslog(s, proc, LOG_ERR, "no IPv4 or IPv6 addresses are configured. Cannot obtain lease");
mslog(s, proc, LOG_ERR,
"no IPv4 or IPv6 addresses are configured. Cannot obtain lease");
return -1;
}
if (proc->ipv4)
mslog(s, proc, LOG_DEBUG, "assigned IPv4: %s",
human_addr((void*)&proc->ipv4->rip, proc->ipv4->rip_len, buf, sizeof(buf)));
human_addr((void *)&proc->ipv4->rip, proc->ipv4->rip_len,
buf, sizeof(buf)));
if (proc->ipv6)
mslog(s, proc, LOG_DEBUG, "assigned IPv6: %s/%u",
human_addr((void*)&proc->ipv6->rip, proc->ipv6->rip_len, buf, sizeof(buf)),
proc->ipv6->prefix);
human_addr((void *)&proc->ipv6->rip, proc->ipv6->rip_len,
buf, sizeof(buf)),
proc->ipv6->prefix);
return 0;
}
void remove_ip_leases(main_server_st* s, struct proc_st* proc)
void remove_ip_leases(main_server_st *s, struct proc_st *proc)
{
if (proc->ipv4) {
talloc_free(proc->ipv4);
@@ -587,7 +643,7 @@ void remove_ip_leases(main_server_st* s, struct proc_st* proc)
}
}
void remove_ip_lease(main_server_st* s, struct ip_lease_st * lease)
void remove_ip_lease(main_server_st *s, struct ip_lease_st *lease)
{
talloc_free(lease);
}

View File

@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_IP_LEASE_H
# define OC_IP_LEASE_H
#define OC_IP_LEASE_H
#include <vpn.h>
#include <string.h>
@@ -28,28 +28,28 @@
#include <main.h>
struct ip_lease_st {
/* In IPv4 this is the same as rip, in IPv6
* that's the network address */
struct sockaddr_storage sig;
/* In IPv4 this is the same as rip, in IPv6
* that's the network address */
struct sockaddr_storage sig;
#define sig_len rip_len
struct sockaddr_storage rip;
socklen_t rip_len;
struct sockaddr_storage rip;
socklen_t rip_len;
struct sockaddr_storage lip;
socklen_t lip_len;
unsigned prefix; /* in ipv6 */
struct sockaddr_storage lip;
socklen_t lip_len;
unsigned int prefix; /* in ipv6 */
struct ip_lease_db_st* db;
struct ip_lease_db_st *db;
};
void ip_lease_deinit(struct ip_lease_db_st* db);
void ip_lease_init(struct ip_lease_db_st* db);
void ip_lease_deinit(struct ip_lease_db_st *db);
void ip_lease_init(struct ip_lease_db_st *db);
void steal_ip_leases(struct proc_st* proc, struct proc_st *thief);
void steal_ip_leases(struct proc_st *proc, struct proc_st *thief);
int get_ip_leases(struct main_server_st* s, struct proc_st* proc);
void remove_ip_leases(struct main_server_st* s, struct proc_st* proc);
void remove_ip_lease(main_server_st* s, struct ip_lease_st * lease);
int get_ip_leases(struct main_server_st *s, struct proc_st *proc);
void remove_ip_leases(struct main_server_st *s, struct proc_st *proc);
void remove_ip_lease(main_server_st *s, struct ip_lease_st *lease);
#endif

View File

@@ -35,16 +35,17 @@
int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2)
{
if (((struct sockaddr*)s1)->sa_family == AF_INET) {
if (((struct sockaddr *)s1)->sa_family == AF_INET) {
return memcmp(SA_IN_P(s1), SA_IN_P(s2), sizeof(struct in_addr));
} else { /* inet6 */
return memcmp(SA_IN6_P(s1), SA_IN6_P(s2), sizeof(struct in6_addr));
return memcmp(SA_IN6_P(s1), SA_IN6_P(s2),
sizeof(struct in6_addr));
}
}
/* returns an allocated string with the mask to apply for the prefix
*/
char* ipv4_prefix_to_strmask(void *pool, unsigned prefix)
char *ipv4_prefix_to_strmask(void *pool, unsigned int prefix)
{
struct in_addr in;
char str[MAX_IP_STR];
@@ -59,7 +60,7 @@ char* ipv4_prefix_to_strmask(void *pool, unsigned prefix)
return talloc_strdup(pool, str);
}
unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix)
unsigned int ipv6_prefix_to_mask(struct in6_addr *in6, unsigned int prefix)
{
int i, j;
@@ -71,7 +72,7 @@ unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix)
if (i >= 8) {
in6->s6_addr[j] = 0xff;
} else {
in6->s6_addr[j] = (unsigned long)(0xffU << ( 8 - i ));
in6->s6_addr[j] = (unsigned long)(0xffU << (8 - i));
}
}
@@ -87,7 +88,7 @@ unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix)
int ip_route_sanity_check(void *pool, char **_route)
{
char *p;
unsigned prefix;
unsigned int prefix;
char *route = *_route, *n;
char *slash_ptr, *pstr;
@@ -98,7 +99,10 @@ int ip_route_sanity_check(void *pool, char **_route)
p = strchr(p, '/');
if (p == NULL) {
oc_syslog(LOG_ERR, "route '%s' in wrong format, use xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx\n", route);
oc_syslog(
LOG_ERR,
"route '%s' in wrong format, use xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx\n",
route);
return -1;
}
slash_ptr = p;
@@ -113,7 +117,8 @@ int ip_route_sanity_check(void *pool, char **_route)
pstr = ipv4_prefix_to_strmask(pool, prefix);
if (pstr == NULL) {
oc_syslog(LOG_ERR, "cannot figure format of route '%s'\n", route);
oc_syslog(LOG_ERR, "cannot figure format of route '%s'\n",
route);
return -1;
}
@@ -131,8 +136,7 @@ int ip_route_sanity_check(void *pool, char **_route)
return 0;
}
static
int bit_count(uint32_t i)
static int bit_count(uint32_t i)
{
int c = 0;
unsigned int seen_one = 0;
@@ -157,8 +161,7 @@ static int mask2prefix(struct in_addr mask)
return bit_count(ntohl(mask.s_addr));
}
static
int ipv4_mask_to_int(const char *prefix)
static int ipv4_mask_to_int(const char *prefix)
{
int ret;
struct in_addr in;
@@ -188,7 +191,7 @@ char *ipv4_route_to_cidr(void *pool, const char *route)
if (p == NULL) {
return NULL;
}
len = (ptrdiff_t)(p-route);
len = (ptrdiff_t)(p - route);
p++;
/* if we are in CIDR format exit */
@@ -202,14 +205,14 @@ char *ipv4_route_to_cidr(void *pool, const char *route)
return talloc_asprintf(pool, "%.*s/%d", len, route, prefix);
}
char *human_addr2(const struct sockaddr *sa, socklen_t salen,
void *_buf, size_t buflen, unsigned full)
char *human_addr2(const struct sockaddr *sa, socklen_t salen, void *_buf,
size_t buflen, unsigned int full)
{
char *save_buf = _buf;
char *buf = _buf;
size_t l;
const char *ret;
unsigned port;
unsigned int port;
if (!buf || !buflen)
return NULL;
@@ -219,20 +222,26 @@ char *human_addr2(const struct sockaddr *sa, socklen_t salen,
}
if (salen == sizeof(struct sockaddr_in6)) {
port = (unsigned)ntohs(((struct sockaddr_in6*)sa)->sin6_port);
port = (unsigned int)ntohs(
((struct sockaddr_in6 *)sa)->sin6_port);
if (full != 0 && port != 0) {
assert(buflen > 0); /* already checked, but to avoid regression */
assert(buflen >
0); /* already checked, but to avoid regression */
*buf = '[';
buf++;
buflen--;
}
ret = inet_ntop(AF_INET6, &((struct sockaddr_in6*)sa)->sin6_addr, buf, buflen);
ret = inet_ntop(AF_INET6,
&((struct sockaddr_in6 *)sa)->sin6_addr, buf,
buflen);
} else {
port = (unsigned)ntohs(((struct sockaddr_in*)sa)->sin_port);
port = (unsigned int)ntohs(
((struct sockaddr_in *)sa)->sin_port);
ret = inet_ntop(AF_INET, &((struct sockaddr_in*)sa)->sin_addr, buf, buflen);
ret = inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr,
buf, buflen);
}
if (ret == NULL) {
@@ -272,7 +281,7 @@ void set_mtu_disc(int fd, int family, int val)
y = val;
#if defined(IPV6_DONTFRAG)
if (setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG,
(const void *) &y, sizeof(y)) < 0)
(const void *)&y, sizeof(y)) < 0)
oc_syslog(LOG_INFO, "setsockopt(IPV6_DF) failed");
#elif defined(IPV6_MTU_DISCOVER)
if (val)
@@ -280,14 +289,15 @@ void set_mtu_disc(int fd, int family, int val)
else
y = IP_PMTUDISC_DONT;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
(const void *) &y, sizeof(y)) < 0)
oc_syslog(LOG_INFO, "setsockopt(IPV6_MTU_DISCOVER) failed");
(const void *)&y, sizeof(y)) < 0)
oc_syslog(LOG_INFO,
"setsockopt(IPV6_MTU_DISCOVER) failed");
#endif
} else {
y = val;
#if defined(IP_DONTFRAG)
if (setsockopt(fd, IPPROTO_IP, IP_DONTFRAG,
(const void *) &y, sizeof(y)) < 0)
if (setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, (const void *)&y,
sizeof(y)) < 0)
oc_syslog(LOG_INFO, "setsockopt(IP_DF) failed");
#elif defined(IP_MTU_DISCOVER)
if (val)
@@ -295,8 +305,9 @@ void set_mtu_disc(int fd, int family, int val)
else
y = IP_PMTUDISC_DONT;
if (setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER,
(const void *) &y, sizeof(y)) < 0)
oc_syslog(LOG_INFO, "setsockopt(IP_MTU_DISCOVER) failed");
(const void *)&y, sizeof(y)) < 0)
oc_syslog(LOG_INFO,
"setsockopt(IP_MTU_DISCOVER) failed");
#endif
}
}

View File

@@ -20,7 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_IP_UTIL_H
# define OC_IP_UTIL_H
#define OC_IP_UTIL_H
#include <sys/socket.h>
#include <netinet/in.h>
@@ -28,15 +28,16 @@
// Lower MTU bound is the value defined in RFC 791
#define RFC_791_MTU (68)
// Upper bound is the maximum DTLS frame size
#define MAX_DTLS_MTU (1<<14)
#define MAX_DTLS_MTU (1 << 14)
void set_mtu_disc(int fd, int family, int val);
int ip_route_sanity_check(void *pool, char **_route);
int ip_cmp(const struct sockaddr_storage *s1, const struct sockaddr_storage *s2);
char* ipv4_prefix_to_strmask(void *pool, unsigned prefix);
unsigned ipv6_prefix_to_mask(struct in6_addr *in6, unsigned prefix);
inline static int valid_ipv6_prefix(unsigned prefix)
int ip_cmp(const struct sockaddr_storage *s1,
const struct sockaddr_storage *s2);
char *ipv4_prefix_to_strmask(void *pool, unsigned int prefix);
unsigned int ipv6_prefix_to_mask(struct in6_addr *in6, unsigned int prefix);
inline static int valid_ipv6_prefix(unsigned int prefix)
{
if (prefix > 10 && prefix <= 128)
return 1;
@@ -48,19 +49,24 @@ char *ipv4_route_to_cidr(void *pool, const char *route);
/* Helper casts */
#define SA_IN_P(p) (&((struct sockaddr_in *)(p))->sin_addr)
#define SA_IN_U8_P(p) ((uint8_t*)(&((struct sockaddr_in *)(p))->sin_addr))
#define SA_IN_U8_P(p) ((uint8_t *)(&((struct sockaddr_in *)(p))->sin_addr))
#define SA_IN6_P(p) (&((struct sockaddr_in6 *)(p))->sin6_addr)
#define SA_IN6_U8_P(p) ((uint8_t*)(&((struct sockaddr_in6 *)(p))->sin6_addr))
#define SA_IN6_U8_P(p) ((uint8_t *)(&((struct sockaddr_in6 *)(p))->sin6_addr))
#define SA_IN_PORT(p) (((struct sockaddr_in *)(p))->sin_port)
#define SA_IN6_PORT(p) (((struct sockaddr_in6 *)(p))->sin6_port)
#define SA_IN_P_GENERIC(addr, size) ((size==sizeof(struct sockaddr_in))?SA_IN_U8_P(addr):SA_IN6_U8_P(addr))
#define SA_IN_P_TYPE(addr, type) ((type==AF_INET)?SA_IN_U8_P(addr):SA_IN6_U8_P(addr))
#define SA_IN_SIZE(size) ((size==sizeof(struct sockaddr_in))?sizeof(struct in_addr):sizeof(struct in6_addr))
#define SA_IN_P_GENERIC(addr, size) \
((size == sizeof(struct sockaddr_in)) ? SA_IN_U8_P(addr) : \
SA_IN6_U8_P(addr))
#define SA_IN_P_TYPE(addr, type) \
((type == AF_INET) ? SA_IN_U8_P(addr) : SA_IN6_U8_P(addr))
#define SA_IN_SIZE(size) \
((size == sizeof(struct sockaddr_in)) ? sizeof(struct in_addr) : \
sizeof(struct in6_addr))
char *human_addr2(const struct sockaddr *sa, socklen_t salen,
void *buf, size_t buflen, unsigned full);
char *human_addr2(const struct sockaddr *sa, socklen_t salen, void *buf,
size_t buflen, unsigned int full);
#define human_addr(x, y, z, w) human_addr2(x, y, z, w, 1)

View File

@@ -35,17 +35,15 @@ void set_worker_fd_limits(struct worker_st *ws)
ret = getrlimit(RLIMIT_NOFILE, &def_set);
if (ret < 0) {
int e = errno;
oclog(ws, LOG_ERR,
"error in getrlimit: %s\n", strerror(e));
oclog(ws, LOG_ERR, "error in getrlimit: %s\n", strerror(e));
exit(EXIT_FAILURE);
}
ret = setrlimit(RLIMIT_NOFILE, &def_set);
if (ret < 0) {
oclog(ws, LOG_INFO,
"cannot update file limit(%u): %s\n",
(unsigned)def_set.rlim_cur,
strerror(errno));
oclog(ws, LOG_INFO, "cannot update file limit(%u): %s\n",
(unsigned int)def_set.rlim_cur, strerror(errno));
}
#endif
}
@@ -98,7 +96,6 @@ void drop_privileges(struct worker_st *ws, main_server_st *s)
oclog(ws, LOG_ERR, "cannot set uid to %d: %s\n",
(int)GETPCONFIG(s)->uid, strerror(e));
exit(EXIT_FAILURE);
}
}

View File

@@ -17,7 +17,7 @@
*/
#ifndef OC_ISOLATE_H
# define OC_ISOLATE_H
#define OC_ISOLATE_H
void set_worker_fd_limits(struct worker_st *);

View File

@@ -1,18 +1,18 @@
#if HAVE_CONFIG_H
# include "config.h"
#include "config.h"
#endif
#include <libtasn1.h>
const asn1_static_node kkdcp_asn1_tab[] = {
{ "KKDCP", 536872976, NULL },
{ NULL, 1073741836, NULL },
{ "KDC-PROXY-MESSAGE", 536870917, NULL },
{ "kerb-message", 1610620935, NULL },
{ NULL, 2056, "0"},
{ "target-domain", 1610637339, NULL },
{ NULL, 2056, "1"},
{ "dclocator-hint", 536895491, NULL },
{ NULL, 2056, "2"},
{ NULL, 0, NULL }
{ "KKDCP", 536872976, NULL },
{ NULL, 1073741836, NULL },
{ "KDC-PROXY-MESSAGE", 536870917, NULL },
{ "kerb-message", 1610620935, NULL },
{ NULL, 2056, "0" },
{ "target-domain", 1610637339, NULL },
{ NULL, 2056, "1" },
{ "dclocator-hint", 536895491, NULL },
{ NULL, 2056, "2" },
{ NULL, 0, NULL }
};

View File

@@ -34,8 +34,8 @@
/* This global variable is used by oc_syslog() */
int global_log_prio = DEFAULT_LOG_LEVEL;
void __attribute__ ((format(printf, 2, 3)))
oc_syslog(int priority, const char *fmt, ...)
void __attribute__((format(printf, 2, 3))) oc_syslog(int priority,
const char *fmt, ...)
{
char buf[512];
va_list args;

119
src/log.h
View File

@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_LOG_H
# define OC_LOG_H
#define OC_LOG_H
#include <stdint.h>
#include <stdio.h>
@@ -31,9 +31,9 @@ extern int global_log_prio;
/* For logging in the main process or sec-mod use the following:
* mslog(const struct main_server_st * s, const struct proc_st* proc,
* int priority, const char *fmt, ...);
* int priority, const char *fmt, ...);
* seclog(const struct sec_mod_st* sec, int priority, const char *fmt, ...);
* int priority, const char *fmt, ...);
* int priority, const char *fmt, ...);
*
* For logging in the worker process:
* oclog(const struct worker_st * server, int priority, const char *fmt, ...);
@@ -47,28 +47,32 @@ extern int global_log_prio;
*/
#ifdef __GNUC__
# define _oc_syslog(prio, fmt, ...) do { \
if (syslog_open) { \
syslog(prio, fmt, ## __VA_ARGS__); \
} else { \
fprintf(stderr, fmt "\n", ## __VA_ARGS__); \
}} while(0)
#define _oc_syslog(prio, fmt, ...) \
do { \
if (syslog_open) { \
syslog(prio, fmt, ##__VA_ARGS__); \
} else { \
fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
} \
} while (0)
#else
# define _oc_syslog(prio, ...) do { \
if (syslog_open) { \
syslog(prio, __VA_ARGS__); \
} else { \
fprintf(stderr, __VA_ARGS__); \
fputc('\n', stderr); \
}} while(0)
#define _oc_syslog(prio, ...) \
do { \
if (syslog_open) { \
syslog(prio, __VA_ARGS__); \
} else { \
fprintf(stderr, __VA_ARGS__); \
fputc('\n', stderr); \
} \
} while (0)
#endif
#ifdef UNDER_TEST
/* for testing */
# define mslog(...)
# define oclog(...)
# define seclog(...)
# define oc_syslog _oc_syslog
#define mslog(...)
#define oclog(...)
#define seclog(...)
#define oc_syslog _oc_syslog
#else
@@ -77,54 +81,56 @@ struct worker_st;
struct proc_st;
struct sec_mod_st;
void
__attribute__ ((format(printf, 4, 5)))
_mslog(const struct main_server_st * s, const struct proc_st* proc,
int priority, const char *fmt, ...);
void __attribute__((format(printf, 4, 5)))
_mslog(const struct main_server_st *s, const struct proc_st *proc, int priority,
const char *fmt, ...);
void __attribute__ ((format(printf, 3, 4)))
_oclog(const struct worker_st * server, int priority, const char *fmt, ...);
void __attribute__((format(printf, 3, 4)))
_oclog(const struct worker_st *server, int priority, const char *fmt, ...);
void __attribute__ ((format(printf, 3, 4)))
_seclog(const struct sec_mod_st* sec, int priority, const char *fmt, ...);
void __attribute__((format(printf, 3, 4)))
_seclog(const struct sec_mod_st *sec, int priority, const char *fmt, ...);
void __attribute__ ((format(printf, 2, 3)))
oc_syslog(int priority, const char *fmt, ...);
void __attribute__((format(printf, 2, 3))) oc_syslog(int priority,
const char *fmt, ...);
#ifdef __GNUC__
#define mslog(s, proc, prio, fmt, ...) \
(prio == LOG_ERR) ? _mslog(s, proc, prio, "%s:%d: " fmt, __FILE__, \
__LINE__, ##__VA_ARGS__) : \
_mslog(s, proc, prio, fmt, ##__VA_ARGS__)
# ifdef __GNUC__
# define mslog(s, proc, prio, fmt, ...) \
(prio==LOG_ERR)?_mslog(s, proc, prio, "%s:%d: "fmt, __FILE__, __LINE__, ##__VA_ARGS__): \
_mslog(s, proc, prio, fmt, ##__VA_ARGS__)
#define oclog(server, prio, fmt, ...) \
(prio == LOG_ERR) ? _oclog(server, prio, "%s:%d: " fmt, __FILE__, \
__LINE__, ##__VA_ARGS__) : \
_oclog(server, prio, fmt, ##__VA_ARGS__)
# define oclog(server, prio, fmt, ...) \
(prio==LOG_ERR)?_oclog(server, prio, "%s:%d: "fmt, __FILE__, __LINE__, ##__VA_ARGS__): \
_oclog(server, prio, fmt, ##__VA_ARGS__)
#define seclog(sec, prio, fmt, ...) \
(prio == LOG_ERR) ? _seclog(sec, prio, "%s:%d: " fmt, __FILE__, \
__LINE__, ##__VA_ARGS__) : \
_seclog(sec, prio, fmt, ##__VA_ARGS__)
#else
#define mslog _mslog
#define seclog _seclog
#define oclog _oclog
#endif
# define seclog(sec, prio, fmt, ...) \
(prio==LOG_ERR)?_seclog(sec, prio, "%s:%d: "fmt, __FILE__, __LINE__, ##__VA_ARGS__): \
_seclog(sec, prio, fmt, ##__VA_ARGS__)
# else
# define mslog _mslog
# define seclog _seclog
# define oclog _oclog
# endif
void mslog_hex(const struct main_server_st *s, const struct proc_st *proc,
int priority, const char *prefix, uint8_t *bin,
unsigned int bin_size, unsigned int b64);
void mslog_hex(const struct main_server_st * s, const struct proc_st* proc,
int priority, const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64);
void oclog_hex(const struct worker_st *ws, int priority, const char *prefix,
uint8_t *bin, unsigned int bin_size, unsigned int b64);
void oclog_hex(const struct worker_st* ws, int priority,
const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64);
void seclog_hex(const struct sec_mod_st* sec, int priority,
const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64);
void seclog_hex(const struct sec_mod_st *sec, int priority, const char *prefix,
uint8_t *bin, unsigned int bin_size, unsigned int b64);
#endif
/* Returns zero when the given priority is not sufficient
* for logging. Updates the priority with */
inline static
unsigned log_check_priority(int oc_priority, int log_prio, int *syslog_prio)
inline static unsigned int log_check_priority(int oc_priority, int log_prio,
int *syslog_prio)
{
switch (oc_priority) {
case LOG_ERR:
@@ -157,7 +163,6 @@ unsigned log_check_priority(int oc_priority, int log_prio, int *syslog_prio)
if (log_prio < OCLOG_TRANSFERRED)
return 0;
if (syslog_prio)
*syslog_prio = LOG_DEBUG;
break;
@@ -173,9 +178,9 @@ unsigned log_check_priority(int oc_priority, int log_prio, int *syslog_prio)
if (syslog_prio)
*syslog_prio = LOG_DEBUG;
}
}
return 1;
return 1;
}
#endif /* OC_LOG_H */

122
src/lzs.c
View File

@@ -23,9 +23,9 @@
#include "lzs.h"
#define GET_BITS(bits) \
do { \
/* Strictly speaking, this check ought to be on \
#define GET_BITS(bits) \
do { \
/* Strictly speaking, this check ought to be on \
* (srclen < 1 + (bits_left < bits)). However, when bits == 9 \
* the (bits_left < bits) comparison is always true so it \
* always comes out as (srclen < 2). \
@@ -33,40 +33,43 @@ do { \
* reading part of a match encoding. And in that case, there \
* damn well ought to be an end marker (7 more bits) after \
* what we're reading now, so it's perfectly OK to use \
* (srclen < 2) in that case too. And a *lot* cheaper. */ \
if (srclen < 2) \
return -EINVAL; \
/* Explicit comparison with 8 to optimise it into a tautology \
* (srclen < 2) in that case too. And a *lot* cheaper. */ \
if (srclen < 2) \
return -EINVAL; \
/* Explicit comparison with 8 to optimise it into a tautology \
* in the bits == 9 case, because the compiler doesn't
* know that bits_left can never be larger than 8. */ \
if (bits >= 8 || bits >= bits_left) { \
/* We need *all* the bits that are left in the current \
* byte. Take them and bump the input pointer. */ \
data = (src[0] << (bits - bits_left)) & ((1 << bits) - 1); \
src++; \
srclen--; \
bits_left += 8 - bits; \
if (bits > 8 || bits_left < 8) { \
/* We need bits from the next byte too... */ \
data |= src[0] >> bits_left; \
/* ...if we used *all* of them then (which can \
* know that bits_left can never be larger than 8. */ \
if (bits >= 8 || bits >= bits_left) { \
/* We need *all* the bits that are left in the current \
* byte. Take them and bump the input pointer. */ \
data = (src[0] << (bits - bits_left)) & \
((1 << bits) - 1); \
src++; \
srclen--; \
bits_left += 8 - bits; \
if (bits > 8 || bits_left < 8) { \
/* We need bits from the next byte too... */ \
data |= src[0] >> bits_left; \
/* ...if we used *all* of them then (which can \
* only happen if bits > 8), then bump the \
* input pointer again so we never leave \
* bits_left == 0. */ \
if (bits > 8 && !bits_left) { \
bits_left = 8; \
src++; \
srclen--; \
} \
} \
} else { \
/* We need fewer bits than are left in the current byte */ \
data = (src[0] >> (bits_left - bits)) & ((1ULL << bits) - 1); \
bits_left -= bits; \
} \
} while (0)
* bits_left == 0. */ \
if (bits > 8 && !bits_left) { \
bits_left = 8; \
src++; \
srclen--; \
} \
} \
} else { \
/* We need fewer bits than are left in the current byte */ \
data = (src[0] >> (bits_left - bits)) & \
((1ULL << bits) - 1); \
bits_left -= bits; \
} \
} while (0)
int lzs_decompress(unsigned char *dst, int dstlen, const unsigned char *src, int srclen)
int lzs_decompress(unsigned char *dst, int dstlen, const unsigned char *src,
int srclen)
{
int outlen = 0;
int bits_left = 8; /* Bits left in the current byte at *src */
@@ -140,24 +143,24 @@ int lzs_decompress(unsigned char *dst, int dstlen, const unsigned char *src, int
return -EINVAL;
}
#define PUT_BITS(nr, bits) \
do { \
outbits <<= (nr); \
outbits |= (bits); \
nr_outbits += (nr); \
if ((nr) > 8) { \
nr_outbits -= 8; \
if (outpos == dstlen) \
return -EFBIG; \
dst[outpos++] = outbits >> nr_outbits; \
} \
if (nr_outbits >= 8) { \
nr_outbits -= 8; \
if (outpos == dstlen) \
return -EFBIG; \
dst[outpos++] = outbits >> nr_outbits; \
} \
} while (0)
#define PUT_BITS(nr, bits) \
do { \
outbits <<= (nr); \
outbits |= (bits); \
nr_outbits += (nr); \
if ((nr) > 8) { \
nr_outbits -= 8; \
if (outpos == dstlen) \
return -EFBIG; \
dst[outpos++] = outbits >> nr_outbits; \
} \
if (nr_outbits >= 8) { \
nr_outbits -= 8; \
if (outpos == dstlen) \
return -EFBIG; \
dst[outpos++] = outbits >> nr_outbits; \
} \
} while (0)
struct oc_packed_uint16_t {
uint16_t d;
@@ -167,7 +170,8 @@ struct oc_packed_uint16_t {
* Much of the compression algorithm used here is based very loosely on ideas
* from isdn_lzscomp.c by Andre Beck: http://micky.ibh.de/~beck/stuff/lzs4i4l/
*/
int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int srclen)
int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src,
int srclen)
{
int length, offset;
int inpos = 0, outpos = 0;
@@ -203,7 +207,7 @@ int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int s
* offset will yield the previous offset at which the same data hash
* value was found.
*/
#define MAX_HISTORY (1<<11) /* Highest offset LZS can represent is 11 bits */
#define MAX_HISTORY (1 << 11) /* Highest offset LZS can represent is 11 bits */
uint16_t hash_chain[MAX_HISTORY];
/* Just in case anyone tries to use this in a more general-purpose
@@ -234,10 +238,10 @@ int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int s
for (; hofs != INVALID_OFS && hofs + MAX_HISTORY > inpos;
hofs = hash_chain[hofs & (MAX_HISTORY - 1)]) {
/* We only get here if longest_match_len is >= 2. We need to find
a match of longest_match_len + 1 for it to be interesting. */
if (!memcmp(src + hofs + 2, src + inpos + 2, longest_match_len - 1)) {
if (!memcmp(src + hofs + 2, src + inpos + 2,
longest_match_len - 1)) {
longest_match_ofs = hofs;
do {
@@ -248,7 +252,8 @@ int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int s
if (longest_match_len + inpos == srclen)
goto got_match;
} while (src[longest_match_len + inpos] == src[longest_match_len + hofs]);
} while (src[longest_match_len + inpos] ==
src[longest_match_len + hofs]);
}
/* Typical compressor tuning would have a break out of the loop
@@ -261,7 +266,7 @@ int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int s
something. Anyway, we currently don't give up until we run out
of reachable history — maximal compression. */
}
got_match:
got_match:
/* Output offset, as 7-bit or 11-bit as appropriate */
offset = inpos - longest_match_ofs;
length = longest_match_len;
@@ -298,7 +303,8 @@ int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int s
inpos++;
while (--longest_match_len) {
hash = HASH(src + inpos);
hash_chain[inpos & (MAX_HISTORY - 1)] = hash_table[hash];
hash_chain[inpos & (MAX_HISTORY - 1)] =
hash_table[hash];
hash_table[hash] = inpos++;
}
}

View File

@@ -16,9 +16,11 @@
*/
#ifndef OC_LZS_H
# define OC_LZS_H
#define OC_LZS_H
int lzs_decompress(unsigned char *dst, int dstlen, const unsigned char *src, int srclen);
int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int srclen);
int lzs_decompress(unsigned char *dst, int dstlen, const unsigned char *src,
int srclen);
int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src,
int srclen);
#endif

View File

@@ -46,7 +46,7 @@
#include <common.h>
/* Puts the provided PIN into the config's cgroup */
void put_into_cgroup(main_server_st * s, const char *_cgroup, pid_t pid)
void put_into_cgroup(main_server_st *s, const char *_cgroup, pid_t pid)
{
#ifdef __linux__
char *name, *p, *savep;
@@ -72,8 +72,8 @@ void put_into_cgroup(main_server_st * s, const char *_cgroup, pid_t pid)
p = strtok_r(cgroup, ",", &savep);
while (p != NULL) {
mslog(s, NULL, LOG_DEBUG,
"putting process %u to cgroup '%s:%s'", (unsigned)pid, p,
name);
"putting process %u to cgroup '%s:%s'", (unsigned int)pid,
p, name);
snprintf(file, sizeof(file), "/sys/fs/cgroup/%s/%s/tasks", p,
name);
@@ -84,7 +84,7 @@ void put_into_cgroup(main_server_st * s, const char *_cgroup, pid_t pid)
return;
}
if (fprintf(fd, "%u", (unsigned)pid) <= 0) {
if (fprintf(fd, "%u", (unsigned int)pid) <= 0) {
mslog(s, NULL, LOG_ERR, "could not write to: %s", file);
}
fclose(fd);
@@ -99,8 +99,7 @@ void put_into_cgroup(main_server_st * s, const char *_cgroup, pid_t pid)
#endif
}
int send_cookie_auth_reply(main_server_st* s, struct proc_st* proc,
AUTHREP r)
int send_cookie_auth_reply(main_server_st *s, struct proc_st *proc, AUTHREP r)
{
AuthCookieReplyMsg msg = AUTH_COOKIE_REPLY_MSG__INIT;
int ret;
@@ -126,36 +125,43 @@ int send_cookie_auth_reply(main_server_st* s, struct proc_st* proc,
msg.group_name = proc->groupname;
if (proc->ipv4 && proc->ipv4->rip_len > 0) {
msg.ipv4 = human_addr2((struct sockaddr*)&proc->ipv4->rip, proc->ipv4->rip_len,
ipv4, sizeof(ipv4), 0);
msg.ipv4_local = human_addr2((struct sockaddr*)&proc->ipv4->lip, proc->ipv4->lip_len,
ipv4_local, sizeof(ipv4_local), 0);
msg.ipv4 = human_addr2(
(struct sockaddr *)&proc->ipv4->rip,
proc->ipv4->rip_len, ipv4, sizeof(ipv4), 0);
msg.ipv4_local =
human_addr2((struct sockaddr *)&proc->ipv4->lip,
proc->ipv4->lip_len, ipv4_local,
sizeof(ipv4_local), 0);
}
if (proc->ipv6 && proc->ipv6->rip_len > 0) {
msg.ipv6 = human_addr2((struct sockaddr*)&proc->ipv6->rip, proc->ipv6->rip_len,
ipv6, sizeof(ipv6), 0);
msg.ipv6_local = human_addr2((struct sockaddr*)&proc->ipv6->lip, proc->ipv6->lip_len,
ipv6_local, sizeof(ipv6_local), 0);
msg.ipv6 = human_addr2(
(struct sockaddr *)&proc->ipv6->rip,
proc->ipv6->rip_len, ipv6, sizeof(ipv6), 0);
msg.ipv6_local =
human_addr2((struct sockaddr *)&proc->ipv6->lip,
proc->ipv6->lip_len, ipv6_local,
sizeof(ipv6_local), 0);
}
msg.config = proc->config;
ret = send_socket_msg_to_worker(s, proc, AUTH_COOKIE_REP, proc->tun_lease.fd,
&msg,
(pack_size_func)auth_cookie_reply_msg__get_packed_size,
(pack_func)auth_cookie_reply_msg__pack);
ret = send_socket_msg_to_worker(
s, proc, AUTH_COOKIE_REP, proc->tun_lease.fd, &msg,
(pack_size_func)auth_cookie_reply_msg__get_packed_size,
(pack_func)auth_cookie_reply_msg__pack);
} else {
msg.reply = AUTH__REP__FAILED;
ret = send_msg_to_worker(s, proc, AUTH_COOKIE_REP,
&msg,
(pack_size_func)auth_cookie_reply_msg__get_packed_size,
(pack_func)auth_cookie_reply_msg__pack);
ret = send_msg_to_worker(
s, proc, AUTH_COOKIE_REP, &msg,
(pack_size_func)auth_cookie_reply_msg__get_packed_size,
(pack_func)auth_cookie_reply_msg__pack);
}
if (ret < 0) {
int e = errno;
mslog(s, proc, LOG_ERR, "send_msg: %s", strerror(e));
return ret;
}
@@ -163,10 +169,11 @@ int send_cookie_auth_reply(main_server_st* s, struct proc_st* proc,
return 0;
}
int handle_auth_cookie_req(sec_mod_instance_st * sec_mod_instance, struct proc_st* proc,
const AuthCookieRequestMsg * req)
int handle_auth_cookie_req(sec_mod_instance_st *sec_mod_instance,
struct proc_st *proc,
const AuthCookieRequestMsg *req)
{
main_server_st * s = sec_mod_instance->server;
main_server_st *s = sec_mod_instance->server;
int ret;
struct proc_st *old_proc;
@@ -175,7 +182,8 @@ int handle_auth_cookie_req(sec_mod_instance_st * sec_mod_instance, struct proc_s
/* generate a new DTLS session ID for each connection, to allow
* openconnect of distinguishing when the DTLS key has switched. */
ret = gnutls_rnd(GNUTLS_RND_NONCE, proc->dtls_session_id, sizeof(proc->dtls_session_id));
ret = gnutls_rnd(GNUTLS_RND_NONCE, proc->dtls_session_id,
sizeof(proc->dtls_session_id));
if (ret < 0)
return -1;
proc->dtls_session_id_size = sizeof(proc->dtls_session_id);
@@ -184,13 +192,15 @@ int handle_auth_cookie_req(sec_mod_instance_st * sec_mod_instance, struct proc_s
old_proc = proc_search_sid(s, req->cookie.data);
if (old_proc != NULL) {
if (old_proc->invalidated != 0) {
mslog(s, proc, LOG_ERR, "the reused session has been invalidated");
mslog(s, proc, LOG_ERR,
"the reused session has been invalidated");
return -1;
}
}
/* loads sup config and basic proc info (e.g., username) */
ret = session_open(sec_mod_instance, proc, req->cookie.data, req->cookie.len);
ret = session_open(sec_mod_instance, proc, req->cookie.data,
req->cookie.len);
if (ret < 0) {
mslog(s, proc, LOG_INFO, "could not open session");
return -1;
@@ -204,12 +214,14 @@ int handle_auth_cookie_req(sec_mod_instance_st * sec_mod_instance, struct proc_s
/* disconnect and reuse previous session's IPs*/
if (old_proc != NULL) {
if (strcmp(proc->username, old_proc->username) != 0) {
mslog(s, old_proc, LOG_ERR, "the user of the new session doesn't match the old (new: %s)",
mslog(s, old_proc, LOG_ERR,
"the user of the new session doesn't match the old (new: %s)",
proc->username);
return -1;
}
mslog(s, old_proc, LOG_INFO, "disconnecting previous user session due to session reuse");
mslog(s, old_proc, LOG_INFO,
"disconnecting previous user session due to session reuse");
/* steal its leases */
steal_ip_leases(old_proc, proc);
@@ -248,20 +260,22 @@ int handle_auth_cookie_req(sec_mod_instance_st * sec_mod_instance, struct proc_s
* used had been reused before, and then disconnect the old session
* (cookies are unique).
*/
int check_multiple_users(main_server_st *s, struct proc_st* proc)
int check_multiple_users(main_server_st *s, struct proc_st *proc)
{
struct proc_st *ctmp = NULL, *cpos;
unsigned int entries = 1; /* that one */
unsigned max;
unsigned int max;
max = proc->config->max_same_clients;
if (max == 0)
return 0;
list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) {
list_for_each_safe(&s->proc_list.head, ctmp, cpos, list)
{
if (ctmp != proc && ctmp->pid != -1) {
if (!ctmp->pid_killed && strcmp(proc->username, ctmp->username) == 0) {
if (!ctmp->pid_killed &&
strcmp(proc->username, ctmp->username) == 0) {
entries++;
if (entries > max)

View File

@@ -45,11 +45,13 @@
#include <ifaddrs.h>
#include <sys/socket.h>
static bool if_address_test_local(main_server_st * s, struct sockaddr_storage *addr);
static bool if_address_test_local(main_server_st *s,
struct sockaddr_storage *addr);
static size_t rehash(const void *_e, void *unused)
{
ban_entry_st *e = (void*)_e;
ban_entry_st *e = (void *)_e;
return hash_any(e->ip.ip, e->ip.size, 0);
}
@@ -61,15 +63,16 @@ static bool ban_entry_cmp(const void *_c1, void *_c2)
const struct ban_entry_st *c1 = _c1;
struct ban_entry_st *c2 = _c2;
if (c1->ip.size == c2->ip.size && memcmp(c1->ip.ip, c2->ip.ip, c1->ip.size) == 0)
if (c1->ip.size == c2->ip.size &&
memcmp(c1->ip.ip, c2->ip.ip, c1->ip.size) == 0)
return 1;
return 0;
}
void *main_ban_db_init(main_server_st *s)
{
struct htable *db = talloc(s, struct htable);
if (db == NULL) {
oc_syslog(LOG_ERR, "error initializing ban DB\n");
exit(EXIT_FAILURE);
@@ -93,13 +96,13 @@ void main_ban_db_deinit(main_server_st *s)
#define IS_BANNED(main, entry) (entry->score >= GETCONFIG(main)->max_ban_score)
unsigned main_ban_db_elems(main_server_st *s)
unsigned int main_ban_db_elems(main_server_st *s)
{
struct htable *db = s->ban_db;
ban_entry_st *t;
struct htable_iter iter;
time_t now = time(NULL);
unsigned banned = 0;
unsigned int banned = 0;
if (db == NULL || GETCONFIG(s)->max_ban_score == 0)
return 0;
@@ -122,8 +125,8 @@ static void massage_ipv6_address(ban_entry_st *t)
}
/* returns -1 if the user is already banned, and zero otherwise */
static
int add_ip_to_ban_list(main_server_st *s, const unsigned char *ip, unsigned ip_size, unsigned score)
static int add_ip_to_ban_list(main_server_st *s, const unsigned char *ip,
unsigned int ip_size, unsigned int score)
{
struct htable *db = s->ban_db;
struct ban_entry_st *e;
@@ -133,9 +136,10 @@ int add_ip_to_ban_list(main_server_st *s, const unsigned char *ip, unsigned ip_s
int ret = 0;
char str_ip[MAX_IP_STR];
const char *p_str_ip = NULL;
unsigned print_msg;
unsigned int print_msg;
if (db == NULL || GETCONFIG(s)->max_ban_score == 0 || ip == NULL || (ip_size != 4 && ip_size != 16))
if (db == NULL || GETCONFIG(s)->max_ban_score == 0 || ip == NULL ||
(ip_size != 4 && ip_size != 16))
return 0;
memcpy(t.ip.ip, ip, ip_size);
@@ -156,7 +160,7 @@ int add_ip_to_ban_list(main_server_st *s, const unsigned char *ip, unsigned ip_s
if (htable_add(db, rehash(e, NULL), e) == 0) {
mslog(s, NULL, LOG_INFO,
"could not add ban entry to hash table");
"could not add ban entry to hash table");
goto fail;
}
} else {
@@ -176,7 +180,8 @@ int add_ip_to_ban_list(main_server_st *s, const unsigned char *ip, unsigned ip_s
print_msg = 0;
/* prevent overflow */
e->score = (e->score + score) > e->score ? (e->score + score) : (e->score);
e->score = (e->score + score) > e->score ? (e->score + score) :
(e->score);
if (ip_size == 4)
p_str_ip = inet_ntop(AF_INET, ip, str_ip, sizeof(str_ip));
@@ -187,32 +192,41 @@ int add_ip_to_ban_list(main_server_st *s, const unsigned char *ip, unsigned ip_s
if (print_msg && p_str_ip) {
char date[256];
struct tm tm;
if ((localtime_r(&e->expires, &tm) == NULL) || (strftime(date, sizeof(date), "%a %b %e %H:%M:%S %Y", &tm) == 0)) {
if ((localtime_r(&e->expires, &tm) == NULL) ||
(strftime(date, sizeof(date),
"%a %b %e %H:%M:%S %Y", &tm) == 0)) {
date[0] = 0;
}
mslog(s, NULL, LOG_INFO, "added IP '%s' (with score %d) to ban list, will be reset at: %s", str_ip, e->score, date);
mslog(s, NULL, LOG_INFO,
"added IP '%s' (with score %d) to ban list, will be reset at: %s",
str_ip, e->score, date);
}
ret = -1;
} else {
if (p_str_ip) {
mslog(s, NULL, LOG_DEBUG, "added %d points (total %d) for IP '%s' to ban list", score, e->score, str_ip);
mslog(s, NULL, LOG_DEBUG,
"added %d points (total %d) for IP '%s' to ban list",
score, e->score, str_ip);
}
ret = 0;
}
return ret;
fail:
fail:
talloc_free(e);
return ret;
}
int add_str_ip_to_ban_list(main_server_st *s, const char *ip, unsigned score)
int add_str_ip_to_ban_list(main_server_st *s, const char *ip,
unsigned int score)
{
struct htable *db = s->ban_db;
ban_entry_st t;
int ret = 0;
if (db == NULL || GETCONFIG(s)->max_ban_score == 0 || ip == NULL || ip[0] == 0)
if (db == NULL || GETCONFIG(s)->max_ban_score == 0 || ip == NULL ||
ip[0] == 0)
return 0;
if (strchr(ip, ':') != 0) {
@@ -223,8 +237,7 @@ int add_str_ip_to_ban_list(main_server_st *s, const char *ip, unsigned score)
t.ip.size = 4;
}
if (ret != 1) {
mslog(s, NULL, LOG_INFO,
"could not read IP: %s", ip);
mslog(s, NULL, LOG_INFO, "could not read IP: %s", ip);
return 0;
}
@@ -232,7 +245,8 @@ int add_str_ip_to_ban_list(main_server_st *s, const char *ip, unsigned score)
}
/* returns non-zero if there is an IP removed */
int remove_ip_from_ban_list(main_server_st *s, const uint8_t *ip, unsigned size)
int remove_ip_from_ban_list(main_server_st *s, const uint8_t *ip,
unsigned int size)
{
struct htable *db = s->ban_db;
struct ban_entry_st *e;
@@ -243,9 +257,9 @@ int remove_ip_from_ban_list(main_server_st *s, const uint8_t *ip, unsigned size)
return 0;
if (size == 4 || size == 16) {
if (inet_ntop(size==16?AF_INET6:AF_INET, ip, txt_ip, sizeof(txt_ip)) != NULL) {
mslog(s, NULL, LOG_INFO,
"unbanning IP '%s'", txt_ip);
if (inet_ntop(size == 16 ? AF_INET6 : AF_INET, ip, txt_ip,
sizeof(txt_ip)) != NULL) {
mslog(s, NULL, LOG_INFO, "unbanning IP '%s'", txt_ip);
}
t.ip.size = size;
@@ -265,12 +279,13 @@ int remove_ip_from_ban_list(main_server_st *s, const uint8_t *ip, unsigned size)
return 0;
}
unsigned check_if_banned(main_server_st *s, struct sockaddr_storage *addr, socklen_t addr_size)
unsigned int check_if_banned(main_server_st *s, struct sockaddr_storage *addr,
socklen_t addr_size)
{
struct htable *db = s->ban_db;
time_t now;
ban_entry_st t, *e;
unsigned in_size;
unsigned int in_size;
char txt[MAX_IP_STR];
if (db == NULL || GETCONFIG(s)->max_ban_score == 0)
@@ -279,24 +294,30 @@ unsigned check_if_banned(main_server_st *s, struct sockaddr_storage *addr, sockl
(void)(txt);
if (if_address_test_local(s, addr)) {
mslog(s, NULL, LOG_DEBUG, "Not applying ban to local IP: %s", human_addr2((struct sockaddr*)addr, addr_size, txt, sizeof(txt), 0));
mslog(s, NULL, LOG_DEBUG, "Not applying ban to local IP: %s",
human_addr2((struct sockaddr *)addr, addr_size, txt,
sizeof(txt), 0));
return 0;
}
in_size = SA_IN_SIZE(addr_size);
if (in_size != 4 && in_size != 16) {
mslog(s, NULL, LOG_ERR, "unknown address type for %s", human_addr2((struct sockaddr*)addr, addr_size, txt, sizeof(txt), 0));
mslog(s, NULL, LOG_ERR, "unknown address type for %s",
human_addr2((struct sockaddr *)addr, addr_size, txt,
sizeof(txt), 0));
return 0;
}
memcpy(t.ip.ip, SA_IN_P_GENERIC(addr, addr_size), SA_IN_SIZE(addr_size));
memcpy(t.ip.ip, SA_IN_P_GENERIC(addr, addr_size),
SA_IN_SIZE(addr_size));
t.ip.size = SA_IN_SIZE(addr_size);
/* In IPv6 treat a /64 as a single address */
massage_ipv6_address(&t);
/* add its current connection points */
add_ip_to_ban_list(s, t.ip.ip, t.ip.size, GETCONFIG(s)->ban_points_connect);
add_ip_to_ban_list(s, t.ip.ip, t.ip.size,
GETCONFIG(s)->ban_points_connect);
now = time(NULL);
e = htable_get(db, rehash(&t, NULL), ban_entry_cmp, &t);
@@ -305,7 +326,10 @@ unsigned check_if_banned(main_server_st *s, struct sockaddr_storage *addr, sockl
return 0;
if (e->score >= GETCONFIG(s)->max_ban_score) {
mslog(s, NULL, LOG_INFO, "rejected connection from banned IP: %s", human_addr2((struct sockaddr*)addr, addr_size, txt, sizeof(txt), 0));
mslog(s, NULL, LOG_INFO,
"rejected connection from banned IP: %s",
human_addr2((struct sockaddr *)addr, addr_size,
txt, sizeof(txt), 0));
return 1;
}
}
@@ -324,27 +348,30 @@ void cleanup_banned_entries(main_server_st *s)
t = htable_first(db, &iter);
while (t != NULL) {
if (now >= t->expires && now > t->last_reset + GETCONFIG(s)->ban_reset_time) {
if (now >= t->expires &&
now > t->last_reset + GETCONFIG(s)->ban_reset_time) {
htable_delval(db, &iter);
talloc_free(t);
}
t = htable_next(db, &iter);
}
}
int if_address_init(main_server_st *s)
{
struct ifaddrs * ifaddr = NULL, *ifa;
if_address_st * local_if_addresses = NULL;
struct ifaddrs *ifaddr = NULL, *ifa;
if_address_st *local_if_addresses = NULL;
int retval = 0;
unsigned count = 0;
unsigned int count = 0;
s->if_addresses_count = 0;
s->if_addresses = NULL;
if (getifaddrs(&ifaddr) < 0) {
int err = errno;
oc_syslog(LOG_ERR, "Failed to read local if address list: %s", strerror(err));
oc_syslog(LOG_ERR, "Failed to read local if address list: %s",
strerror(err));
goto cleanup;
}
@@ -352,7 +379,7 @@ int if_address_init(main_server_st *s)
if (ifa->ifa_addr == NULL) {
continue;
}
count ++;
count++;
}
local_if_addresses = talloc_array(s, if_address_st, count);
@@ -365,13 +392,16 @@ int if_address_init(main_server_st *s)
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
sa_family_t family;
if (ifa->ifa_addr == NULL) {
continue;
}
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6) {
memcpy(&local_if_addresses[count].if_addr, ifa->ifa_addr, sizeof(struct sockaddr));
memcpy(&local_if_addresses[count].if_netmask, ifa->ifa_netmask, sizeof(struct sockaddr));
memcpy(&local_if_addresses[count].if_addr,
ifa->ifa_addr, sizeof(struct sockaddr));
memcpy(&local_if_addresses[count].if_netmask,
ifa->ifa_netmask, sizeof(struct sockaddr));
count++;
}
}
@@ -392,45 +422,61 @@ cleanup:
return retval;
}
static bool test_local_ipv4(struct sockaddr_in * remote, struct sockaddr_in * local, struct sockaddr_in * network)
static bool test_local_ipv4(struct sockaddr_in *remote,
struct sockaddr_in *local,
struct sockaddr_in *network)
{
uint32_t l = local->sin_addr.s_addr & network->sin_addr.s_addr;
uint32_t r = remote->sin_addr.s_addr & network->sin_addr.s_addr;
if (l != r)
return false;
else
return true;
}
static bool test_local_ipv6(struct sockaddr_in6 * remote, struct sockaddr_in6 * local, struct sockaddr_in6 * network)
static bool test_local_ipv6(struct sockaddr_in6 *remote,
struct sockaddr_in6 *local,
struct sockaddr_in6 *network)
{
unsigned index = 0;
unsigned int index = 0;
for (index = 0; index < 4; index++) {
uint32_t l = local->sin6_addr.s6_addr32[index] &
network->sin6_addr.s6_addr32[index];
uint32_t r = remote->sin6_addr.s6_addr32[index] &
network->sin6_addr.s6_addr32[index];
for (index = 0; index < 4; index ++) {
uint32_t l = local->sin6_addr.s6_addr32[index] & network->sin6_addr.s6_addr32[index];
uint32_t r = remote->sin6_addr.s6_addr32[index] & network->sin6_addr.s6_addr32[index];
if (l != r)
return false;
}
return true;
}
static bool if_address_test_local(main_server_st * s, struct sockaddr_storage *addr)
static bool if_address_test_local(main_server_st *s,
struct sockaddr_storage *addr)
{
unsigned index;
for (index = 0; index < s->if_addresses_count; index ++)
{
if_address_st * ifa = &s->if_addresses[index];
unsigned int index;
for (index = 0; index < s->if_addresses_count; index++) {
if_address_st *ifa = &s->if_addresses[index];
if (ifa->if_addr.sa_family != addr->ss_family)
continue;
switch (addr->ss_family) {
case AF_INET:
if (test_local_ipv4((struct sockaddr_in *)addr, (struct sockaddr_in *)&ifa->if_addr, (struct sockaddr_in *)&ifa->if_netmask))
if (test_local_ipv4(
(struct sockaddr_in *)addr,
(struct sockaddr_in *)&ifa->if_addr,
(struct sockaddr_in *)&ifa->if_netmask))
return true;
break;
case AF_INET6:
if (test_local_ipv6((struct sockaddr_in6 *)addr, (struct sockaddr_in6 *)&ifa->if_addr, (struct sockaddr_in6 *)&ifa->if_netmask))
if (test_local_ipv6(
(struct sockaddr_in6 *)addr,
(struct sockaddr_in6 *)&ifa->if_addr,
(struct sockaddr_in6 *)&ifa->if_netmask))
return true;
break;
default:
@@ -440,7 +486,7 @@ static bool if_address_test_local(main_server_st * s, struct sockaddr_storage *a
return false;
}
void if_address_cleanup(main_server_st * s)
void if_address_cleanup(main_server_st *s)
{
if (s->if_addresses)
talloc_free(s->if_addresses);

View File

@@ -19,32 +19,35 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_MAIN_BAN_H
# define OC_MAIN_BAN_H
#define OC_MAIN_BAN_H
# include "main.h"
#include "main.h"
typedef struct inaddr_st {
uint8_t ip[16];
unsigned size; /* 4 or 16 */
unsigned int size; /* 4 or 16 */
} inaddr_st;
typedef struct ban_entry_st {
inaddr_st ip;
unsigned score;
unsigned int score;
time_t last_reset; /* the time its score counting started */
time_t expires; /* the time after the client is allowed to login */
} ban_entry_st;
void cleanup_banned_entries(main_server_st *s);
unsigned check_if_banned(main_server_st *s, struct sockaddr_storage *addr, socklen_t addr_size);
int add_str_ip_to_ban_list(main_server_st *s, const char *ip, unsigned score);
int remove_ip_from_ban_list(main_server_st *s, const uint8_t *ip, unsigned size);
unsigned main_ban_db_elems(main_server_st *s);
unsigned int check_if_banned(main_server_st *s, struct sockaddr_storage *addr,
socklen_t addr_size);
int add_str_ip_to_ban_list(main_server_st *s, const char *ip,
unsigned int score);
int remove_ip_from_ban_list(main_server_st *s, const uint8_t *ip,
unsigned int size);
unsigned int main_ban_db_elems(main_server_st *s);
void main_ban_db_deinit(main_server_st *s);
void *main_ban_db_init(main_server_st *s);
int if_address_init(main_server_st *s);
void if_address_cleanup(main_server_st * s);
void if_address_cleanup(main_server_st *s);
#endif

View File

@@ -45,46 +45,44 @@ typedef struct method_ctx {
void *pool;
} method_ctx;
static void method_top(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_status(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_list_users(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_disconnect_user_name(method_ctx *ctx, int cfd,
uint8_t * msg, unsigned msg_size);
static void method_disconnect_user_id(method_ctx *ctx, int cfd,
uint8_t * msg, unsigned msg_size);
static void method_unban_ip(method_ctx *ctx, int cfd,
uint8_t * msg, unsigned msg_size);
static void method_stop(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_reload(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_user_info(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_id_info(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_list_banned(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
static void method_top(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_status(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_list_users(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_disconnect_user_name(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_disconnect_user_id(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_unban_ip(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_stop(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_reload(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_user_info(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_id_info(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_list_banned(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
typedef void (*method_func) (method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
typedef void (*method_func)(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size);
typedef struct {
char *name;
unsigned cmd;
unsigned int cmd;
method_func func;
unsigned indefinite; /* session remains open */
unsigned int indefinite; /* session remains open */
} ctl_method_st;
#define ENTRY(cmd, func) \
{#cmd, cmd, func, 0}
#define ENTRY(cmd, func) { #cmd, cmd, func, 0 }
#define ENTRY_INDEF(cmd, func) \
{#cmd, cmd, func, 1}
#define ENTRY_INDEF(cmd, func) { #cmd, cmd, func, 1 }
static const ctl_method_st methods[] = {
ENTRY_INDEF(CTL_CMD_TOP, method_top),
@@ -99,10 +97,10 @@ static const ctl_method_st methods[] = {
ENTRY(CTL_CMD_UNBAN_IP, method_unban_ip),
ENTRY(CTL_CMD_DISCONNECT_NAME, method_disconnect_user_name),
ENTRY(CTL_CMD_DISCONNECT_ID, method_disconnect_user_id),
{NULL, 0, NULL}
{ NULL, 0, NULL }
};
void ctl_handler_deinit(main_server_st * s)
void ctl_handler_deinit(main_server_st *s)
{
if (GETCONFIG(s)->use_occtl == 0)
return;
@@ -116,21 +114,24 @@ void ctl_handler_deinit(main_server_st * s)
/* Initializes unix socket and stores the fd.
*/
int ctl_handler_init(main_server_st * s)
int ctl_handler_init(main_server_st *s)
{
int ret;
struct sockaddr_un sa;
int sd, e;
if (GETCONFIG(s)->use_occtl == 0 || GETPCONFIG(s)->occtl_socket_file == NULL) {
if (GETCONFIG(s)->use_occtl == 0 ||
GETPCONFIG(s)->occtl_socket_file == NULL) {
mslog(s, NULL, LOG_INFO, "not using control unix socket");
return 0;
}
mslog(s, NULL, LOG_DEBUG, "initializing control unix socket: %s", GETPCONFIG(s)->occtl_socket_file);
mslog(s, NULL, LOG_DEBUG, "initializing control unix socket: %s",
GETPCONFIG(s)->occtl_socket_file);
memset(&sa, 0, sizeof(sa));
sa.sun_family = AF_UNIX;
strlcpy(sa.sun_path, GETPCONFIG(s)->occtl_socket_file, sizeof(sa.sun_path));
strlcpy(sa.sun_path, GETPCONFIG(s)->occtl_socket_file,
sizeof(sa.sun_path));
ret = remove(GETPCONFIG(s)->occtl_socket_file);
if (ret != 0) {
e = errno;
@@ -156,7 +157,8 @@ int ctl_handler_init(main_server_st * s)
return -1;
}
ret = chown(GETPCONFIG(s)->occtl_socket_file, GETPCONFIG(s)->uid, GETPCONFIG(s)->gid);
ret = chown(GETPCONFIG(s)->occtl_socket_file, GETPCONFIG(s)->uid,
GETPCONFIG(s)->gid);
if (ret == -1) {
e = errno;
mslog(s, NULL, LOG_ERR, "could not chown socket '%s': %s",
@@ -176,18 +178,20 @@ int ctl_handler_init(main_server_st * s)
return sd;
}
static void method_status(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_status(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
StatusRep rep = STATUS_REP__INIT;
int ret;
unsigned int i;
uint32_t * sec_mod_pids;
uint32_t *sec_mod_pids;
sec_mod_pids = talloc_array(ctx->pool, uint32_t, ctx->s->sec_mod_instance_count);
sec_mod_pids = talloc_array(ctx->pool, uint32_t,
ctx->s->sec_mod_instance_count);
if (sec_mod_pids) {
for (i = 0; i < ctx->s->sec_mod_instance_count; i ++) {
sec_mod_pids[i] = ctx->s->sec_mod_instances[i].sec_mod_pid;
for (i = 0; i < ctx->s->sec_mod_instance_count; i++) {
sec_mod_pids[i] =
ctx->s->sec_mod_instances[i].sec_mod_pid;
}
}
@@ -205,10 +209,14 @@ static void method_status(method_ctx *ctx, int cfd, uint8_t * msg,
rep.stored_tls_sessions = 0;
rep.max_auth_time = 0;
rep.avg_auth_time = 0;
for (i = 0; i < ctx->s->sec_mod_instance_count; i ++) {
rep.secmod_client_entries += ctx->s->sec_mod_instances[i].secmod_client_entries;
rep.stored_tls_sessions += ctx->s->sec_mod_instances[i].tlsdb_entries;
rep.max_auth_time = MAX(rep.max_auth_time, ctx->s->sec_mod_instances[i].max_auth_time);
for (i = 0; i < ctx->s->sec_mod_instance_count; i++) {
rep.secmod_client_entries +=
ctx->s->sec_mod_instances[i].secmod_client_entries;
rep.stored_tls_sessions +=
ctx->s->sec_mod_instances[i].tlsdb_entries;
rep.max_auth_time =
MAX(rep.max_auth_time,
ctx->s->sec_mod_instances[i].max_auth_time);
rep.avg_auth_time = ctx->s->sec_mod_instances[i].avg_auth_time;
}
if (ctx->s->sec_mod_instance_count != 0) {
@@ -232,65 +240,66 @@ static void method_status(method_ctx *ctx, int cfd, uint8_t * msg,
rep.total_auth_failures = ctx->s->stats.total_auth_failures;
rep.total_sessions_closed = ctx->s->stats.total_sessions_closed;
#if defined(CAPTURE_LATENCY_SUPPORT)
rep.latency_median_total = ctx->s->stats.current_latency_stats.median_total;
rep.latency_median_total =
ctx->s->stats.current_latency_stats.median_total;
rep.has_latency_median_total = true;
rep.latency_rms_total = ctx->s->stats.current_latency_stats.rms_total;
rep.has_latency_rms_total = true;
rep.latency_sample_count = ctx->s->stats.current_latency_stats.sample_count;
rep.latency_sample_count =
ctx->s->stats.current_latency_stats.sample_count;
rep.has_latency_sample_count = true;
#endif
ret = send_msg(ctx->pool, cfd, CTL_CMD_STATUS_REP, &rep,
(pack_size_func) status_rep__get_packed_size,
(pack_func) status_rep__pack);
(pack_size_func)status_rep__get_packed_size,
(pack_func)status_rep__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply");
}
}
static void method_reload(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_reload(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
BoolMsg rep = BOOL_MSG__INIT;
int ret;
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: reload");
ev_feed_signal_event (main_loop, SIGHUP);
ev_feed_signal_event(main_loop, SIGHUP);
rep.status = 1;
ret = send_msg(ctx->pool, cfd, CTL_CMD_RELOAD_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
(pack_size_func)bool_msg__get_packed_size,
(pack_func)bool_msg__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply");
}
}
static void method_stop(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_stop(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
BoolMsg rep = BOOL_MSG__INIT;
int ret;
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: stop");
ev_feed_signal_event (main_loop, SIGTERM);
ev_feed_signal_event(main_loop, SIGTERM);
rep.status = 1;
ret = send_msg(ctx->pool, cfd, CTL_CMD_STOP_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
(pack_size_func)bool_msg__get_packed_size,
(pack_func)bool_msg__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply");
}
}
#define IPBUF_SIZE 64
static int append_user_info(method_ctx *ctx,
UserListRep * list,
static int append_user_info(method_ctx *ctx, UserListRep *list,
struct proc_st *ctmp)
{
uint32_t tmp;
@@ -299,8 +308,8 @@ static int append_user_info(method_ctx *ctx,
UserInfoRep *rep;
char *safe_id;
list->user =
talloc_realloc(ctx->pool, list->user, UserInfoRep *, (1 + list->n_user));
list->user = talloc_realloc(ctx->pool, list->user, UserInfoRep *,
(1 + list->n_user));
if (list->user == NULL)
return -1;
@@ -327,9 +336,8 @@ static int append_user_info(method_ctx *ctx,
if (ipbuf == NULL)
return -1;
strtmp =
human_addr2((struct sockaddr *)&ctmp->remote_addr,
ctmp->remote_addr_len, ipbuf, IPBUF_SIZE, 0);
strtmp = human_addr2((struct sockaddr *)&ctmp->remote_addr,
ctmp->remote_addr_len, ipbuf, IPBUF_SIZE, 0);
if (strtmp == NULL)
strtmp = "";
rep->ip = strtmp;
@@ -338,9 +346,8 @@ static int append_user_info(method_ctx *ctx,
if (ipbuf == NULL)
return -1;
strtmp =
human_addr2((struct sockaddr *)&ctmp->our_addr,
ctmp->our_addr_len, ipbuf, IPBUF_SIZE, 0);
strtmp = human_addr2((struct sockaddr *)&ctmp->our_addr,
ctmp->our_addr_len, ipbuf, IPBUF_SIZE, 0);
if (strtmp == NULL)
strtmp = "";
rep->local_dev_ip = strtmp;
@@ -353,9 +360,8 @@ static int append_user_info(method_ctx *ctx,
strtmp = NULL;
if (ctmp->ipv4 != NULL)
strtmp =
human_addr2((struct sockaddr *)&ctmp->ipv4->rip,
ctmp->ipv4->rip_len, ipbuf, IPBUF_SIZE, 0);
strtmp = human_addr2((struct sockaddr *)&ctmp->ipv4->rip,
ctmp->ipv4->rip_len, ipbuf, IPBUF_SIZE, 0);
if (strtmp == NULL)
strtmp = "";
rep->local_ip = strtmp;
@@ -366,9 +372,8 @@ static int append_user_info(method_ctx *ctx,
strtmp = NULL;
if (ctmp->ipv4 != NULL)
strtmp =
human_addr2((struct sockaddr *)&ctmp->ipv4->lip,
ctmp->ipv4->lip_len, ipbuf, IPBUF_SIZE, 0);
strtmp = human_addr2((struct sockaddr *)&ctmp->ipv4->lip,
ctmp->ipv4->lip_len, ipbuf, IPBUF_SIZE, 0);
if (strtmp == NULL)
strtmp = "";
rep->remote_ip = strtmp;
@@ -381,9 +386,8 @@ static int append_user_info(method_ctx *ctx,
strtmp = NULL;
if (ctmp->ipv6 != NULL)
strtmp =
human_addr2((struct sockaddr *)&ctmp->ipv6->rip,
ctmp->ipv6->rip_len, ipbuf, IPBUF_SIZE, 0);
strtmp = human_addr2((struct sockaddr *)&ctmp->ipv6->rip,
ctmp->ipv6->rip_len, ipbuf, IPBUF_SIZE, 0);
if (strtmp == NULL)
strtmp = "";
rep->local_ip6 = strtmp;
@@ -394,9 +398,8 @@ static int append_user_info(method_ctx *ctx,
strtmp = NULL;
if (ctmp->ipv6 != NULL)
strtmp =
human_addr2((struct sockaddr *)&ctmp->ipv6->lip,
ctmp->ipv6->lip_len, ipbuf, IPBUF_SIZE, 0);
strtmp = human_addr2((struct sockaddr *)&ctmp->ipv6->lip,
ctmp->ipv6->lip_len, ipbuf, IPBUF_SIZE, 0);
if (strtmp == NULL)
strtmp = "";
rep->remote_ip6 = strtmp;
@@ -411,7 +414,7 @@ static int append_user_info(method_ctx *ctx,
rep->dtls_ciphersuite = ctmp->dtls_ciphersuite;
calc_safe_id(ctmp->sid, sizeof(ctmp->sid), safe_id, SAFE_ID_SIZE);
rep->safe_id.data = (unsigned char*)safe_id;
rep->safe_id.data = (unsigned char *)safe_id;
rep->safe_id.len = SAFE_ID_SIZE;
rep->cstp_compr = ctmp->cstp_compr;
@@ -438,8 +441,10 @@ static int append_user_info(method_ctx *ctx,
rep->keepalive = ctmp->config->keepalive;
if (ctmp->vhost) {
rep->domains = ctmp->vhost->perm_config.config->split_dns;
rep->n_domains = ctmp->vhost->perm_config.config->split_dns_size;
rep->domains =
ctmp->vhost->perm_config.config->split_dns;
rep->n_domains =
ctmp->vhost->perm_config.config->split_dns_size;
}
rep->dns = ctmp->config->dns;
@@ -464,8 +469,8 @@ static int append_user_info(method_ctx *ctx,
return 0;
}
static void method_list_users(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_list_users(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
UserListRep rep = USER_LIST_REP__INIT;
struct proc_st *ctmp = NULL;
@@ -473,7 +478,8 @@ static void method_list_users(method_ctx *ctx, int cfd, uint8_t * msg,
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: list-users");
list_for_each(&ctx->s->proc_list.head, ctmp, list) {
list_for_each(&ctx->s->proc_list.head, ctmp, list)
{
ret = append_user_info(ctx, &rep, ctmp);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR,
@@ -483,15 +489,15 @@ static void method_list_users(method_ctx *ctx, int cfd, uint8_t * msg,
}
ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep,
(pack_size_func) user_list_rep__get_packed_size,
(pack_func) user_list_rep__pack);
(pack_size_func)user_list_rep__get_packed_size,
(pack_func)user_list_rep__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply");
}
}
static void method_top(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_top(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
/* we send the initial user list, and the we send a TOP reply message
* once a user connects/disconnects. */
@@ -505,15 +511,14 @@ static void method_top(method_ctx *ctx, int cfd, uint8_t * msg,
method_list_users(ctx, cfd, msg, msg_size);
}
static int append_ban_info(method_ctx *ctx,
BanListRep *list,
static int append_ban_info(method_ctx *ctx, BanListRep *list,
struct ban_entry_st *e)
{
BanInfoRep *rep;
main_server_st *s = ctx->s;
list->info =
talloc_realloc(ctx->pool, list->info, BanInfoRep *, (1 + list->n_info));
list->info = talloc_realloc(ctx->pool, list->info, BanInfoRep *,
(1 + list->n_info));
if (list->info == NULL)
return -1;
@@ -528,7 +533,8 @@ static int append_ban_info(method_ctx *ctx,
rep->ip.len = e->ip.size;
rep->score = e->score;
if (GETCONFIG(s)->max_ban_score > 0 && e->score >= GETCONFIG(s)->max_ban_score) {
if (GETCONFIG(s)->max_ban_score > 0 &&
e->score >= GETCONFIG(s)->max_ban_score) {
rep->expires = e->expires;
rep->has_expires = 1;
}
@@ -536,8 +542,8 @@ static int append_ban_info(method_ctx *ctx,
return 0;
}
static void method_list_banned(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_list_banned(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
BanListRep rep = BAN_LIST_REP__INIT;
struct ban_entry_st *e = NULL;
@@ -559,19 +565,21 @@ static void method_list_banned(method_ctx *ctx, int cfd, uint8_t * msg,
}
ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_BANNED_REP, &rep,
(pack_size_func) ban_list_rep__get_packed_size,
(pack_func) ban_list_rep__pack);
(pack_size_func)ban_list_rep__get_packed_size,
(pack_func)ban_list_rep__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ban list reply");
}
}
static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
SecmListCookiesReplyMsg reply = SECM_LIST_COOKIES_REPLY_MSG__INIT;
SecmListCookiesReplyMsg ** sub_replies = NULL;
CookieIntMsg ** cookies = NULL;
SecmListCookiesReplyMsg **sub_replies = NULL;
CookieIntMsg **cookies = NULL;
PROTOBUF_ALLOCATOR(pa, ctx->pool);
size_t total_cookies = 0;
@@ -582,23 +590,31 @@ static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t * msg,
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: list-cookies");
sub_replies = talloc_zero_array(ctx->pool, SecmListCookiesReplyMsg*, ctx->s->sec_mod_instance_count);
sub_replies = talloc_zero_array(ctx->pool, SecmListCookiesReplyMsg *,
ctx->s->sec_mod_instance_count);
if (!sub_replies) {
goto reply_and_exit;
}
for (i = 0; i < ctx->s->sec_mod_instance_count; i++) {
SecmListCookiesReplyMsg * sub_reply = NULL;
ret = send_msg(ctx->pool, ctx->s->sec_mod_instances[i].sec_mod_fd_sync, CMD_SECM_LIST_COOKIES,
NULL, NULL, NULL);
SecmListCookiesReplyMsg *sub_reply = NULL;
ret = send_msg(ctx->pool,
ctx->s->sec_mod_instances[i].sec_mod_fd_sync,
CMD_SECM_LIST_COOKIES, NULL, NULL, NULL);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending list cookies to sec-mod!");
mslog(ctx->s, NULL, LOG_ERR,
"error sending list cookies to sec-mod!");
continue;
}
ret = recv_msg(ctx->pool, ctx->s->sec_mod_instances[i].sec_mod_fd_sync, CMD_SECM_LIST_COOKIES_REPLY,
(void*)&sub_reply, (unpack_func)secm_list_cookies_reply_msg__unpack, MAIN_SEC_MOD_TIMEOUT);
ret = recv_msg(ctx->pool,
ctx->s->sec_mod_instances[i].sec_mod_fd_sync,
CMD_SECM_LIST_COOKIES_REPLY, (void *)&sub_reply,
(unpack_func)secm_list_cookies_reply_msg__unpack,
MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error receiving list cookies reply");
mslog(ctx->s, NULL, LOG_ERR,
"error receiving list cookies reply");
continue;
}
@@ -608,7 +624,7 @@ static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t * msg,
}
}
cookies = talloc_zero_array(ctx->pool, CookieIntMsg*, total_cookies);
cookies = talloc_zero_array(ctx->pool, CookieIntMsg *, total_cookies);
if (!cookies) {
goto reply_and_exit;
}
@@ -628,11 +644,13 @@ reply_and_exit:
reply.cookies = cookies;
reply.n_cookies = total_cookies;
ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_COOKIES_REP, &reply,
(pack_size_func) secm_list_cookies_reply_msg__get_packed_size,
(pack_func) secm_list_cookies_reply_msg__pack);
ret = send_msg(
ctx->pool, cfd, CTL_CMD_LIST_COOKIES_REP, &reply,
(pack_size_func)secm_list_cookies_reply_msg__get_packed_size,
(pack_func)secm_list_cookies_reply_msg__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending list cookies reply");
mslog(ctx->s, NULL, LOG_ERR,
"error sending list cookies reply");
}
if (sub_replies) {
@@ -640,7 +658,8 @@ reply_and_exit:
if (sub_replies[i] == NULL) {
continue;
}
secm_list_cookies_reply_msg__free_unpacked(sub_replies[i], &pa);
secm_list_cookies_reply_msg__free_unpacked(
sub_replies[i], &pa);
}
talloc_free(sub_replies);
}
@@ -650,25 +669,28 @@ reply_and_exit:
}
}
static void single_info_common(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size, const char *user, unsigned id)
static void single_info_common(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size, const char *user,
unsigned int id)
{
UserListRep rep = USER_LIST_REP__INIT;
int ret;
unsigned found_user = 0;
unsigned int found_user = 0;
struct proc_st *ctmp = NULL;
if (user != NULL)
mslog(ctx->s, NULL, LOG_INFO, "providing info for user '%s'", user);
mslog(ctx->s, NULL, LOG_INFO, "providing info for user '%s'",
user);
else
mslog(ctx->s, NULL, LOG_INFO, "providing info for ID '%u'", id);
list_for_each(&ctx->s->proc_list.head, ctmp, list) {
if (user == NULL) { /* id */
list_for_each(&ctx->s->proc_list.head, ctmp, list)
{
if (user == NULL) { /* id */
if (id == 0 || id == -1 || id != ctmp->pid) {
continue;
}
} else { /* username */
} else { /* username */
if (strcmp(ctmp->username, user) != 0) {
continue;
}
@@ -683,28 +705,29 @@ static void single_info_common(method_ctx *ctx, int cfd, uint8_t * msg,
found_user = 1;
if (id != 0) /* id -> one a single element */
if (id != 0) /* id -> one a single element */
break;
}
if (found_user == 0) {
if (user != NULL)
mslog(ctx->s, NULL, LOG_INFO, "could not find user '%s'",
user);
mslog(ctx->s, NULL, LOG_INFO,
"could not find user '%s'", user);
else
mslog(ctx->s, NULL, LOG_INFO, "could not find ID '%u'", id);
mslog(ctx->s, NULL, LOG_INFO, "could not find ID '%u'",
id);
}
ret = send_msg(ctx->pool, cfd, CTL_CMD_LIST_REP, &rep,
(pack_size_func) user_list_rep__get_packed_size,
(pack_func) user_list_rep__pack);
(pack_size_func)user_list_rep__get_packed_size,
(pack_func)user_list_rep__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply");
}
}
static void method_user_info(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_user_info(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
UsernameReq *req;
@@ -720,8 +743,8 @@ static void method_user_info(method_ctx *ctx, int cfd, uint8_t * msg,
username_req__free_unpacked(req, NULL);
}
static void method_id_info(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
static void method_id_info(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
IdReq *req;
@@ -737,9 +760,8 @@ static void method_id_info(method_ctx *ctx, int cfd, uint8_t * msg,
id_req__free_unpacked(req, NULL);
}
static void method_unban_ip(method_ctx *ctx,
int cfd, uint8_t * msg,
unsigned msg_size)
static void method_unban_ip(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
UnbanReq *req;
BoolMsg rep = BOOL_MSG__INIT;
@@ -749,8 +771,7 @@ static void method_unban_ip(method_ctx *ctx,
req = unban_req__unpack(NULL, msg_size, msg);
if (req == NULL) {
mslog(ctx->s, NULL, LOG_ERR,
"error parsing unban IP request");
mslog(ctx->s, NULL, LOG_ERR, "error parsing unban IP request");
return;
}
@@ -761,16 +782,16 @@ static void method_unban_ip(method_ctx *ctx,
unban_req__free_unpacked(req, NULL);
ret = send_msg(ctx->pool, cfd, CTL_CMD_UNBAN_IP_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
(pack_size_func)bool_msg__get_packed_size,
(pack_func)bool_msg__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending unban IP ctl reply");
mslog(ctx->s, NULL, LOG_ERR,
"error sending unban IP ctl reply");
}
}
static void method_disconnect_user_name(method_ctx *ctx,
int cfd, uint8_t * msg,
unsigned msg_size)
static void method_disconnect_user_name(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
UsernameReq *req;
BoolMsg rep = BOOL_MSG__INIT;
@@ -788,7 +809,8 @@ static void method_disconnect_user_name(method_ctx *ctx,
}
/* got the name. Try to disconnect */
list_for_each_safe(&ctx->s->proc_list.head, ctmp, cpos, list) {
list_for_each_safe(&ctx->s->proc_list.head, ctmp, cpos, list)
{
if (strcmp(ctmp->username, req->username) == 0) {
disconnect_proc(ctx->s, ctmp);
rep.status = 1;
@@ -798,15 +820,15 @@ static void method_disconnect_user_name(method_ctx *ctx,
username_req__free_unpacked(req, NULL);
ret = send_msg(ctx->pool, cfd, CTL_CMD_DISCONNECT_NAME_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
(pack_size_func)bool_msg__get_packed_size,
(pack_func)bool_msg__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply");
}
}
static void method_disconnect_user_id(method_ctx *ctx, int cfd,
uint8_t * msg, unsigned msg_size)
static void method_disconnect_user_id(method_ctx *ctx, int cfd, uint8_t *msg,
unsigned int msg_size)
{
IdReq *req;
BoolMsg rep = BOOL_MSG__INIT;
@@ -818,12 +840,14 @@ static void method_disconnect_user_id(method_ctx *ctx, int cfd,
req = id_req__unpack(NULL, msg_size, msg);
if (req == NULL) {
mslog(ctx->s, NULL, LOG_ERR, "error parsing disconnect_id request");
mslog(ctx->s, NULL, LOG_ERR,
"error parsing disconnect_id request");
return;
}
/* got the ID. Try to disconnect */
list_for_each_safe(&ctx->s->proc_list.head, ctmp, cpos, list) {
list_for_each_safe(&ctx->s->proc_list.head, ctmp, cpos, list)
{
if (ctmp->pid == req->id) {
disconnect_proc(ctx->s, ctmp);
rep.status = 1;
@@ -837,8 +861,8 @@ static void method_disconnect_user_id(method_ctx *ctx, int cfd,
id_req__free_unpacked(req, NULL);
ret = send_msg(ctx->pool, cfd, CTL_CMD_DISCONNECT_ID_REP, &rep,
(pack_size_func) bool_msg__get_packed_size,
(pack_func) bool_msg__pack);
(pack_size_func)bool_msg__get_packed_size,
(pack_func)bool_msg__pack);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending ctl reply");
}
@@ -857,8 +881,9 @@ static void ctl_cmd_wacher_cb(EV_P_ ev_io *w, int revents)
uint8_t cmd;
uint8_t buffer[256];
method_ctx ctx;
struct ctl_watcher_st *wst = container_of(w, struct ctl_watcher_st, ctl_cmd_io);
unsigned i, indef = 0;
struct ctl_watcher_st *wst =
container_of(w, struct ctl_watcher_st, ctl_cmd_io);
unsigned int i, indef = 0;
ctx.s = s;
ctx.pool = talloc_new(wst);
@@ -879,7 +904,7 @@ static void ctl_cmd_wacher_cb(EV_P_ ev_io *w, int revents)
if (methods[i].cmd == 0) {
mslog(s, NULL, LOG_INFO,
"unknown unix ctl message: 0x%.1x",
(unsigned)cmd);
(unsigned int)cmd);
break;
} else if (methods[i].cmd == cmd) {
indef = methods[i].indefinite;
@@ -892,7 +917,7 @@ static void ctl_cmd_wacher_cb(EV_P_ ev_io *w, int revents)
talloc_free(ctx.pool);
return;
}
fail:
fail:
if (s->top_fd == wst->fd)
s->top_fd = -1;
close(wst->fd);
@@ -900,7 +925,7 @@ static void ctl_cmd_wacher_cb(EV_P_ ev_io *w, int revents)
talloc_free(wst);
}
static void ctl_handle_commands(main_server_st * s)
static void ctl_handle_commands(main_server_st *s)
{
int cfd = -1, e, ret;
struct sockaddr_un sa;
@@ -916,7 +941,8 @@ static void ctl_handle_commands(main_server_st * s)
goto fail;
}
ret = check_upeer_id("ctl", GETPCONFIG(s)->log_level, cfd, 0, 0, NULL, NULL);
ret = check_upeer_id("ctl", GETPCONFIG(s)->log_level, cfd, 0, 0, NULL,
NULL);
if (ret < 0) {
mslog(s, NULL, LOG_ERR, "ctl: unauthorized connection");
goto fail;
@@ -934,12 +960,12 @@ static void ctl_handle_commands(main_server_st * s)
ev_io_start(main_loop, &wst->ctl_cmd_io);
return;
fail:
fail:
if (cfd != -1)
close(cfd);
}
void ctl_handler_set_fds(main_server_st * s, ev_io *watcher)
void ctl_handler_set_fds(main_server_st *s, ev_io *watcher)
{
if (GETCONFIG(s)->use_occtl == 0)
return;
@@ -947,7 +973,7 @@ void ctl_handler_set_fds(main_server_st * s, ev_io *watcher)
ev_io_set(watcher, s->ctl_fd, EV_READ);
}
void ctl_handler_run_pending(main_server_st* s, ev_io *watcher)
void ctl_handler_run_pending(main_server_st *s, ev_io *watcher)
{
if (GETCONFIG(s)->use_occtl == 0)
return;
@@ -955,7 +981,8 @@ void ctl_handler_run_pending(main_server_st* s, ev_io *watcher)
ctl_handle_commands(s);
}
void ctl_handler_notify (main_server_st* s, struct proc_st *proc, unsigned connect)
void ctl_handler_notify(main_server_st *s, struct proc_st *proc,
unsigned int connect)
{
TopUpdateRep rep = TOP_UPDATE_REP__INIT;
UserListRep list = USER_LIST_REP__INIT;
@@ -979,20 +1006,20 @@ void ctl_handler_notify (main_server_st* s, struct proc_st *proc, unsigned conne
if (connect == 0 && proc->discon_reason) {
rep.has_discon_reason = 1;
rep.discon_reason = proc->discon_reason;
rep.discon_reason_txt = (char*)discon_reason_to_str(proc->discon_reason);
rep.discon_reason_txt =
(char *)discon_reason_to_str(proc->discon_reason);
}
ret = append_user_info(&ctx, &list, proc);
if (ret < 0) {
mslog(s, NULL, LOG_ERR,
"error appending user info to reply");
mslog(s, NULL, LOG_ERR, "error appending user info to reply");
goto fail;
}
rep.user = &list;
ret = send_msg(pool, s->top_fd, CTL_CMD_TOP_UPDATE_REP, &rep,
(pack_size_func) top_update_rep__get_packed_size,
(pack_func) top_update_rep__pack);
(pack_size_func)top_update_rep__get_packed_size,
(pack_func)top_update_rep__pack);
if (ret < 0) {
mslog(s, NULL, LOG_ERR, "error sending ctl reply");
goto fail;
@@ -1000,7 +1027,7 @@ void ctl_handler_notify (main_server_st* s, struct proc_st *proc, unsigned conne
talloc_free(pool);
return;
fail:
fail:
talloc_free(pool);
s->top_fd = -1;
}

View File

@@ -1,14 +1,15 @@
#ifndef OC_MAIN_CTL_H
# define OC_MAIN_CTL_H
#define OC_MAIN_CTL_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_init(main_server_st *s);
void ctl_handler_deinit(main_server_st *s);
void ctl_handler_set_fds(main_server_st* s, ev_io *watcher);
void ctl_handler_run_pending(main_server_st* s, ev_io *watcher);
void ctl_handler_notify (main_server_st* s, struct proc_st *proc, unsigned connect);
void ctl_handler_set_fds(main_server_st *s, ev_io *watcher);
void ctl_handler_run_pending(main_server_st *s, ev_io *watcher);
void ctl_handler_notify(main_server_st *s, struct proc_st *proc,
unsigned int connect);
#endif

View File

@@ -22,14 +22,14 @@
#include <sys/resource.h>
#include <grp.h>
#include <main.h>
#include <limits.h>
void init_fd_limits_default(main_server_st * s)
void init_fd_limits_default(main_server_st *s)
{
#ifdef RLIMIT_NOFILE
int ret = getrlimit(RLIMIT_NOFILE, &s->fd_limits_default_set);
if (ret < 0) {
oc_syslog(LOG_ERR, "error in getrlimit: %s\n", strerror(errno));
exit(EXIT_FAILURE);
@@ -46,11 +46,11 @@ void init_fd_limits_default(main_server_st * s)
/* Adjusts the file descriptor limits for the main or worker processes
*/
void set_main_fd_limits(main_server_st * s)
void set_main_fd_limits(main_server_st *s)
{
#ifdef RLIMIT_NOFILE
struct rlimit new_set;
unsigned max;
unsigned int max;
int ret;
if (GETCONFIG(s)->max_clients > 0)
@@ -66,19 +66,19 @@ void set_main_fd_limits(main_server_st * s)
ret = setrlimit(RLIMIT_NOFILE, &new_set);
if (ret < 0) {
fprintf(stderr,
"error in setrlimit(%u): %s (cur: %u)\n",
max, strerror(errno),
(unsigned)s->fd_limits_default_set.
rlim_cur);
"error in setrlimit(%u): %s (cur: %u)\n", max,
strerror(errno),
(unsigned int)s->fd_limits_default_set.rlim_cur);
}
}
#endif
}
void set_self_oom_score_adj(main_server_st * s)
void set_self_oom_score_adj(main_server_st *s)
{
#ifdef __linux__
static const char proc_self_oom_adj_score_path[] = "/proc/self/oom_score_adj";
static const char proc_self_oom_adj_score_path[] =
"/proc/self/oom_score_adj";
static const char oom_adj_score_value[] = "1000";
size_t written = 0;
int fd;
@@ -87,6 +87,7 @@ void set_self_oom_score_adj(main_server_st * s)
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd == -1) {
int e = errno;
mslog(s, NULL, LOG_ERR, "cannot open %s: %s",
proc_self_oom_adj_score_path, strerror(e));
goto cleanup;
@@ -95,12 +96,13 @@ void set_self_oom_score_adj(main_server_st * s)
written = write(fd, oom_adj_score_value, sizeof(oom_adj_score_value));
if (written != sizeof(oom_adj_score_value)) {
int e = errno;
mslog(s, NULL, LOG_ERR, "cannot write %s: %s",
proc_self_oom_adj_score_path, strerror(e));
goto cleanup;
}
cleanup:
cleanup:
if (fd >= 0) {
close(fd);
}

View File

@@ -17,15 +17,14 @@
*/
#ifndef MAIN_LIMITS_H
# define MAIN_LIMITS_H
#define MAIN_LIMITS_H
void init_fd_limits_default(struct main_server_st * s);
void init_fd_limits_default(struct main_server_st *s);
/* Adjusts the file descriptor limits for the main or worker processes
*/
void set_main_fd_limits(struct main_server_st * s);
void set_main_fd_limits(struct main_server_st *s);
void set_self_oom_score_adj(struct main_server_st * s);
void set_self_oom_score_adj(struct main_server_st *s);
#endif

View File

@@ -32,17 +32,18 @@
#include "log.h"
/* proc is optional */
void __attribute__ ((format(printf, 4, 5)))
_mslog(const main_server_st * s, const struct proc_st* proc,
int priority, const char *fmt, ...)
void __attribute__((format(printf, 4, 5))) _mslog(const main_server_st *s,
const struct proc_st *proc,
int priority, const char *fmt,
...)
{
char buf[512];
char ipbuf[128];
char name[MAX_USERNAME_SIZE+MAX_HOSTNAME_SIZE+3];
const char* ip = NULL;
char name[MAX_USERNAME_SIZE + MAX_HOSTNAME_SIZE + 3];
const char *ip = NULL;
va_list args;
int log_prio = DEFAULT_LOG_LEVEL;
unsigned have_vhosts;
unsigned int have_vhosts;
int syslog_prio;
if (s)
@@ -52,8 +53,8 @@ _mslog(const main_server_st * s, const struct proc_st* proc,
return;
if (proc) {
ip = human_addr((void*)&proc->remote_addr, proc->remote_addr_len,
ipbuf, sizeof(ipbuf));
ip = human_addr((void *)&proc->remote_addr,
proc->remote_addr_len, ipbuf, sizeof(ipbuf));
} else {
ip = "";
}
@@ -62,27 +63,32 @@ _mslog(const main_server_st * s, const struct proc_st* proc,
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
have_vhosts = s?HAVE_VHOSTS(s):0;
have_vhosts = s ? HAVE_VHOSTS(s) : 0;
if (have_vhosts && proc && proc->username[0] != 0) {
snprintf(name, sizeof(name), "[%s%s]", PREFIX_VHOST(proc->vhost), proc->username);
} else if (have_vhosts && proc && proc->username[0] == 0 && proc->vhost && proc->vhost->name) {
snprintf(name, sizeof(name), "[vhost:%s]", VHOSTNAME(proc->vhost));
snprintf(name, sizeof(name), "[%s%s]",
PREFIX_VHOST(proc->vhost), proc->username);
} else if (have_vhosts && proc && proc->username[0] == 0 &&
proc->vhost && proc->vhost->name) {
snprintf(name, sizeof(name), "[vhost:%s]",
VHOSTNAME(proc->vhost));
} else if (proc && proc->username[0] != 0) {
snprintf(name, sizeof(name), "[%s]", proc->username);
} else
name[0] = 0;
_oc_syslog(syslog_prio, "main%s:%s %s", name, ip?ip:"[unknown]", buf);
_oc_syslog(syslog_prio, "main%s:%s %s", name, ip ? ip : "[unknown]",
buf);
}
void mslog_hex(const main_server_st * s, const struct proc_st* proc,
int priority, const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64)
void mslog_hex(const main_server_st *s, const struct proc_st *proc,
int priority, const char *prefix, uint8_t *bin,
unsigned int bin_size, unsigned int b64)
{
char buf[512];
int ret;
size_t buf_size;
gnutls_datum_t data = {bin, bin_size};
gnutls_datum_t data = { bin, bin_size };
int log_prio = DEFAULT_LOG_LEVEL;
if (s)
@@ -92,7 +98,8 @@ void mslog_hex(const main_server_st * s, const struct proc_st* proc,
return;
if (b64) {
oc_base64_encode((char*)bin, bin_size, (char*)buf, sizeof(buf));
oc_base64_encode((char *)bin, bin_size, (char *)buf,
sizeof(buf));
} else {
buf_size = sizeof(buf);
ret = gnutls_hex_encode(&data, buf, &buf_size);
@@ -103,13 +110,13 @@ void mslog_hex(const main_server_st * s, const struct proc_st* proc,
_mslog(s, proc, priority, "%s %s", prefix, buf);
}
void seclog_hex(const struct sec_mod_st* sec, int priority,
const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64)
void seclog_hex(const struct sec_mod_st *sec, int priority, const char *prefix,
uint8_t *bin, unsigned int bin_size, unsigned int b64)
{
char buf[512];
int ret;
size_t buf_size;
gnutls_datum_t data = {bin, bin_size};
gnutls_datum_t data = { bin, bin_size };
int log_prio;
log_prio = GETPCONFIG(sec)->log_level;
@@ -118,7 +125,8 @@ void seclog_hex(const struct sec_mod_st* sec, int priority,
return;
if (b64) {
oc_base64_encode((char*)bin, bin_size, (char*)buf, sizeof(buf));
oc_base64_encode((char *)bin, bin_size, (char *)buf,
sizeof(buf));
} else {
buf_size = sizeof(buf);
ret = gnutls_hex_encode(&data, buf, &buf_size);
@@ -129,8 +137,8 @@ void seclog_hex(const struct sec_mod_st* sec, int priority,
seclog(sec, priority, "%s %s", prefix, buf);
}
void __attribute__ ((format(printf, 3, 4)))
_seclog(const sec_mod_st* sec, int priority, const char *fmt, ...)
void __attribute__((format(printf, 3, 4)))
_seclog(const sec_mod_st *sec, int priority, const char *fmt, ...)
{
char buf[512];
va_list args;

View File

@@ -56,10 +56,11 @@
#include <main-ban.h>
#include <ccan/list/list.h>
struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd,
struct sockaddr_storage *remote_addr, socklen_t remote_addr_len,
struct sockaddr_storage *our_addr, socklen_t our_addr_len,
uint8_t *sid, size_t sid_size)
struct proc_st *new_proc(main_server_st *s, pid_t pid, int cmd_fd,
struct sockaddr_storage *remote_addr,
socklen_t remote_addr_len,
struct sockaddr_storage *our_addr,
socklen_t our_addr_len, uint8_t *sid, size_t sid_size)
{
struct proc_st *ctmp;
@@ -70,7 +71,7 @@ struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd,
ctmp->pid = pid;
ctmp->tun_lease.fd = -1;
ctmp->fd = cmd_fd;
set_cloexec_flag (cmd_fd, 1);
set_cloexec_flag(cmd_fd, 1);
ctmp->conn_time = time(NULL);
memcpy(&ctmp->remote_addr, remote_addr, remote_addr_len);
@@ -92,7 +93,7 @@ struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd,
/* k: whether to kill the process
*/
void remove_proc(main_server_st * s, struct proc_st *proc, unsigned flags)
void remove_proc(main_server_st *s, struct proc_st *proc, unsigned int flags)
{
pid_t pid;
@@ -102,19 +103,25 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned flags)
list_del(&proc->list);
s->stats.active_clients--;
if ((flags&RPROC_KILL) && proc->pid != -1 && proc->pid != 0)
if ((flags & RPROC_KILL) && proc->pid != -1 && proc->pid != 0)
kill(proc->pid, SIGTERM);
/* close any pending sessions */
if (proc->active_sid && !(flags & RPROC_QUIT)) {
if (session_close(&(s->sec_mod_instances[proc->sec_mod_instance_index]), proc) < 0) {
mslog(s, proc, LOG_ERR, "error closing session (communication with sec-mod issue)");
if (session_close(
&(s->sec_mod_instances[proc->sec_mod_instance_index]),
proc) < 0) {
mslog(s, proc, LOG_ERR,
"error closing session (communication with sec-mod issue)");
exit(EXIT_FAILURE);
}
}
mslog(s, proc, discon_reason_to_log_level(proc->discon_reason), "user disconnected (reason: %s, rx: %"PRIu64", tx: %"PRIu64")",
discon_reason_to_str(proc->discon_reason), proc->bytes_in, proc->bytes_out);
mslog(s, proc, discon_reason_to_log_level(proc->discon_reason),
"user disconnected (reason: %s, rx: %" PRIu64 ", tx: %" PRIu64
")",
discon_reason_to_str(proc->discon_reason), proc->bytes_in,
proc->bytes_out);
pid = remove_from_script_list(s, proc);
if (proc->status == PS_AUTH_COMPLETED || pid > 0) {
@@ -128,8 +135,8 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned flags)
user_disconnected(s, proc);
}
} else { /* pid > 0 or status == PS_AUTH_COMPLETED are mutually exclusive
* since PS_AUTH_COMPLETED is set only after a successful script run.
*/
* since PS_AUTH_COMPLETED is set only after a successful script run.
*/
user_disconnected(s, proc);
}
}

View File

@@ -52,13 +52,14 @@
#include <ccan/list/list.h>
#ifdef HAVE_MALLOC_TRIM
# include <malloc.h>
#include <malloc.h>
#endif
static void update_auth_failures(main_server_st * s, uint64_t auth_failures)
static void update_auth_failures(main_server_st *s, uint64_t auth_failures)
{
if (s->stats.auth_failures + auth_failures < s->stats.auth_failures) {
mslog(s, NULL, LOG_INFO, "overflow on updating authentication failures; resetting");
mslog(s, NULL, LOG_INFO,
"overflow on updating authentication failures; resetting");
s->stats.auth_failures = 0;
return;
}
@@ -66,9 +67,9 @@ static void update_auth_failures(main_server_st * s, uint64_t auth_failures)
s->stats.total_auth_failures += auth_failures;
}
int handle_sec_mod_commands(sec_mod_instance_st * sec_mod_instance)
int handle_sec_mod_commands(sec_mod_instance_st *sec_mod_instance)
{
struct main_server_st * s = sec_mod_instance->server;
struct main_server_st *s = sec_mod_instance->server;
struct iovec iov[3];
uint8_t cmd;
struct msghdr hdr;
@@ -76,6 +77,7 @@ int handle_sec_mod_commands(sec_mod_instance_st * sec_mod_instance)
uint8_t *raw;
int ret, raw_len, e;
void *pool = talloc_new(s);
PROTOBUF_ALLOCATOR(pa, pool);
BanIpMsg *tmsg = NULL;
@@ -108,14 +110,17 @@ int handle_sec_mod_commands(sec_mod_instance_st * sec_mod_instance)
return ERR_BAD_COMMAND;
}
if (ret < 5 || cmd <= MIN_SECM_CMD || cmd >= MAX_SECM_CMD || (int)length < 0) {
mslog(s, NULL, LOG_ERR, "main received invalid message from sec-mod of %d bytes (cmd: %u)\n",
(int)length, (unsigned)cmd);
if (ret < 5 || cmd <= MIN_SECM_CMD || cmd >= MAX_SECM_CMD ||
(int)length < 0) {
mslog(s, NULL, LOG_ERR,
"main received invalid message from sec-mod of %d bytes (cmd: %u)\n",
(int)length, (unsigned int)cmd);
return ERR_BAD_COMMAND;
}
mslog(s, NULL, LOG_DEBUG, "main received message '%s' from sec-mod of %u bytes\n",
cmd_request_to_str(cmd), (unsigned)length);
mslog(s, NULL, LOG_DEBUG,
"main received message '%s' from sec-mod of %u bytes\n",
cmd_request_to_str(cmd), (unsigned int)length);
raw = talloc_size(pool, length);
if (raw == NULL) {
@@ -123,86 +128,90 @@ int handle_sec_mod_commands(sec_mod_instance_st * sec_mod_instance)
return ERR_MEM;
}
raw_len = force_read_timeout(sec_mod_instance->sec_mod_fd, raw, length, MAIN_SEC_MOD_TIMEOUT);
raw_len = force_read_timeout(sec_mod_instance->sec_mod_fd, raw, length,
MAIN_SEC_MOD_TIMEOUT);
if (raw_len != length) {
e = errno;
mslog(s, NULL, LOG_ERR,
"cannot obtain data of cmd %u with length %u from sec-mod socket: %s",
(unsigned)cmd, (unsigned)length, strerror(e));
(unsigned int)cmd, (unsigned int)length, strerror(e));
ret = ERR_BAD_COMMAND;
goto cleanup;
}
switch (cmd) {
case CMD_SECM_BAN_IP:{
BanIpReplyMsg reply = BAN_IP_REPLY_MSG__INIT;
case CMD_SECM_BAN_IP: {
BanIpReplyMsg reply = BAN_IP_REPLY_MSG__INIT;
tmsg = ban_ip_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
/* No need to authenticate tmsg->ip as sec-mod is trusted */
ret = add_str_ip_to_ban_list(s, tmsg->ip, tmsg->score);
if (ret < 0) {
reply.reply =
AUTH__REP__FAILED;
} else {
/* no need to send a reply at all */
ret = 0;
goto cleanup;
}
reply.sid.data = tmsg->sid.data;
reply.sid.len = tmsg->sid.len;
reply.has_sid = tmsg->has_sid;
mslog(s, NULL, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_BAN_IP_REPLY));
ret = send_msg(NULL, sec_mod_instance->sec_mod_fd, CMD_SECM_BAN_IP_REPLY,
&reply, (pack_size_func)ban_ip_reply_msg__get_packed_size,
(pack_func)ban_ip_reply_msg__pack);
if (ret < 0) {
mslog(s, NULL, LOG_ERR,
"could not send reply cmd %d.",
(unsigned)cmd);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
safe_memset(tmsg->sid.data, 0, tmsg->sid.len);
safe_memset(raw, 0, raw_len);
tmsg = ban_ip_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
/* No need to authenticate tmsg->ip as sec-mod is trusted */
ret = add_str_ip_to_ban_list(s, tmsg->ip, tmsg->score);
if (ret < 0) {
reply.reply = AUTH__REP__FAILED;
} else {
/* no need to send a reply at all */
ret = 0;
goto cleanup;
}
break;
case CMD_SECM_STATS:{
SecmStatsMsg *smsg = NULL;
reply.sid.data = tmsg->sid.data;
reply.sid.len = tmsg->sid.len;
reply.has_sid = tmsg->has_sid;
smsg = secm_stats_msg__unpack(&pa, raw_len, raw);
if (smsg == NULL) {
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
sec_mod_instance->secmod_client_entries = smsg->secmod_client_entries;
sec_mod_instance->tlsdb_entries = smsg->secmod_tlsdb_entries;
sec_mod_instance->max_auth_time = smsg->secmod_max_auth_time;
sec_mod_instance->avg_auth_time = smsg->secmod_avg_auth_time;
update_auth_failures(s, smsg->secmod_auth_failures);
mslog(s, NULL, LOG_DEBUG, "sending msg %s to sec-mod",
cmd_request_to_str(CMD_SECM_BAN_IP_REPLY));
ret = send_msg(
NULL, sec_mod_instance->sec_mod_fd,
CMD_SECM_BAN_IP_REPLY, &reply,
(pack_size_func)ban_ip_reply_msg__get_packed_size,
(pack_func)ban_ip_reply_msg__pack);
if (ret < 0) {
mslog(s, NULL, LOG_ERR, "could not send reply cmd %d.",
(unsigned int)cmd);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
break;
safe_memset(tmsg->sid.data, 0, tmsg->sid.len);
safe_memset(raw, 0, raw_len);
}
break;
case CMD_SECM_STATS: {
SecmStatsMsg *smsg = NULL;
smsg = secm_stats_msg__unpack(&pa, raw_len, raw);
if (smsg == NULL) {
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
sec_mod_instance->secmod_client_entries =
smsg->secmod_client_entries;
sec_mod_instance->tlsdb_entries = smsg->secmod_tlsdb_entries;
sec_mod_instance->max_auth_time = smsg->secmod_max_auth_time;
sec_mod_instance->avg_auth_time = smsg->secmod_avg_auth_time;
update_auth_failures(s, smsg->secmod_auth_failures);
}
break;
default:
mslog(s, NULL, LOG_ERR, "unknown CMD from sec-mod 0x%x.", (unsigned)cmd);
mslog(s, NULL, LOG_ERR, "unknown CMD from sec-mod 0x%x.",
(unsigned int)cmd);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
ret = 0;
cleanup:
cleanup:
if (tmsg != NULL)
ban_ip_msg__free_unpacked(tmsg, &pa);
talloc_free(raw);
@@ -211,25 +220,29 @@ int handle_sec_mod_commands(sec_mod_instance_st * sec_mod_instance)
return ret;
}
static void append_routes(sec_mod_instance_st * sec_mod_instance, proc_st *proc, GroupCfgSt *gc)
static void append_routes(sec_mod_instance_st *sec_mod_instance, proc_st *proc,
GroupCfgSt *gc)
{
vhost_cfg_st *vhost = proc->vhost;
/* if we have known_iroutes, we must append them to the routes list */
if (vhost->perm_config.config->known_iroutes_size > 0 || vhost->perm_config.config->append_routes) {
if (vhost->perm_config.config->known_iroutes_size > 0 ||
vhost->perm_config.config->append_routes) {
char **old_routes = gc->routes;
unsigned old_routes_size = gc->n_routes;
unsigned i, j, append;
unsigned to_append = 0;
unsigned int old_routes_size = gc->n_routes;
unsigned int i, j, append;
unsigned int to_append = 0;
to_append = vhost->perm_config.config->known_iroutes_size;
if (vhost->perm_config.config->append_routes)
to_append += vhost->perm_config.config->network.routes_size;
to_append +=
vhost->perm_config.config->network.routes_size;
gc->n_routes = 0;
gc->routes = talloc_size(proc, sizeof(char*)*(old_routes_size+to_append));
gc->routes = talloc_size(
proc, sizeof(char *) * (old_routes_size + to_append));
for (i=0;i<old_routes_size;i++) {
for (i = 0; i < old_routes_size; i++) {
gc->routes[i] = talloc_strdup(proc, old_routes[i]);
if (gc->routes[i] == NULL)
break;
@@ -238,17 +251,25 @@ static void append_routes(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
if (gc->routes) {
/* Append any iroutes that are known and don't match the client's */
for (i=0;i<vhost->perm_config.config->known_iroutes_size;i++) {
for (i = 0;
i < vhost->perm_config.config->known_iroutes_size;
i++) {
append = 1;
for (j=0;j<gc->n_iroutes;j++) {
if (strcmp(gc->iroutes[j], vhost->perm_config.config->known_iroutes[i]) == 0) {
for (j = 0; j < gc->n_iroutes; j++) {
if (strcmp(gc->iroutes[j],
vhost->perm_config.config
->known_iroutes[i]) ==
0) {
append = 0;
break;
}
}
if (append) {
gc->routes[gc->n_routes] = talloc_strdup(proc, vhost->perm_config.config->known_iroutes[i]);
gc->routes[gc->n_routes] = talloc_strdup(
proc,
vhost->perm_config.config
->known_iroutes[i]);
if (gc->routes[gc->n_routes] == NULL)
break;
gc->n_routes++;
@@ -259,8 +280,13 @@ static void append_routes(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
if (vhost->perm_config.config->append_routes) {
/* Append all global routes */
if (gc->routes) {
for (i=0;i<vhost->perm_config.config->network.routes_size;i++) {
gc->routes[gc->n_routes] = talloc_strdup(proc, vhost->perm_config.config->network.routes[i]);
for (i = 0; i < vhost->perm_config.config
->network.routes_size;
i++) {
gc->routes[gc->n_routes] = talloc_strdup(
proc,
vhost->perm_config.config
->network.routes[i]);
if (gc->routes[gc->n_routes] == NULL)
break;
gc->n_routes++;
@@ -268,24 +294,36 @@ static void append_routes(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
/* Append no-routes */
if (vhost->perm_config.config->network.no_routes_size == 0)
if (vhost->perm_config.config->network.no_routes_size ==
0)
return;
old_routes = gc->no_routes;
old_routes_size = gc->n_no_routes;
gc->n_no_routes = 0;
gc->no_routes = talloc_size(proc, sizeof(char*)*(old_routes_size+vhost->perm_config.config->network.no_routes_size));
gc->no_routes = talloc_size(
proc,
sizeof(char *) *
(old_routes_size +
vhost->perm_config.config->network
.no_routes_size));
for (i=0;i<old_routes_size;i++) {
gc->no_routes[i] = talloc_strdup(proc, old_routes[i]);
for (i = 0; i < old_routes_size; i++) {
gc->no_routes[i] =
talloc_strdup(proc, old_routes[i]);
if (gc->no_routes[i] == NULL)
break;
gc->n_no_routes++;
}
for (i=0;i<vhost->perm_config.config->network.no_routes_size;i++) {
gc->no_routes[gc->n_no_routes] = talloc_strdup(proc, vhost->perm_config.config->network.no_routes[i]);
for (i = 0;
i <
vhost->perm_config.config->network.no_routes_size;
i++) {
gc->no_routes[gc->n_no_routes] = talloc_strdup(
proc, vhost->perm_config.config->network
.no_routes[i]);
if (gc->no_routes[gc->n_no_routes] == NULL)
break;
gc->n_no_routes++;
@@ -294,13 +332,13 @@ static void append_routes(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
}
static
void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc, GroupCfgSt *gc)
static void apply_default_config(sec_mod_instance_st *sec_mod_instance,
proc_st *proc, GroupCfgSt *gc)
{
vhost_cfg_st *vhost = proc->vhost;
if (!gc->has_no_udp) {
gc->no_udp = (vhost->perm_config.udp_port!=0)?0:1;
gc->no_udp = (vhost->perm_config.udp_port != 0) ? 0 : 1;
gc->has_no_udp = 1;
}
@@ -313,7 +351,8 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
if (gc->no_routes == NULL) {
gc->no_routes = vhost->perm_config.config->network.no_routes;
gc->n_no_routes = vhost->perm_config.config->network.no_routes_size;
gc->n_no_routes =
vhost->perm_config.config->network.no_routes_size;
}
if (gc->dns == NULL) {
@@ -332,12 +371,14 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
if (!gc->has_interim_update_secs) {
gc->interim_update_secs = vhost->perm_config.config->stats_report_time;
gc->interim_update_secs =
vhost->perm_config.config->stats_report_time;
gc->has_interim_update_secs = 1;
}
if (!gc->has_session_timeout_secs) {
gc->session_timeout_secs = vhost->perm_config.config->session_timeout;
gc->session_timeout_secs =
vhost->perm_config.config->session_timeout;
gc->has_session_timeout_secs = 1;
}
@@ -351,7 +392,8 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
if (!gc->ipv4_netmask) {
gc->ipv4_netmask = vhost->perm_config.config->network.ipv4_netmask;
gc->ipv4_netmask =
vhost->perm_config.config->network.ipv4_netmask;
}
if (!gc->ipv6_net) {
@@ -359,12 +401,14 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
if (!gc->has_ipv6_prefix) {
gc->ipv6_prefix = vhost->perm_config.config->network.ipv6_prefix;
gc->ipv6_prefix =
vhost->perm_config.config->network.ipv6_prefix;
gc->has_ipv6_prefix = 1;
}
if (!gc->has_ipv6_subnet_prefix) {
gc->ipv6_subnet_prefix = vhost->perm_config.config->network.ipv6_subnet_prefix;
gc->ipv6_subnet_prefix =
vhost->perm_config.config->network.ipv6_subnet_prefix;
gc->has_ipv6_subnet_prefix = 1;
}
@@ -374,12 +418,14 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
#ifdef ANYCONNECT_CLIENT_COMPAT
if (!gc->xml_config_file) {
gc->xml_config_file = vhost->perm_config.config->xml_config_file;
gc->xml_config_file =
vhost->perm_config.config->xml_config_file;
}
#endif
if (!gc->has_client_bypass_protocol) {
gc->client_bypass_protocol = vhost->perm_config.config->client_bypass_protocol;
gc->client_bypass_protocol =
vhost->perm_config.config->client_bypass_protocol;
gc->has_client_bypass_protocol = 1;
}
@@ -414,7 +460,8 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
if (!gc->has_max_same_clients) {
gc->max_same_clients = vhost->perm_config.config->max_same_clients;
gc->max_same_clients =
vhost->perm_config.config->max_same_clients;
gc->has_max_same_clients = 1;
}
@@ -424,7 +471,8 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
if (!gc->has_restrict_user_to_routes) {
gc->restrict_user_to_routes = vhost->perm_config.config->restrict_user_to_routes;
gc->restrict_user_to_routes =
vhost->perm_config.config->restrict_user_to_routes;
gc->has_restrict_user_to_routes = 1;
}
@@ -439,7 +487,8 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
}
if (!gc->has_mobile_idle_timeout) {
gc->mobile_idle_timeout = vhost->perm_config.config->mobile_idle_timeout;
gc->mobile_idle_timeout =
vhost->perm_config.config->mobile_idle_timeout;
gc->has_mobile_idle_timeout = 1;
}
@@ -453,10 +502,11 @@ void apply_default_config(sec_mod_instance_st * sec_mod_instance, proc_st *proc,
(*proc->config_usage_count)++;
}
int session_open(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc, const uint8_t *cookie, unsigned cookie_size)
int session_open(sec_mod_instance_st *sec_mod_instance, struct proc_st *proc,
const uint8_t *cookie, unsigned int cookie_size)
{
int ret, e;
main_server_st * s = sec_mod_instance->server;
main_server_st *s = sec_mod_instance->server;
SecmSessionOpenMsg ireq = SECM_SESSION_OPEN_MSG__INIT;
SecmSessionReplyMsg *msg = NULL;
char str_ipv4[MAX_IP_STR];
@@ -466,37 +516,43 @@ int session_open(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc, c
if (cookie == NULL || cookie_size != SID_SIZE)
return -1;
ireq.sid.data = (void*)cookie;
ireq.sid.data = (void *)cookie;
ireq.sid.len = cookie_size;
if (proc->ipv4 &&
human_addr2((struct sockaddr *)&proc->ipv4->rip, proc->ipv4->rip_len,
str_ipv4, sizeof(str_ipv4), 0) != NULL) {
if (proc->ipv4 && human_addr2((struct sockaddr *)&proc->ipv4->rip,
proc->ipv4->rip_len, str_ipv4,
sizeof(str_ipv4), 0) != NULL) {
ireq.ipv4 = str_ipv4;
}
if (proc->ipv6 &&
human_addr2((struct sockaddr *)&proc->ipv6->rip, proc->ipv6->rip_len,
str_ipv6, sizeof(str_ipv6), 0) != NULL) {
if (proc->ipv6 && human_addr2((struct sockaddr *)&proc->ipv6->rip,
proc->ipv6->rip_len, str_ipv6,
sizeof(str_ipv6), 0) != NULL) {
ireq.ipv6 = str_ipv6;
}
mslog(s, proc, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_SESSION_OPEN));
mslog(s, proc, LOG_DEBUG, "sending msg %s to sec-mod",
cmd_request_to_str(CMD_SECM_SESSION_OPEN));
ret = send_msg(proc, sec_mod_instance->sec_mod_fd_sync, CMD_SECM_SESSION_OPEN,
&ireq, (pack_size_func)secm_session_open_msg__get_packed_size,
(pack_func)secm_session_open_msg__pack);
ret = send_msg(proc, sec_mod_instance->sec_mod_fd_sync,
CMD_SECM_SESSION_OPEN, &ireq,
(pack_size_func)secm_session_open_msg__get_packed_size,
(pack_func)secm_session_open_msg__pack);
if (ret < 0) {
mslog(s, proc, LOG_ERR,
"error sending message to sec-mod cmd socket");
return -1;
}
ret = recv_msg(proc, sec_mod_instance->sec_mod_fd_sync, CMD_SECM_SESSION_REPLY,
(void *)&msg, (unpack_func) secm_session_reply_msg__unpack, MAIN_SEC_MOD_TIMEOUT);
ret = recv_msg(proc, sec_mod_instance->sec_mod_fd_sync,
CMD_SECM_SESSION_REPLY, (void *)&msg,
(unpack_func)secm_session_reply_msg__unpack,
MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
e = errno;
mslog(s, proc, LOG_ERR, "error receiving auth reply message from sec-mod cmd socket: %s", strerror(e));
mslog(s, proc, LOG_ERR,
"error receiving auth reply message from sec-mod cmd socket: %s",
strerror(e));
return ret;
}
@@ -507,30 +563,37 @@ int session_open(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc, c
}
if (msg->username == NULL) {
mslog(s, proc, LOG_INFO, "no username present in session reply");
mslog(s, proc, LOG_INFO,
"no username present in session reply");
return -1;
}
strlcpy(proc->username, msg->username, sizeof(proc->username));
if (msg->user_agent != NULL) {
strlcpy(proc->user_agent, msg->user_agent, sizeof(proc->user_agent));
strlcpy(proc->user_agent, msg->user_agent,
sizeof(proc->user_agent));
}
if (msg->device_type != NULL) {
strlcpy(proc->device_type, msg->device_type, sizeof(proc->device_type));
strlcpy(proc->device_type, msg->device_type,
sizeof(proc->device_type));
}
if (msg->device_platform != NULL) {
strlcpy(proc->device_platform, msg->device_platform, sizeof(proc->device_platform));
strlcpy(proc->device_platform, msg->device_platform,
sizeof(proc->device_platform));
}
/* override the group name in order to load the correct configuration in
* case his group is specified in the certificate */
if (msg->groupname)
strlcpy(proc->groupname, msg->groupname, sizeof(proc->groupname));
strlcpy(proc->groupname, msg->groupname,
sizeof(proc->groupname));
if (msg->config == NULL) {
mslog(s, proc, LOG_INFO, "received invalid configuration for '%s'; could not initiate session", proc->username);
mslog(s, proc, LOG_INFO,
"received invalid configuration for '%s'; could not initiate session",
proc->username);
return -1;
}
@@ -548,13 +611,15 @@ int session_open(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc, c
return -1;
}
if (human_addr2((struct sockaddr *)&proc->remote_addr, proc->remote_addr_len,
str_ip, sizeof(str_ip), 0) == NULL)
if (human_addr2((struct sockaddr *)&proc->remote_addr,
proc->remote_addr_len, str_ip,
sizeof(str_ip), 0) == NULL)
return -1;
if (strcmp(str_ip, msg->ip) != 0) {
mslog(s, proc, LOG_INFO, "user '%s' is re-using cookie from different IP (prev: %s, current: %s); rejecting",
proc->username, msg->ip, str_ip);
mslog(s, proc, LOG_INFO,
"user '%s' is re-using cookie from different IP (prev: %s, current: %s); rejecting",
proc->username, msg->ip, str_ip);
return -1;
}
}
@@ -568,8 +633,10 @@ static void reset_stats(main_server_st *s, time_t now)
unsigned int i;
unsigned long max_auth_time = 0;
unsigned long avg_auth_time = 0;
for (i = 0; i < s->sec_mod_instance_count; i ++) {
max_auth_time = MAX(max_auth_time, s->sec_mod_instances[i].max_auth_time);
for (i = 0; i < s->sec_mod_instance_count; i++) {
max_auth_time = MAX(max_auth_time,
s->sec_mod_instances[i].max_auth_time);
s->sec_mod_instances[i].max_auth_time = 0;
avg_auth_time += s->sec_mod_instances[i].avg_auth_time;
s->sec_mod_instances[i].avg_auth_time = 0;
@@ -577,20 +644,34 @@ static void reset_stats(main_server_st *s, time_t now)
if (s->sec_mod_instance_count != 0)
avg_auth_time /= s->sec_mod_instance_count;
mslog(s, NULL, LOG_INFO, "Start statistics block");
mslog(s, NULL, LOG_INFO, "Total sessions handled: %lu", (unsigned long)s->stats.total_sessions_closed);
mslog(s, NULL, LOG_INFO, "Sessions handled: %lu", (unsigned long)s->stats.sessions_closed);
mslog(s, NULL, LOG_INFO, "Maximum session time: %lu min", (unsigned long)s->stats.max_session_mins);
mslog(s, NULL, LOG_INFO, "Average session time: %lu min", (unsigned long)s->stats.avg_session_mins);
mslog(s, NULL, LOG_INFO, "Closed due to timeout sessions: %lu", (unsigned long)s->stats.session_timeouts);
mslog(s, NULL, LOG_INFO, "Closed due to timeout (idle) sessions: %lu", (unsigned long)s->stats.session_idle_timeouts);
mslog(s, NULL, LOG_INFO, "Closed due to error sessions: %lu", (unsigned long)s->stats.session_errors);
mslog(s, NULL, LOG_INFO, "Total sessions handled: %lu",
(unsigned long)s->stats.total_sessions_closed);
mslog(s, NULL, LOG_INFO, "Sessions handled: %lu",
(unsigned long)s->stats.sessions_closed);
mslog(s, NULL, LOG_INFO, "Maximum session time: %lu min",
(unsigned long)s->stats.max_session_mins);
mslog(s, NULL, LOG_INFO, "Average session time: %lu min",
(unsigned long)s->stats.avg_session_mins);
mslog(s, NULL, LOG_INFO, "Closed due to timeout sessions: %lu",
(unsigned long)s->stats.session_timeouts);
mslog(s, NULL, LOG_INFO, "Closed due to timeout (idle) sessions: %lu",
(unsigned long)s->stats.session_idle_timeouts);
mslog(s, NULL, LOG_INFO, "Closed due to error sessions: %lu",
(unsigned long)s->stats.session_errors);
mslog(s, NULL, LOG_INFO, "Total authentication failures: %lu", (unsigned long)s->stats.total_auth_failures);
mslog(s, NULL, LOG_INFO, "Authentication failures: %lu", (unsigned long)s->stats.auth_failures);
mslog(s, NULL, LOG_INFO, "Maximum authentication time: %lu sec", max_auth_time);
mslog(s, NULL, LOG_INFO, "Average authentication time: %lu sec", avg_auth_time);
mslog(s, NULL, LOG_INFO, "Data in: %lu, out: %lu kbytes", (unsigned long)s->stats.kbytes_in, (unsigned long)s->stats.kbytes_out);
mslog(s, NULL, LOG_INFO, "End of statistics block; resetting non-total stats");
mslog(s, NULL, LOG_INFO, "Total authentication failures: %lu",
(unsigned long)s->stats.total_auth_failures);
mslog(s, NULL, LOG_INFO, "Authentication failures: %lu",
(unsigned long)s->stats.auth_failures);
mslog(s, NULL, LOG_INFO, "Maximum authentication time: %lu sec",
max_auth_time);
mslog(s, NULL, LOG_INFO, "Average authentication time: %lu sec",
avg_auth_time);
mslog(s, NULL, LOG_INFO, "Data in: %lu, out: %lu kbytes",
(unsigned long)s->stats.kbytes_in,
(unsigned long)s->stats.kbytes_out);
mslog(s, NULL, LOG_INFO,
"End of statistics block; resetting non-total stats");
s->stats.session_idle_timeouts = 0;
s->stats.session_timeouts = 0;
@@ -601,10 +682,9 @@ static void reset_stats(main_server_st *s, time_t now)
s->stats.kbytes_in = 0;
s->stats.kbytes_out = 0;
s->stats.max_session_mins = 0;
}
static void update_main_stats(main_server_st * s, struct proc_st *proc)
static void update_main_stats(main_server_st *s, struct proc_st *proc)
{
uint64_t kb_in, kb_out;
time_t now = time(NULL), stime;
@@ -629,13 +709,13 @@ static void update_main_stats(main_server_st * s, struct proc_st *proc)
goto reset;
}
kb_in = proc->bytes_in/1000;
kb_out = proc->bytes_out/1000;
kb_in = proc->bytes_in / 1000;
kb_out = proc->bytes_out / 1000;
if (s->stats.kbytes_in + kb_in < s->stats.kbytes_in)
if (s->stats.kbytes_in + kb_in < s->stats.kbytes_in)
goto reset;
if (s->stats.kbytes_out + kb_out < s->stats.kbytes_out)
if (s->stats.kbytes_out + kb_out < s->stats.kbytes_out)
goto reset;
s->stats.kbytes_in += kb_in;
@@ -647,25 +727,30 @@ static void update_main_stats(main_server_st * s, struct proc_st *proc)
s->stats.max_mtu = proc->mtu;
/* connection time in minutes */
stime = (now - proc->conn_time)/60;
stime = (now - proc->conn_time) / 60;
if (stime > 0) {
s->stats.avg_session_mins = ((s->stats.sessions_closed-1) * s->stats.avg_session_mins + stime) / s->stats.sessions_closed;
s->stats.avg_session_mins = ((s->stats.sessions_closed - 1) *
s->stats.avg_session_mins +
stime) /
s->stats.sessions_closed;
if (stime > s->stats.max_session_mins)
s->stats.max_session_mins = stime;
}
return;
reset:
mslog(s, NULL, LOG_INFO, "overflow on updating server statistics, resetting stats");
reset:
mslog(s, NULL, LOG_INFO,
"overflow on updating server statistics, resetting stats");
reset_stats(s, now);
}
int session_close(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc)
int session_close(sec_mod_instance_st *sec_mod_instance, struct proc_st *proc)
{
main_server_st * s = sec_mod_instance->server;
main_server_st *s = sec_mod_instance->server;
int ret, e;
SecmSessionCloseMsg ireq = SECM_SESSION_CLOSE_MSG__INIT;
CliStatsMsg *msg = NULL;
PROTOBUF_ALLOCATOR(pa, proc);
ireq.uptime = time(NULL) - proc->conn_time;
@@ -680,22 +765,28 @@ int session_close(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc)
if (proc->invalidated)
ireq.server_disconnected = 1;
mslog(s, proc, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_SESSION_CLOSE));
mslog(s, proc, LOG_DEBUG, "sending msg %s to sec-mod",
cmd_request_to_str(CMD_SECM_SESSION_CLOSE));
ret = send_msg(proc, sec_mod_instance->sec_mod_fd_sync, CMD_SECM_SESSION_CLOSE,
&ireq, (pack_size_func)secm_session_close_msg__get_packed_size,
(pack_func)secm_session_close_msg__pack);
ret = send_msg(proc, sec_mod_instance->sec_mod_fd_sync,
CMD_SECM_SESSION_CLOSE, &ireq,
(pack_size_func)secm_session_close_msg__get_packed_size,
(pack_func)secm_session_close_msg__pack);
if (ret < 0) {
mslog(s, proc, LOG_ERR,
"error sending message to sec-mod cmd socket");
return -1;
}
ret = recv_msg(proc, sec_mod_instance->sec_mod_fd_sync, CMD_SECM_CLI_STATS,
(void *)&msg, (unpack_func) cli_stats_msg__unpack, MAIN_SEC_MOD_TIMEOUT);
ret = recv_msg(proc, sec_mod_instance->sec_mod_fd_sync,
CMD_SECM_CLI_STATS, (void *)&msg,
(unpack_func)cli_stats_msg__unpack,
MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
e = errno;
mslog(s, proc, LOG_ERR, "error receiving auth cli stats message from sec-mod cmd socket: %s", strerror(e));
mslog(s, proc, LOG_ERR,
"error receiving auth cli stats message from sec-mod cmd socket: %s",
strerror(e));
return ret;
}
@@ -712,26 +803,29 @@ int session_close(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc)
return 0;
}
int secmod_reload(sec_mod_instance_st * sec_mod_instance)
int secmod_reload(sec_mod_instance_st *sec_mod_instance)
{
main_server_st * s = sec_mod_instance->server;
main_server_st *s = sec_mod_instance->server;
int ret, e;
mslog(s, NULL, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(CMD_SECM_RELOAD));
mslog(s, NULL, LOG_DEBUG, "sending msg %s to sec-mod",
cmd_request_to_str(CMD_SECM_RELOAD));
ret = send_msg(s->main_pool, sec_mod_instance->sec_mod_fd_sync, CMD_SECM_RELOAD,
NULL, NULL, NULL);
ret = send_msg(s->main_pool, sec_mod_instance->sec_mod_fd_sync,
CMD_SECM_RELOAD, NULL, NULL, NULL);
if (ret < 0) {
mslog(s, NULL, LOG_ERR,
"error sending message to sec-mod cmd socket");
return -1;
}
ret = recv_msg(s->main_pool, sec_mod_instance->sec_mod_fd_sync, CMD_SECM_RELOAD_REPLY,
NULL, NULL, MAIN_SEC_MOD_TIMEOUT);
ret = recv_msg(s->main_pool, sec_mod_instance->sec_mod_fd_sync,
CMD_SECM_RELOAD_REPLY, NULL, NULL, MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
e = errno;
mslog(s, NULL, LOG_ERR, "error receiving reload reply message from sec-mod cmd socket: %s", strerror(e));
mslog(s, NULL, LOG_ERR,
"error receiving reload reply message from sec-mod cmd socket: %s",
strerror(e));
return ret;
}
@@ -743,7 +837,8 @@ static void clear_unneeded_mem(struct list_head *vconfig)
vhost_cfg_st *vhost = NULL;
/* deinitialize certificate credentials etc. */
list_for_each_rev(vconfig, vhost, list) {
list_for_each_rev(vconfig, vhost, list)
{
tls_vhost_deinit(vhost);
}
}
@@ -752,47 +847,59 @@ static void clear_unneeded_mem(struct list_head *vconfig)
* The sync_fd is used by main to send synchronous commands- commands which
* expect a reply immediately.
*/
void run_sec_mod(sec_mod_instance_st * sec_mod_instance, unsigned int instance_index)
void run_sec_mod(sec_mod_instance_st *sec_mod_instance,
unsigned int instance_index)
{
int e, fd[2], ret;
int sfd[2];
pid_t pid;
const char *p;
main_server_st * s = sec_mod_instance->server;
main_server_st *s = sec_mod_instance->server;
/* fills sec_mod_instance->socket_file */
snprintf(sec_mod_instance->socket_file, sizeof(sec_mod_instance->socket_file), "%s.%d", secmod_socket_file_name(GETPCONFIG(s)), instance_index);
mslog(s, NULL, LOG_DEBUG, "created sec-mod socket file (%s)", sec_mod_instance->socket_file);
snprintf(sec_mod_instance->socket_file,
sizeof(sec_mod_instance->socket_file), "%s.%d",
secmod_socket_file_name(GETPCONFIG(s)), instance_index);
mslog(s, NULL, LOG_DEBUG, "created sec-mod socket file (%s)",
sec_mod_instance->socket_file);
if (GETPCONFIG(s)->chroot_dir != NULL) {
ret = snprintf(sec_mod_instance->full_socket_file, sizeof(sec_mod_instance->full_socket_file), "%s/%s",
GETPCONFIG(s)->chroot_dir, sec_mod_instance->socket_file);
ret = snprintf(sec_mod_instance->full_socket_file,
sizeof(sec_mod_instance->full_socket_file),
"%s/%s", GETPCONFIG(s)->chroot_dir,
sec_mod_instance->socket_file);
if (ret != strlen(sec_mod_instance->full_socket_file)) {
mslog(s, NULL, LOG_ERR, "too long chroot path; cannot create socket: %s", sec_mod_instance->full_socket_file);
mslog(s, NULL, LOG_ERR,
"too long chroot path; cannot create socket: %s",
sec_mod_instance->full_socket_file);
exit(EXIT_FAILURE);
}
} else {
strlcpy(sec_mod_instance->full_socket_file, sec_mod_instance->socket_file, sizeof(sec_mod_instance->full_socket_file));
strlcpy(sec_mod_instance->full_socket_file,
sec_mod_instance->socket_file,
sizeof(sec_mod_instance->full_socket_file));
}
p = sec_mod_instance->full_socket_file;
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
if (ret < 0) {
mslog(s, NULL, LOG_ERR, "error creating sec-mod command socket");
mslog(s, NULL, LOG_ERR,
"error creating sec-mod command socket");
exit(EXIT_FAILURE);
}
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sfd);
if (ret < 0) {
mslog(s, NULL, LOG_ERR, "error creating sec-mod sync command socket");
mslog(s, NULL, LOG_ERR,
"error creating sec-mod sync command socket");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid == 0) { /* child */
if (pid == 0) { /* child */
clear_lists(s);
kill_on_parent_kill(SIGTERM);
@@ -804,17 +911,19 @@ void run_sec_mod(sec_mod_instance_st * sec_mod_instance, unsigned int instance_i
setproctitle(PACKAGE "-sm");
close(fd[1]);
close(sfd[1]);
set_cloexec_flag (fd[0], 1);
set_cloexec_flag (sfd[0], 1);
set_cloexec_flag(fd[0], 1);
set_cloexec_flag(sfd[0], 1);
clear_unneeded_mem(s->vconfig);
sec_mod_server(s->main_pool, s->config_pool, s->vconfig, p, fd[0], sfd[0], sizeof(s->hmac_key), s->hmac_key, instance_index);
sec_mod_server(s->main_pool, s->config_pool, s->vconfig, p,
fd[0], sfd[0], sizeof(s->hmac_key), s->hmac_key,
instance_index);
exit(EXIT_SUCCESS);
} else if (pid > 0) { /* parent */
} else if (pid > 0) { /* parent */
close(fd[0]);
close(sfd[0]);
sec_mod_instance->sec_mod_pid = pid;
set_cloexec_flag (fd[1], 1);
set_cloexec_flag (sfd[1], 1);
set_cloexec_flag(fd[1], 1);
set_cloexec_flag(sfd[1], 1);
sec_mod_instance->sec_mod_fd_sync = sfd[1];
sec_mod_instance->sec_mod_fd = fd[1];
return;

View File

@@ -34,7 +34,7 @@
#include <gnutls/crypto.h>
#include <tlslib.h>
#ifdef HAVE_LIBUTIL
# include <utmpx.h>
#include <utmpx.h>
#endif
#include <gettime.h>
@@ -49,13 +49,14 @@
#define OCSERV_FW_SCRIPT "/usr/libexec/ocserv-fw"
#define APPEND_TO_STR(str, val) \
do { \
ret = str_append_str(str, val); \
if (ret < 0) { \
mslog(s, proc, LOG_ERR, "could not append value to environment\n"); \
exit(EXIT_FAILURE); \
} \
#define APPEND_TO_STR(str, val) \
do { \
ret = str_append_str(str, val); \
if (ret < 0) { \
mslog(s, proc, LOG_ERR, \
"could not append value to environment\n"); \
exit(EXIT_FAILURE); \
} \
} while (0)
typedef enum script_type_t {
@@ -64,14 +65,14 @@ typedef enum script_type_t {
SCRIPT_DISCONNECT
} script_type_t;
static const char * const type_name[] = {"up", "host-update", "down"};
static const char *const type_name[] = { "up", "host-update", "down" };
static void export_fw_info(main_server_st *s, struct proc_st* proc)
static void export_fw_info(main_server_st *s, struct proc_st *proc)
{
str_st str4;
str_st str6;
str_st str_common;
unsigned i, negate = 0;
unsigned int i, negate = 0;
int ret;
str_init(&str4, proc);
@@ -82,7 +83,7 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
* with legacy software such as iptables and ip6tables. */
/* append custom routes to str */
for (i=0;i<proc->config->n_routes;i++) {
for (i = 0; i < proc->config->n_routes; i++) {
APPEND_TO_STR(&str_common, proc->config->routes[i]);
APPEND_TO_STR(&str_common, " ");
@@ -95,17 +96,20 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
}
}
if (str4.length > 0 && setenv("OCSERV_ROUTES4", (char*)str4.data, 1) == -1) {
if (str4.length > 0 &&
setenv("OCSERV_ROUTES4", (char *)str4.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export routes\n");
exit(EXIT_FAILURE);
}
if (str6.length > 0 && setenv("OCSERV_ROUTES6", (char*)str6.data, 1) == -1) {
if (str6.length > 0 &&
setenv("OCSERV_ROUTES6", (char *)str6.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export routes\n");
exit(EXIT_FAILURE);
}
if (str_common.length > 0 && setenv("OCSERV_ROUTES", (char*)str_common.data, 1) == -1) {
if (str_common.length > 0 &&
setenv("OCSERV_ROUTES", (char *)str_common.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export routes\n");
exit(EXIT_FAILURE);
}
@@ -117,7 +121,7 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
str_reset(&str_common);
/* append custom no_routes to str */
for (i=0;i<proc->config->n_no_routes;i++) {
for (i = 0; i < proc->config->n_no_routes; i++) {
APPEND_TO_STR(&str_common, proc->config->no_routes[i]);
APPEND_TO_STR(&str_common, " ");
@@ -130,24 +134,28 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
}
}
if (str4.length > 0 && setenv("OCSERV_NO_ROUTES4", (char*)str4.data, 1) == -1) {
if (str4.length > 0 &&
setenv("OCSERV_NO_ROUTES4", (char *)str4.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export no-routes\n");
exit(EXIT_FAILURE);
}
if (str6.length > 0 && setenv("OCSERV_NO_ROUTES6", (char*)str6.data, 1) == -1) {
if (str6.length > 0 &&
setenv("OCSERV_NO_ROUTES6", (char *)str6.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export no-routes\n");
exit(EXIT_FAILURE);
}
if (str_common.length > 0 && setenv("OCSERV_NO_ROUTES", (char*)str_common.data, 1) == -1) {
if (str_common.length > 0 &&
setenv("OCSERV_NO_ROUTES", (char *)str_common.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export no-routes\n");
exit(EXIT_FAILURE);
}
if (proc->config->restrict_user_to_routes) {
if (setenv("OCSERV_RESTRICT_TO_ROUTES", "1", 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export OCSERV_RESTRICT_TO_ROUTES\n");
mslog(s, proc, LOG_ERR,
"could not export OCSERV_RESTRICT_TO_ROUTES\n");
exit(EXIT_FAILURE);
}
}
@@ -158,7 +166,7 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
str_reset(&str_common);
if (proc->config->n_dns > 0) {
for (i=0;i<proc->config->n_dns;i++) {
for (i = 0; i < proc->config->n_dns; i++) {
APPEND_TO_STR(&str_common, proc->config->dns[i]);
APPEND_TO_STR(&str_common, " ");
@@ -172,17 +180,20 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
}
}
if (str4.length > 0 && setenv("OCSERV_DNS4", (char*)str4.data, 1) == -1) {
if (str4.length > 0 &&
setenv("OCSERV_DNS4", (char *)str4.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export DNS servers\n");
exit(EXIT_FAILURE);
}
if (str6.length > 0 && setenv("OCSERV_DNS6", (char*)str6.data, 1) == -1) {
if (str6.length > 0 &&
setenv("OCSERV_DNS6", (char *)str6.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export DNS servers\n");
exit(EXIT_FAILURE);
}
if (str_common.length > 0 && setenv("OCSERV_DNS", (char*)str_common.data, 1) == -1) {
if (str_common.length > 0 &&
setenv("OCSERV_DNS", (char *)str_common.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export DNS servers\n");
exit(EXIT_FAILURE);
}
@@ -196,35 +207,45 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
str_reset(&str_common);
if (proc->config->n_fw_ports > 0) {
for (i=0;i<proc->config->n_fw_ports;i++) {
for (i = 0; i < proc->config->n_fw_ports; i++) {
if (proc->config->fw_ports[i]->negate)
negate = 1;
switch (proc->config->fw_ports[i]->proto) {
case PROTO_UDP:
ret = str_append_printf(&str_common, "udp %u ", proc->config->fw_ports[i]->port);
ret = str_append_printf(
&str_common, "udp %u ",
proc->config->fw_ports[i]->port);
break;
case PROTO_TCP:
ret = str_append_printf(&str_common, "tcp %u ", proc->config->fw_ports[i]->port);
ret = str_append_printf(
&str_common, "tcp %u ",
proc->config->fw_ports[i]->port);
break;
case PROTO_SCTP:
ret = str_append_printf(&str_common, "sctp %u ", proc->config->fw_ports[i]->port);
ret = str_append_printf(
&str_common, "sctp %u ",
proc->config->fw_ports[i]->port);
break;
case PROTO_ICMP:
ret = str_append_printf(&str_common, "icmp all ");
ret = str_append_printf(&str_common,
"icmp all ");
break;
case PROTO_ESP:
ret = str_append_printf(&str_common, "esp all ");
ret = str_append_printf(&str_common,
"esp all ");
break;
case PROTO_ICMPv6:
ret = str_append_printf(&str_common, "icmpv6 all ");
ret = str_append_printf(&str_common,
"icmpv6 all ");
break;
default:
ret = -1;
}
if (ret < 0) {
mslog(s, proc, LOG_ERR, "could not append value to environment\n");
mslog(s, proc, LOG_ERR,
"could not append value to environment\n");
exit(EXIT_FAILURE);
}
}
@@ -232,13 +253,17 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
if (str_common.length > 0) {
if (negate) {
if (setenv("OCSERV_DENY_PORTS", (char*)str_common.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export DENY_PORTS\n");
if (setenv("OCSERV_DENY_PORTS", (char *)str_common.data,
1) == -1) {
mslog(s, proc, LOG_ERR,
"could not export DENY_PORTS\n");
exit(EXIT_FAILURE);
}
} else {
if (setenv("OCSERV_ALLOW_PORTS", (char*)str_common.data, 1) == -1) {
mslog(s, proc, LOG_ERR, "could not export ALLOW_PORTS\n");
if (setenv("OCSERV_ALLOW_PORTS",
(char *)str_common.data, 1) == -1) {
mslog(s, proc, LOG_ERR,
"could not export ALLOW_PORTS\n");
exit(EXIT_FAILURE);
}
}
@@ -247,12 +272,12 @@ static void export_fw_info(main_server_st *s, struct proc_st* proc)
str_clear(&str_common);
}
static
int call_script(main_server_st *s, struct proc_st* proc, script_type_t type)
static int call_script(main_server_st *s, struct proc_st *proc,
script_type_t type)
{
pid_t pid;
int ret;
const char* script, *next_script = NULL;
pid_t pid;
int ret;
const char *script, *next_script = NULL;
if (type == SCRIPT_CONNECT)
script = GETCONFIG(s)->connect_script;
@@ -262,7 +287,8 @@ const char* script, *next_script = NULL;
script = GETCONFIG(s)->disconnect_script;
if (type != SCRIPT_HOST_UPDATE) {
if (proc->config->restrict_user_to_routes || proc->config->n_fw_ports > 0) {
if (proc->config->restrict_user_to_routes ||
proc->config->n_fw_ports > 0) {
next_script = script;
script = OCSERV_FW_SCRIPT;
}
@@ -279,20 +305,32 @@ const char* script, *next_script = NULL;
sigprocmask(SIG_SETMASK, &sig_default_set, NULL);
snprintf(real, sizeof(real), "%u", (unsigned)proc->pid);
snprintf(real, sizeof(real), "%u", (unsigned int)proc->pid);
setenv("ID", real, 1);
if (proc->remote_addr_len > 0) {
if ((ret=getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, real, sizeof(real), NULL, 0, NI_NUMERICHOST)) != 0) {
mslog(s, proc, LOG_DEBUG, "cannot determine peer address: %s; script failed", gai_strerror(ret));
ret = getnameinfo((void *)&proc->remote_addr,
proc->remote_addr_len, real,
sizeof(real), NULL, 0,
NI_NUMERICHOST);
if (ret != 0) {
mslog(s, proc, LOG_DEBUG,
"cannot determine peer address: %s; script failed",
gai_strerror(ret));
exit(EXIT_FAILURE);
}
setenv("IP_REAL", real, 1);
}
if (proc->our_addr_len > 0) {
if ((ret=getnameinfo((void*)&proc->our_addr, proc->our_addr_len, real, sizeof(real), NULL, 0, NI_NUMERICHOST)) != 0) {
mslog(s, proc, LOG_DEBUG, "cannot determine our address: %s", gai_strerror(ret));
ret = getnameinfo((void *)&proc->our_addr,
proc->our_addr_len, real,
sizeof(real), NULL, 0,
NI_NUMERICHOST);
if (ret != 0) {
mslog(s, proc, LOG_DEBUG,
"cannot determine our address: %s",
gai_strerror(ret));
} else {
setenv("IP_REAL_LOCAL", real, 1);
}
@@ -300,16 +338,24 @@ const char* script, *next_script = NULL;
if (proc->ipv4 != NULL || proc->ipv6 != NULL) {
if (proc->ipv4 && proc->ipv4->lip_len > 0) {
if (getnameinfo((void*)&proc->ipv4->lip, proc->ipv4->lip_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG, "cannot determine local VPN address; script failed");
if (getnameinfo((void *)&proc->ipv4->lip,
proc->ipv4->lip_len, local,
sizeof(local), NULL, 0,
NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG,
"cannot determine local VPN address; script failed");
exit(EXIT_FAILURE);
}
setenv("IP_LOCAL", local, 1);
}
if (proc->ipv6 && proc->ipv6->lip_len > 0) {
if (getnameinfo((void*)&proc->ipv6->lip, proc->ipv6->lip_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG, "cannot determine local VPN PtP address; script failed");
if (getnameinfo((void *)&proc->ipv6->lip,
proc->ipv6->lip_len, local,
sizeof(local), NULL, 0,
NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG,
"cannot determine local VPN PtP address; script failed");
exit(EXIT_FAILURE);
}
if (local[0] == 0)
@@ -318,22 +364,31 @@ const char* script, *next_script = NULL;
}
if (proc->ipv4 && proc->ipv4->rip_len > 0) {
if (getnameinfo((void*)&proc->ipv4->rip, proc->ipv4->rip_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG, "cannot determine local VPN address; script failed");
if (getnameinfo((void *)&proc->ipv4->rip,
proc->ipv4->rip_len, remote,
sizeof(remote), NULL, 0,
NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG,
"cannot determine local VPN address; script failed");
exit(EXIT_FAILURE);
}
setenv("IP_REMOTE", remote, 1);
}
if (proc->ipv6 && proc->ipv6->rip_len > 0) {
if (getnameinfo((void*)&proc->ipv6->rip, proc->ipv6->rip_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG, "cannot determine local VPN PtP address; script failed");
if (getnameinfo((void *)&proc->ipv6->rip,
proc->ipv6->rip_len, remote,
sizeof(remote), NULL, 0,
NI_NUMERICHOST) != 0) {
mslog(s, proc, LOG_DEBUG,
"cannot determine local VPN PtP address; script failed");
exit(EXIT_FAILURE);
}
if (remote[0] == 0)
setenv("IP_REMOTE", remote, 1);
setenv("IPV6_REMOTE", remote, 1);
snprintf(remote, sizeof(remote), "%u", proc->ipv6->prefix);
snprintf(remote, sizeof(remote), "%u",
proc->ipv6->prefix);
setenv("IPV6_PREFIX", remote, 1);
}
}
@@ -355,12 +410,16 @@ const char* script, *next_script = NULL;
setenv("REASON", "host-update", 1);
} else if (type == SCRIPT_DISCONNECT) {
/* use remote as temp buffer */
snprintf(remote, sizeof(remote), "%lu", (unsigned long)proc->bytes_in);
snprintf(remote, sizeof(remote), "%lu",
(unsigned long)proc->bytes_in);
setenv("STATS_BYTES_IN", remote, 1);
snprintf(remote, sizeof(remote), "%lu", (unsigned long)proc->bytes_out);
snprintf(remote, sizeof(remote), "%lu",
(unsigned long)proc->bytes_out);
setenv("STATS_BYTES_OUT", remote, 1);
if (proc->conn_time > 0) {
snprintf(remote, sizeof(remote), "%lu", (unsigned long)(time(NULL)-proc->conn_time));
snprintf(remote, sizeof(remote), "%lu",
(unsigned long)(time(NULL) -
proc->conn_time));
setenv("STATS_DURATION", remote, 1);
}
setenv("REASON", "disconnect", 1);
@@ -372,18 +431,25 @@ const char* script, *next_script = NULL;
/* set stdout to be stderr to avoid confusing scripts - note we have stdout closed */
if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
int e = errno;
mslog(s, proc, LOG_INFO, "cannot dup2(STDERR_FILENO, STDOUT_FILENO): %s", strerror(e));
mslog(s, proc, LOG_INFO,
"cannot dup2(STDERR_FILENO, STDOUT_FILENO): %s",
strerror(e));
}
if (next_script) {
setenv("OCSERV_NEXT_SCRIPT", next_script, 1);
mslog(s, proc, LOG_DEBUG, "executing script %s %s (next: %s)", type_name[type], script, next_script);
mslog(s, proc, LOG_DEBUG,
"executing script %s %s (next: %s)",
type_name[type], script, next_script);
} else
mslog(s, proc, LOG_DEBUG, "executing script %s %s", type_name[type], script);
mslog(s, proc, LOG_DEBUG, "executing script %s %s",
type_name[type], script);
ret = execl(script, script, NULL);
if (ret == -1) {
mslog(s, proc, LOG_ERR, "Could not execute script %s", script);
mslog(s, proc, LOG_ERR, "Could not execute script %s",
script);
exit(EXIT_FAILURE);
}
@@ -404,8 +470,7 @@ const char* script, *next_script = NULL;
}
}
static void
add_utmp_entry(main_server_st *s, struct proc_st* proc)
static void add_utmp_entry(main_server_st *s, struct proc_st *proc)
{
#ifdef HAVE_LIBUTIL
struct utmpx entry;
@@ -421,15 +486,19 @@ add_utmp_entry(main_server_st *s, struct proc_st* proc)
strlcpy(entry.ut_user, proc->username, sizeof(entry.ut_user));
#ifdef __linux__
if (proc->remote_addr_len == sizeof(struct sockaddr_in))
memcpy(entry.ut_addr_v6, SA_IN_P(&proc->remote_addr), sizeof(struct in_addr));
memcpy(entry.ut_addr_v6, SA_IN_P(&proc->remote_addr),
sizeof(struct in_addr));
else
memcpy(entry.ut_addr_v6, SA_IN6_P(&proc->remote_addr), sizeof(struct in6_addr));
memcpy(entry.ut_addr_v6, SA_IN6_P(&proc->remote_addr),
sizeof(struct in6_addr));
#endif
gettime(&tv);
entry.ut_tv.tv_sec = tv.tv_sec;
entry.ut_tv.tv_usec = tv.tv_nsec / 1000;
getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, entry.ut_host, sizeof(entry.ut_host), NULL, 0, NI_NUMERICHOST);
getnameinfo((void *)&proc->remote_addr, proc->remote_addr_len,
entry.ut_host, sizeof(entry.ut_host), NULL, 0,
NI_NUMERICHOST);
setutxent();
pututxline(&entry);
@@ -443,7 +512,7 @@ add_utmp_entry(main_server_st *s, struct proc_st* proc)
#endif
}
static void remove_utmp_entry(main_server_st *s, struct proc_st* proc)
static void remove_utmp_entry(main_server_st *s, struct proc_st *proc)
{
#ifdef HAVE_LIBUTIL
struct utmpx entry;
@@ -457,7 +526,8 @@ static void remove_utmp_entry(main_server_st *s, struct proc_st* proc)
memset(&entry, 0, sizeof(entry));
entry.ut_type = DEAD_PROCESS;
if (proc->tun_lease.name[0] != 0)
strlcpy(entry.ut_line, proc->tun_lease.name, sizeof(entry.ut_line));
strlcpy(entry.ut_line, proc->tun_lease.name,
sizeof(entry.ut_line));
entry.ut_pid = proc->pid;
setutxent();
@@ -474,11 +544,11 @@ static void remove_utmp_entry(main_server_st *s, struct proc_st* proc)
#endif
}
int user_connected(main_server_st *s, struct proc_st* proc)
int user_connected(main_server_st *s, struct proc_st *proc)
{
int ret;
int ret;
ctl_handler_notify(s,proc, 1);
ctl_handler_notify(s, proc, 1);
add_utmp_entry(s, proc);
ret = call_script(s, proc, SCRIPT_CONNECT);
@@ -488,7 +558,7 @@ int ret;
return 0;
}
void user_hostname_update(main_server_st *s, struct proc_st* proc)
void user_hostname_update(main_server_st *s, struct proc_st *proc)
{
if (proc->host_updated != 0)
return;
@@ -496,9 +566,9 @@ void user_hostname_update(main_server_st *s, struct proc_st* proc)
proc->host_updated = 1;
}
void user_disconnected(main_server_st *s, struct proc_st* proc)
void user_disconnected(main_server_st *s, struct proc_st *proc)
{
ctl_handler_notify(s,proc, 0);
ctl_handler_notify(s, proc, 0);
remove_utmp_entry(s, proc);
call_script(s, proc, SCRIPT_DISCONNECT);
}

View File

@@ -56,7 +56,7 @@
#include <main-ban.h>
#include <ccan/list/list.h>
int set_tun_mtu(main_server_st * s, struct proc_st *proc, unsigned mtu)
int set_tun_mtu(main_server_st *s, struct proc_st *proc, unsigned int mtu)
{
int fd, ret, e;
struct ifreq ifr;
@@ -79,15 +79,15 @@ int set_tun_mtu(main_server_st * s, struct proc_st *proc, unsigned mtu)
ret = ioctl(fd, SIOCSIFMTU, &ifr);
if (ret != 0) {
e = errno;
mslog(s, proc, LOG_INFO, "ioctl SIOCSIFMTU(%d) error: %s",
mtu, strerror(e));
mslog(s, proc, LOG_INFO, "ioctl SIOCSIFMTU(%d) error: %s", mtu,
strerror(e));
ret = -1;
goto fail;
}
proc->mtu = mtu;
ret = 0;
fail:
fail:
close(fd);
return ret;
}
@@ -119,8 +119,7 @@ int handle_script_exit(main_server_st *s, struct proc_st *proc, int code)
mslog(s, proc, LOG_INFO,
"failed authentication attempt for user '%s'",
proc->username);
ret =
send_cookie_auth_reply(s, proc, AUTH__REP__FAILED);
ret = send_cookie_auth_reply(s, proc, AUTH__REP__FAILED);
if (ret < 0) {
mslog(s, proc, LOG_ERR,
"could not send reply auth cmd.");
@@ -130,7 +129,7 @@ int handle_script_exit(main_server_st *s, struct proc_st *proc, int code)
}
ret = 0;
fail:
fail:
/* we close the lease tun fd both on success and failure.
* The parent doesn't need to keep the tunfd, and if it does,
* it causes issues to client.
@@ -143,7 +142,8 @@ int handle_script_exit(main_server_st *s, struct proc_st *proc, int code)
}
/* This is the function after which proc is populated */
static int accept_user(main_server_st * s, struct proc_st *proc, unsigned cmd)
static int accept_user(main_server_st *s, struct proc_st *proc,
unsigned int cmd)
{
int ret;
const char *group;
@@ -169,8 +169,7 @@ static int accept_user(main_server_st * s, struct proc_st *proc, unsigned cmd)
if (cmd == AUTH_COOKIE_REQ) {
mslog(s, proc, LOG_DEBUG,
"user of group '%s' authenticated (using cookie)",
group);
"user of group '%s' authenticated (using cookie)", group);
} else {
mslog(s, proc, LOG_INFO,
"user of group '%s' authenticated but from unknown state! rejecting.",
@@ -194,7 +193,7 @@ static int accept_user(main_server_st * s, struct proc_st *proc, unsigned cmd)
* @result: the auth result
*/
static int handle_cookie_auth_res(main_server_st *s, struct proc_st *proc,
unsigned cmd, int result)
unsigned int cmd, int result)
{
int ret;
@@ -214,7 +213,7 @@ static int handle_cookie_auth_res(main_server_st *s, struct proc_st *proc,
ret = ERR_BAD_COMMAND;
}
finished:
finished:
if (ret == ERR_WAIT_FOR_SCRIPT) {
/* we will wait for script termination to send our reply.
* The notification of peer will be done in handle_script_exit().
@@ -230,20 +229,20 @@ static int handle_cookie_auth_res(main_server_st *s, struct proc_st *proc,
return ret;
}
int handle_worker_commands(main_server_st * s, struct proc_st *proc)
int handle_worker_commands(main_server_st *s, struct proc_st *proc)
{
uint8_t cmd;
AuthCookieRequestMsg *auth_cookie_req;
size_t length;
uint8_t *raw;
int ret, raw_len, e;
PROTOBUF_ALLOCATOR(pa, proc);
ret = recv_msg_headers(proc->fd, &cmd, MAX_WAIT_SECS);
if (ret < 0) {
if (ret == ERR_PEER_TERMINATED)
mslog(s, proc, LOG_DEBUG,
"worker terminated");
mslog(s, proc, LOG_DEBUG, "worker terminated");
else
mslog(s, proc, LOG_DEBUG,
"cannot obtain metadata from worker's command socket");
@@ -253,14 +252,15 @@ int handle_worker_commands(main_server_st * s, struct proc_st *proc)
length = ret;
if (length > MAX_MSG_SIZE) {
mslog(s, proc, LOG_DEBUG,
"received too big message (%d)", (int)length);
mslog(s, proc, LOG_DEBUG, "received too big message (%d)",
(int)length);
ret = ERR_BAD_COMMAND;
return ret;
}
mslog(s, proc, LOG_DEBUG, "main received worker's message '%s' of %u bytes\n",
cmd_request_to_str(cmd), (unsigned)length);
mslog(s, proc, LOG_DEBUG,
"main received worker's message '%s' of %u bytes\n",
cmd_request_to_str(cmd), (unsigned int)length);
raw = talloc_size(proc, length);
if (raw == NULL) {
@@ -279,138 +279,145 @@ int handle_worker_commands(main_server_st * s, struct proc_st *proc)
}
switch (cmd) {
case CMD_BAN_IP:{
BanIpMsg *tmsg;
BanIpReplyMsg reply = BAN_IP_REPLY_MSG__INIT;
char remote_address[MAX_IP_STR];
case CMD_BAN_IP: {
BanIpMsg *tmsg;
BanIpReplyMsg reply = BAN_IP_REPLY_MSG__INIT;
char remote_address[MAX_IP_STR];
tmsg = ban_ip_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, NULL, LOG_ERR, "error unpacking worker data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
human_addr2((struct sockaddr *)&proc->remote_addr, proc->remote_addr_len, remote_address, sizeof(remote_address), 0);
ret = add_str_ip_to_ban_list(s, remote_address, tmsg->score);
if (tmsg->has_discon_reason) {
proc->discon_reason = tmsg->discon_reason;
}
ban_ip_msg__free_unpacked(tmsg, &pa);
if (ret < 0) {
reply.reply =
AUTH__REP__FAILED;
} else {
reply.reply =
AUTH__REP__OK;
}
ret =
send_msg_to_worker(s, proc, CMD_BAN_IP_REPLY, &reply,
(pack_size_func)
ban_ip_reply_msg__get_packed_size,
(pack_func)
ban_ip_reply_msg__pack);
if (ret < 0) {
mslog(s, NULL, LOG_ERR,
"could not send reply cmd %d.",
(unsigned)cmd);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
}
break;
case CMD_TUN_MTU:{
TunMtuMsg *tmsg;
unsigned minimum_mtu = RFC_791_MTU;
unsigned maximum_mtu =
proc->vhost->perm_config.config->default_mtu != 0 ?
proc->vhost->perm_config.config->default_mtu :
MAX_DTLS_MTU;
if (proc->status != PS_AUTH_COMPLETED) {
mslog(s, proc, LOG_ERR,
"received TUN MTU in unauthenticated state.");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
tmsg = tun_mtu_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, proc, LOG_ERR, "error unpacking data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
if (tmsg->mtu < minimum_mtu || tmsg->mtu > maximum_mtu) {
mslog(s, proc, LOG_ERR,
"worker process invalid MTU %d", (int)tmsg->mtu);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
set_tun_mtu(s, proc, tmsg->mtu);
tun_mtu_msg__free_unpacked(tmsg, &pa);
tmsg = ban_ip_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, NULL, LOG_ERR, "error unpacking worker data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
break;
case CMD_SESSION_INFO:{
SessionInfoMsg *tmsg;
human_addr2((struct sockaddr *)&proc->remote_addr,
proc->remote_addr_len, remote_address,
sizeof(remote_address), 0);
tmsg = session_info_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, proc, LOG_ERR, "error unpacking session info data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
ret = add_str_ip_to_ban_list(s, remote_address, tmsg->score);
if (tmsg->tls_ciphersuite)
strlcpy(proc->tls_ciphersuite, tmsg->tls_ciphersuite,
sizeof(proc->tls_ciphersuite));
if (tmsg->dtls_ciphersuite)
strlcpy(proc->dtls_ciphersuite, tmsg->dtls_ciphersuite,
sizeof(proc->dtls_ciphersuite));
if (tmsg->cstp_compr)
strlcpy(proc->cstp_compr, tmsg->cstp_compr,
sizeof(proc->cstp_compr));
if (tmsg->dtls_compr)
strlcpy(proc->dtls_compr, tmsg->dtls_compr,
sizeof(proc->dtls_compr));
if (tmsg->has_discon_reason) {
proc->discon_reason = tmsg->discon_reason;
}
if (proc->hostname[0] != 0) {
user_hostname_update(s, proc);
}
ban_ip_msg__free_unpacked(tmsg, &pa);
if (GETCONFIG(s)->listen_proxy_proto) {
if (tmsg->has_remote_addr && tmsg->remote_addr.len <= sizeof(struct sockaddr_storage)) {
proc_table_update_ip(s, proc, (struct sockaddr_storage*)tmsg->remote_addr.data, tmsg->remote_addr.len);
if (ret < 0) {
reply.reply = AUTH__REP__FAILED;
} else {
reply.reply = AUTH__REP__OK;
}
/* If the address is in the BAN list, terminate it */
if (check_if_banned(s, &proc->remote_addr, proc->remote_addr_len) != 0) {
if (proc->pid != -1 && proc->pid != 0) {
kill_proc(proc);
}
ret = send_msg_to_worker(
s, proc, CMD_BAN_IP_REPLY, &reply,
(pack_size_func)ban_ip_reply_msg__get_packed_size,
(pack_func)ban_ip_reply_msg__pack);
if (ret < 0) {
mslog(s, NULL, LOG_ERR, "could not send reply cmd %d.",
(unsigned int)cmd);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
} break;
case CMD_TUN_MTU: {
TunMtuMsg *tmsg;
unsigned int minimum_mtu = RFC_791_MTU;
unsigned int maximum_mtu =
proc->vhost->perm_config.config->default_mtu != 0 ?
proc->vhost->perm_config.config->default_mtu :
MAX_DTLS_MTU;
if (proc->status != PS_AUTH_COMPLETED) {
mslog(s, proc, LOG_ERR,
"received TUN MTU in unauthenticated state.");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
tmsg = tun_mtu_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, proc, LOG_ERR, "error unpacking data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
if (tmsg->mtu < minimum_mtu || tmsg->mtu > maximum_mtu) {
mslog(s, proc, LOG_ERR, "worker process invalid MTU %d",
(int)tmsg->mtu);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
set_tun_mtu(s, proc, tmsg->mtu);
tun_mtu_msg__free_unpacked(tmsg, &pa);
}
break;
case CMD_SESSION_INFO: {
SessionInfoMsg *tmsg;
tmsg = session_info_msg__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, proc, LOG_ERR,
"error unpacking session info data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
if (tmsg->tls_ciphersuite)
strlcpy(proc->tls_ciphersuite, tmsg->tls_ciphersuite,
sizeof(proc->tls_ciphersuite));
if (tmsg->dtls_ciphersuite)
strlcpy(proc->dtls_ciphersuite, tmsg->dtls_ciphersuite,
sizeof(proc->dtls_ciphersuite));
if (tmsg->cstp_compr)
strlcpy(proc->cstp_compr, tmsg->cstp_compr,
sizeof(proc->cstp_compr));
if (tmsg->dtls_compr)
strlcpy(proc->dtls_compr, tmsg->dtls_compr,
sizeof(proc->dtls_compr));
if (proc->hostname[0] != 0) {
user_hostname_update(s, proc);
}
if (GETCONFIG(s)->listen_proxy_proto) {
if (tmsg->has_remote_addr &&
tmsg->remote_addr.len <=
sizeof(struct sockaddr_storage)) {
proc_table_update_ip(
s, proc,
(struct sockaddr_storage *)
tmsg->remote_addr.data,
tmsg->remote_addr.len);
/* If the address is in the BAN list, terminate it */
if (check_if_banned(s, &proc->remote_addr,
proc->remote_addr_len) !=
0) {
if (proc->pid != -1 && proc->pid != 0) {
kill_proc(proc);
}
}
if (tmsg->has_our_addr && tmsg->our_addr.len <= sizeof(struct sockaddr_storage) &&
tmsg->our_addr.len > 0) {
memcpy(&proc->our_addr, tmsg->our_addr.data, tmsg->our_addr.len);
proc->our_addr_len = tmsg->our_addr.len;
}
}
session_info_msg__free_unpacked(tmsg, &pa);
if (tmsg->has_our_addr &&
tmsg->our_addr.len <=
sizeof(struct sockaddr_storage) &&
tmsg->our_addr.len > 0) {
memcpy(&proc->our_addr, tmsg->our_addr.data,
tmsg->our_addr.len);
proc->our_addr_len = tmsg->our_addr.len;
}
}
break;
session_info_msg__free_unpacked(tmsg, &pa);
}
break;
case AUTH_COOKIE_REQ:
if (proc->status != PS_AUTH_INACTIVE) {
mslog(s, proc, LOG_ERR,
@@ -420,19 +427,23 @@ int handle_worker_commands(main_server_st * s, struct proc_st *proc)
}
auth_cookie_req =
auth_cookie_request_msg__unpack(&pa, raw_len, raw);
auth_cookie_request_msg__unpack(&pa, raw_len, raw);
if (auth_cookie_req == NULL) {
mslog(s, proc, LOG_ERR, "error unpacking cookie data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
proc->sec_mod_instance_index = auth_cookie_req->cookie.data[0] % s->sec_mod_instance_count;
proc->sec_mod_instance_index = auth_cookie_req->cookie.data[0] %
s->sec_mod_instance_count;
ret = handle_auth_cookie_req(&s->sec_mod_instances[proc->sec_mod_instance_index], proc, auth_cookie_req);
ret = handle_auth_cookie_req(
&s->sec_mod_instances[proc->sec_mod_instance_index],
proc, auth_cookie_req);
safe_memset(raw, 0, raw_len);
safe_memset(auth_cookie_req->cookie.data, 0, auth_cookie_req->cookie.len);
safe_memset(auth_cookie_req->cookie.data, 0,
auth_cookie_req->cookie.len);
auth_cookie_request_msg__free_unpacked(auth_cookie_req, &pa);
@@ -444,39 +455,41 @@ int handle_worker_commands(main_server_st * s, struct proc_st *proc)
break;
#if defined(CAPTURE_LATENCY_SUPPORT)
case CMD_LATENCY_STATS_DELTA:{
LatencyStatsDelta * tmsg;
case CMD_LATENCY_STATS_DELTA: {
LatencyStatsDelta *tmsg;
if (proc->status != PS_AUTH_COMPLETED) {
mslog(s, proc, LOG_ERR,
"received LATENCY STATS DELTA in unauthenticated state.");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
tmsg = latency_stats_delta__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, proc, LOG_ERR, "error unpacking latency stats delta data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
s->stats.delta_latency_stats.median_total += tmsg->median_delta;
s->stats.delta_latency_stats.rms_total += tmsg->rms_delta;
s->stats.delta_latency_stats.sample_count += tmsg->sample_count_delta;
latency_stats_delta__free_unpacked(tmsg, &pa);
if (proc->status != PS_AUTH_COMPLETED) {
mslog(s, proc, LOG_ERR,
"received LATENCY STATS DELTA in unauthenticated state.");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
break;
tmsg = latency_stats_delta__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, proc, LOG_ERR,
"error unpacking latency stats delta data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
s->stats.delta_latency_stats.median_total += tmsg->median_delta;
s->stats.delta_latency_stats.rms_total += tmsg->rms_delta;
s->stats.delta_latency_stats.sample_count +=
tmsg->sample_count_delta;
latency_stats_delta__free_unpacked(tmsg, &pa);
} break;
#endif
default:
mslog(s, proc, LOG_ERR, "unknown CMD from worker: 0x%x", (unsigned)cmd);
mslog(s, proc, LOG_ERR, "unknown CMD from worker: 0x%x",
(unsigned int)cmd);
ret = ERR_BAD_COMMAND;
goto cleanup;
}
ret = 0;
cleanup:
cleanup:
talloc_free(raw);
return ret;

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_MAIN_H
# define OC_MAIN_H
#define OC_MAIN_H
#include <sys/types.h>
#include <sys/socket.h>
@@ -40,8 +40,8 @@
#include <namespace.h>
#if defined(__FreeBSD__) || defined(__OpenBSD__)
# include <limits.h>
# define SOL_IP IPPROTO_IP
#include <limits.h>
#define SOL_IP IPPROTO_IP
#endif
#define COOKIE_KEY_SIZE 16
@@ -56,7 +56,8 @@ extern ev_timer maintainance_watcher;
#define MAIN_MAINTENANCE_TIME (900)
int cmd_parser (void *pool, int argc, char **argv, struct list_head *head, bool worker);
int cmd_parser(void *pool, int argc, char **argv, struct list_head *head,
bool worker);
#if defined(CAPTURE_LATENCY_SUPPORT)
#define LATENCY_AGGREGATION_TIME (60)
@@ -89,7 +90,7 @@ struct script_wait_st {
struct list_node list;
pid_t pid;
struct proc_st* proc;
struct proc_st *proc;
};
/* Each worker process maps to a unique proc_st structure.
@@ -102,7 +103,7 @@ typedef struct proc_st {
struct list_node list;
int fd; /* the command file descriptor */
pid_t pid;
unsigned pid_killed; /* if explicitly disconnected */
unsigned int pid_killed; /* if explicitly disconnected */
time_t udp_fd_receive_time; /* when the corresponding process has received a UDP fd */
@@ -112,7 +113,7 @@ typedef struct proc_st {
struct tun_lease_st tun_lease;
struct ip_lease_st *ipv4;
struct ip_lease_st *ipv6;
unsigned leases_in_use; /* someone else got our IP leases */
unsigned int leases_in_use; /* someone else got our IP leases */
struct sockaddr_storage remote_addr; /* peer address (CSTP) */
socklen_t remote_addr_len;
@@ -125,20 +126,21 @@ typedef struct proc_st {
/* The SID which acts as a cookie */
uint8_t sid[SID_SIZE];
unsigned active_sid;
unsigned int active_sid;
/* non zero if the sid has been invalidated and must not be allowed
* to reconnect. */
unsigned invalidated;
unsigned int invalidated;
/* whether the host-update script has already been called */
unsigned host_updated;
unsigned int host_updated;
/* The DTLS session ID associated with the TLS session
* it is either generated or restored from a cookie.
*/
uint8_t dtls_session_id[GNUTLS_MAX_SESSION_ID];
unsigned dtls_session_id_size; /* would act as a flag if session_id is set */
unsigned int
dtls_session_id_size; /* would act as a flag if session_id is set */
/* The following are set by the worker process (or by a stored cookie) */
char username[MAX_USERNAME_SIZE]; /* the owner */
@@ -154,7 +156,7 @@ typedef struct proc_st {
char dtls_ciphersuite[MAX_CIPHERSUITE_NAME];
char cstp_compr[8];
char dtls_compr[8];
unsigned mtu;
unsigned int mtu;
unsigned int sec_mod_instance_index;
/* if the session is initiated by a cookie the following two are set
@@ -163,7 +165,7 @@ typedef struct proc_st {
*/
uint8_t ipv4_seed[4];
unsigned status; /* PS_AUTH_ */
unsigned int status; /* PS_AUTH_ */
/* these are filled in after the worker process dies, using the
* Cli stats message. */
@@ -171,7 +173,8 @@ typedef struct proc_st {
uint64_t bytes_out;
uint32_t discon_reason; /* filled on session close */
unsigned applied_iroutes; /* whether the iroutes in the config have been successfully applied */
unsigned int
applied_iroutes; /* whether the iroutes in the config have been successfully applied */
/* The following we rely on talloc for deallocation */
GroupCfgSt *config; /* custom user/group config */
@@ -205,7 +208,7 @@ struct proc_hash_db_st {
struct htable *db_dtls_ip;
struct htable *db_dtls_id;
struct htable *db_sid;
unsigned total;
unsigned int total;
};
#if defined(CAPTURE_LATENCY_SUPPORT)
@@ -223,10 +226,10 @@ struct main_stats_st {
uint64_t sessions_closed; /* sessions closed since last reset */
uint64_t kbytes_in;
uint64_t kbytes_out;
unsigned min_mtu;
unsigned max_mtu;
unsigned int min_mtu;
unsigned int max_mtu;
unsigned active_clients;
unsigned int active_clients;
time_t start_time;
time_t last_reset;
@@ -245,20 +248,20 @@ struct main_stats_st {
};
typedef struct sec_mod_instance_st {
struct main_server_st * server;
struct main_server_st *server;
char socket_file[_POSIX_PATH_MAX];
char full_socket_file[_POSIX_PATH_MAX];
pid_t sec_mod_pid;
struct sockaddr_un secmod_addr;
unsigned secmod_addr_len;
unsigned int secmod_addr_len;
int sec_mod_fd; /* messages are sent and received async */
int sec_mod_fd_sync; /* messages are send in a sync order (ping-pong). Only main sends. */
/* updated on the cli_stats_msg from sec-mod.
* Holds the number of entries in secmod list of users */
unsigned secmod_client_entries;
unsigned tlsdb_entries;
unsigned int secmod_client_entries;
unsigned int tlsdb_entries;
uint32_t avg_auth_time; /* in seconds */
uint32_t max_auth_time; /* in seconds */
@@ -285,13 +288,13 @@ typedef struct main_server_st {
struct main_stats_st stats;
void * auth_extra;
void *auth_extra;
/* This one is on worker pool */
struct worker_st *ws;
unsigned int sec_mod_instance_count;
sec_mod_instance_st * sec_mod_instances;
sec_mod_instance_st *sec_mod_instances;
int top_fd;
int ctl_fd;
@@ -310,52 +313,55 @@ typedef struct main_server_st {
struct rlimit fd_limits_default_set;
#endif
struct if_address_st * if_addresses;
struct if_address_st *if_addresses;
unsigned int if_addresses_count;
} main_server_st;
void clear_lists(main_server_st *s);
int handle_worker_commands(main_server_st *s, struct proc_st* cur);
int handle_sec_mod_commands(sec_mod_instance_st * sec_mod_instances);
int handle_worker_commands(main_server_st *s, struct proc_st *cur);
int handle_sec_mod_commands(sec_mod_instance_st *sec_mod_instances);
int user_connected(main_server_st *s, struct proc_st* cur);
void user_hostname_update(main_server_st *s, struct proc_st* cur);
void user_disconnected(main_server_st *s, struct proc_st* cur);
int user_connected(main_server_st *s, struct proc_st *cur);
void user_hostname_update(main_server_st *s, struct proc_st *cur);
void user_disconnected(main_server_st *s, struct proc_st *cur);
int send_udp_fd(main_server_st* s, struct proc_st * proc, int fd);
int send_udp_fd(main_server_st *s, struct proc_st *proc, int fd);
int session_open(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc, const uint8_t *cookie, unsigned cookie_size);
int session_close(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc);
int session_open(sec_mod_instance_st *sec_mod_instance, struct proc_st *proc,
const uint8_t *cookie, unsigned int cookie_size);
int session_close(sec_mod_instance_st *sec_mod_instance, struct proc_st *proc);
int open_tun(main_server_st* s, struct proc_st* proc);
void close_tun(main_server_st* s, struct proc_st* proc);
void reset_tun(struct proc_st* proc);
int set_tun_mtu(main_server_st* s, struct proc_st * proc, unsigned mtu);
int open_tun(main_server_st *s, struct proc_st *proc);
void close_tun(main_server_st *s, struct proc_st *proc);
void reset_tun(struct proc_st *proc);
int set_tun_mtu(main_server_st *s, struct proc_st *proc, unsigned int mtu);
int send_cookie_auth_reply(main_server_st* s, struct proc_st* proc,
AUTHREP r);
int send_cookie_auth_reply(main_server_st *s, struct proc_st *proc, AUTHREP r);
int handle_auth_cookie_req(sec_mod_instance_st * sec_mod_instance, struct proc_st* proc,
const AuthCookieRequestMsg * req);
int handle_auth_cookie_req(sec_mod_instance_st *sec_mod_instance,
struct proc_st *proc,
const AuthCookieRequestMsg *req);
int check_multiple_users(main_server_st *s, struct proc_st* proc);
int handle_script_exit(main_server_st *s, struct proc_st* proc, int code);
int check_multiple_users(main_server_st *s, struct proc_st *proc);
int handle_script_exit(main_server_st *s, struct proc_st *proc, int code);
void run_sec_mod(sec_mod_instance_st * sec_mod_instance, unsigned int instance_index);
void run_sec_mod(sec_mod_instance_st *sec_mod_instance,
unsigned int instance_index);
struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd,
struct sockaddr_storage *remote_addr, socklen_t remote_addr_len,
struct sockaddr_storage *our_addr, socklen_t our_addr_len,
uint8_t *sid, size_t sid_size);
struct proc_st *new_proc(main_server_st *s, pid_t pid, int cmd_fd,
struct sockaddr_storage *remote_addr,
socklen_t remote_addr_len,
struct sockaddr_storage *our_addr,
socklen_t our_addr_len, uint8_t *sid, size_t sid_size);
/* kill the pid */
#define RPROC_KILL 1
/* we are on shutdown, don't wait for anything */
#define RPROC_QUIT (1<<1)
#define RPROC_QUIT (1 << 1)
void remove_proc(main_server_st* s, struct proc_st *proc, unsigned flags);
void proc_to_zombie(main_server_st* s, struct proc_st *proc);
void remove_proc(main_server_st *s, struct proc_st *proc, unsigned int flags);
void proc_to_zombie(main_server_st *s, struct proc_st *proc);
inline static void disconnect_proc(main_server_st *s, proc_st *proc)
{
@@ -365,34 +371,39 @@ inline static void disconnect_proc(main_server_st *s, proc_st *proc)
/* if it has a PID, send a signal so that we cleanup
* and sec-mod gets stats orderly */
if (proc->pid != -1 && proc->pid != 0) {
kill(proc->pid, SIGTERM);
kill(proc->pid, SIGTERM);
} else {
remove_proc(s, proc, RPROC_KILL);
}
}
void put_into_cgroup(main_server_st * s, const char* cgroup, pid_t pid);
void put_into_cgroup(main_server_st *s, const char *cgroup, pid_t pid);
inline static
int send_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t cmd,
const void* msg, pack_size_func get_size, pack_func pack)
inline static int send_msg_to_worker(main_server_st *s, struct proc_st *proc,
uint8_t cmd, const void *msg,
pack_size_func get_size, pack_func pack)
{
mslog(s, proc, LOG_DEBUG, "sending message '%s' to worker", cmd_request_to_str(cmd));
mslog(s, proc, LOG_DEBUG, "sending message '%s' to worker",
cmd_request_to_str(cmd));
return send_msg(proc, proc->fd, cmd, msg, get_size, pack);
}
inline static
int send_socket_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t cmd,
int socketfd, const void* msg, pack_size_func get_size, pack_func pack)
inline static int send_socket_msg_to_worker(main_server_st *s,
struct proc_st *proc, uint8_t cmd,
int socketfd, const void *msg,
pack_size_func get_size,
pack_func pack)
{
mslog(s, proc, LOG_DEBUG, "sending (socket) message %u to worker", (unsigned)cmd);
return send_socket_msg(proc, proc->fd, cmd, socketfd, msg, get_size, pack);
mslog(s, proc, LOG_DEBUG, "sending (socket) message %u to worker",
(unsigned int)cmd);
return send_socket_msg(proc, proc->fd, cmd, socketfd, msg, get_size,
pack);
}
int secmod_reload(sec_mod_instance_st * sec_mod_instance);
int secmod_reload(sec_mod_instance_st *sec_mod_instance);
const char *secmod_socket_file_name(struct perm_cfg_st *perm_config);
void restore_secmod_socket_file_name(const char * save_path);
void restore_secmod_socket_file_name(const char *save_path);
void clear_vhosts(struct list_head *head);
void request_reload(int signo);

View File

@@ -15,7 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#if defined(LINUX_NAMESPACES)
@@ -45,7 +44,8 @@ static int init_default_namespace(void)
int fd;
pid = getpid();
if (snprintf(netns_path, sizeof(netns_path), "/proc/%d/ns/net", pid) < 0)
if (snprintf(netns_path, sizeof(netns_path), "/proc/%d/ns/net", pid) <
0)
return -1;
fd = open(netns_path, O_RDONLY | O_CLOEXEC);
@@ -64,7 +64,8 @@ static int init_listen_namespace(const char *ns_name)
int error;
int fd;
if (snprintf(netns_path, sizeof(netns_path), "/var/run/netns/%s", ns_name) < 0)
if (snprintf(netns_path, sizeof(netns_path), "/var/run/netns/%s",
ns_name) < 0)
return -1;
fd = open(netns_path, O_RDONLY | O_CLOEXEC);
@@ -101,16 +102,19 @@ int close_namespaces(struct netns_fds *netns)
}
/* opens a socket in the namespace described by <nsfd> */
int socket_netns(const struct netns_fds *fds, int domain, int type, int protocol)
int socket_netns(const struct netns_fds *fds, int domain, int type,
int protocol)
{
int sock;
if (fds->default_fd >= 0 && fds->listen_fd && setns(fds->listen_fd, CLONE_NEWNET) == -1)
if (fds->default_fd >= 0 && fds->listen_fd &&
setns(fds->listen_fd, CLONE_NEWNET) == -1)
return -1;
sock = socket(domain, type, protocol);
if (fds->default_fd >= 0 && fds->listen_fd && setns(fds->default_fd, CLONE_NEWNET) == -1) {
if (fds->default_fd >= 0 && fds->listen_fd &&
setns(fds->default_fd, CLONE_NEWNET) == -1) {
if (sock >= 0)
close(sock);
return -1;

View File

@@ -16,7 +16,7 @@
*/
#ifndef OC_NAMESPACE_H
# define OC_NAMESPACE_H
#define OC_NAMESPACE_H
#include <config.h>
@@ -27,7 +27,7 @@ struct netns_fds {
#if defined(LINUX_NAMESPACES)
int socket_netns(const struct netns_fds*, int domain, int type, int protocol);
int socket_netns(const struct netns_fds *, int domain, int type, int protocol);
int open_namespaces(struct netns_fds *netns, struct perm_cfg_st *config);
int close_namespaces(struct netns_fds *netns);
@@ -36,10 +36,11 @@ int close_namespaces(struct netns_fds *netns);
#define open_namespaces(netns, config) (-1)
#define close_namespaces(netns) (-1)
static inline int socket_netns(__attribute__((unused)) const struct netns_fds* fds,
static inline int socket_netns(__attribute__((unused))
const struct netns_fds *fds,
int domain, int type, int protocol)
{
return socket(domain, type, protocol);
return socket(domain, type, protocol);
}
#endif /* __linux__ */

View File

@@ -26,52 +26,57 @@
#include <occtl/occtl.h>
typedef struct uid_entries_st {
char* user;
unsigned user_size;
char *user;
unsigned int user_size;
char id[8];
unsigned id_size;
unsigned int id_size;
} uid_entries_st;
static uid_entries_st *entries = NULL;
static unsigned entries_size = 0;
static unsigned max_entries_size = 0;
static uid_entries_st *entries;
static unsigned int entries_size;
static unsigned int max_entries_size;
void entries_clear(void)
{
unsigned i;
unsigned int i;
for (i=0;i<entries_size;i++) {
for (i = 0; i < entries_size; i++) {
talloc_free(entries[i].user);
entries[i].user = 0;
}
entries_size = 0;
}
void entries_add(void *pool, const char* user, unsigned user_size, unsigned id)
void entries_add(void *pool, const char *user, unsigned int user_size,
unsigned int id)
{
if (entries_size+1 > max_entries_size) {
if (entries_size + 1 > max_entries_size) {
max_entries_size += 128;
entries = talloc_realloc_size(pool, entries, sizeof(uid_entries_st)*max_entries_size);
entries = talloc_realloc_size(pool, entries,
sizeof(uid_entries_st) *
max_entries_size);
}
entries[entries_size].user = talloc_strdup(pool, user);
entries[entries_size].user_size = user_size;
entries[entries_size].id_size =
snprintf(entries[entries_size].id, sizeof(entries[entries_size].id), "%u", id);
snprintf(entries[entries_size].id,
sizeof(entries[entries_size].id), "%u", id);
entries_size++;
}
char* search_for_user(unsigned idx, const char* match, int match_size)
char *search_for_user(unsigned int idx, const char *match, int match_size)
{
unsigned i;
unsigned int i;
if (idx >= entries_size)
return NULL;
for (i=idx;i<entries_size;i++) {
for (i = idx; i < entries_size; i++) {
if (match_size <= entries[i].user_size) {
if (strncasecmp(match, entries[i].user, match_size) == 0)
if (strncasecmp(match, entries[i].user, match_size) ==
0)
return strdup(entries[i].user);
}
}
@@ -79,16 +84,17 @@ unsigned i;
return NULL;
}
char* search_for_id(unsigned idx, const char* match, int match_size)
char *search_for_id(unsigned int idx, const char *match, int match_size)
{
unsigned i;
unsigned int i;
if (idx >= entries_size)
return NULL;
for (i=idx;i<entries_size;i++) {
for (i = idx; i < entries_size; i++) {
if (match_size <= entries[i].id_size) {
if (strncasecmp(match, entries[i].id, match_size) == 0) {
if (strncasecmp(match, entries[i].id, match_size) ==
0) {
return strdup(entries[i].id);
}
}

View File

@@ -1,5 +1,5 @@
#ifndef CTL_H
# define CTL_H
#define CTL_H
#define OCCTL_UNIX_SOCKET "/var/run/occtl.socket"

View File

@@ -30,23 +30,23 @@
#ifdef HAVE_GEOIP
# include <GeoIP.h>
# include <GeoIPCity.h>
#include <GeoIP.h>
#include <GeoIPCity.h>
extern void _GeoIP_setup_dbfilename(void);
# define p_GeoIP_setup_dbfilename _GeoIP_setup_dbfilename
# define pGeoIP_open_type GeoIP_open_type
# define pGeoIP_country_name_by_id GeoIP_country_name_by_id
# define pGeoIP_delete GeoIP_delete
# define pGeoIP_record_by_ipnum GeoIP_record_by_ipnum
# define pGeoIP_id_by_ipnum GeoIP_id_by_ipnum
# define pGeoIP_id_by_ipnum_v6 GeoIP_id_by_ipnum_v6
# define pGeoIP_record_by_ipnum_v6 GeoIP_record_by_ipnum_v6
# define pGeoIP_code_by_id GeoIP_code_by_id
#define p_GeoIP_setup_dbfilename _GeoIP_setup_dbfilename
#define pGeoIP_open_type GeoIP_open_type
#define pGeoIP_country_name_by_id GeoIP_country_name_by_id
#define pGeoIP_delete GeoIP_delete
#define pGeoIP_record_by_ipnum GeoIP_record_by_ipnum
#define pGeoIP_id_by_ipnum GeoIP_id_by_ipnum
#define pGeoIP_id_by_ipnum_v6 GeoIP_id_by_ipnum_v6
#define pGeoIP_record_by_ipnum_v6 GeoIP_record_by_ipnum_v6
#define pGeoIP_code_by_id GeoIP_code_by_id
int geo_setup(void)
{
static unsigned init = 0;
static unsigned int init;
if (init == 0) {
p_GeoIP_setup_dbfilename();
@@ -56,7 +56,8 @@ int geo_setup(void)
return 0;
}
void geo_ipv4_lookup(struct in_addr ip, char **country, char **city, char **coord)
void geo_ipv4_lookup(struct in_addr ip, char **country, char **city,
char **coord)
{
GeoIP *gi;
GeoIPRecord *gir;
@@ -68,7 +69,8 @@ void geo_ipv4_lookup(struct in_addr ip, char **country, char **city, char **coor
ip.s_addr = ntohl(ip.s_addr);
gi = pGeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD | GEOIP_SILENCE);
gi = pGeoIP_open_type(GEOIP_COUNTRY_EDITION,
GEOIP_STANDARD | GEOIP_SILENCE);
if (gi != NULL) {
gi->charset = GEOIP_CHARSET_UTF8;
@@ -83,7 +85,8 @@ void geo_ipv4_lookup(struct in_addr ip, char **country, char **city, char **coor
pGeoIP_delete(gi);
}
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV1, GEOIP_STANDARD | GEOIP_SILENCE);
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV1,
GEOIP_STANDARD | GEOIP_SILENCE);
if (gi != NULL) {
gi->charset = GEOIP_CHARSET_UTF8;
@@ -93,12 +96,14 @@ void geo_ipv4_lookup(struct in_addr ip, char **country, char **city, char **coor
*city = strdup(gir->city);
if (gir && gir->longitude != 0 && gir->longitude != 0)
if (asprintf(coord, "%f,%f", gir->latitude, gir->longitude) < 0)
if (asprintf(coord, "%f,%f", gir->latitude,
gir->longitude) < 0)
*coord = NULL;
pGeoIP_delete(gi);
} else {
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV0, GEOIP_STANDARD | GEOIP_SILENCE);
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV0,
GEOIP_STANDARD | GEOIP_SILENCE);
if (gi != NULL) {
gi->charset = GEOIP_CHARSET_UTF8;
@@ -108,7 +113,8 @@ void geo_ipv4_lookup(struct in_addr ip, char **country, char **city, char **coor
*city = strdup(gir->city);
if (gir && gir->longitude != 0 && gir->longitude != 0)
if (asprintf(coord, "%f,%f", gir->latitude, gir->longitude) < 0)
if (asprintf(coord, "%f,%f", gir->latitude,
gir->longitude) < 0)
*coord = NULL;
pGeoIP_delete(gi);
@@ -116,7 +122,8 @@ void geo_ipv4_lookup(struct in_addr ip, char **country, char **city, char **coor
}
}
void geo_ipv6_lookup(struct in6_addr *ip, char **country, char **city, char **coord)
void geo_ipv6_lookup(struct in6_addr *ip, char **country, char **city,
char **coord)
{
GeoIP *gi;
GeoIPRecord *gir;
@@ -126,7 +133,8 @@ void geo_ipv6_lookup(struct in6_addr *ip, char **country, char **city, char **co
if (geo_setup() != 0)
return;
gi = pGeoIP_open_type(GEOIP_COUNTRY_EDITION_V6, GEOIP_STANDARD | GEOIP_SILENCE);
gi = pGeoIP_open_type(GEOIP_COUNTRY_EDITION_V6,
GEOIP_STANDARD | GEOIP_SILENCE);
if (gi != NULL) {
gi->charset = GEOIP_CHARSET_UTF8;
@@ -141,7 +149,8 @@ void geo_ipv6_lookup(struct in6_addr *ip, char **country, char **city, char **co
pGeoIP_delete(gi);
}
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV1_V6, GEOIP_STANDARD | GEOIP_SILENCE);
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV1_V6,
GEOIP_STANDARD | GEOIP_SILENCE);
if (gi != NULL) {
gi->charset = GEOIP_CHARSET_UTF8;
@@ -151,12 +160,14 @@ void geo_ipv6_lookup(struct in6_addr *ip, char **country, char **city, char **co
*city = strdup(gir->city);
if (gir && gir->longitude != 0 && gir->longitude != 0)
if (asprintf(coord, "%f,%f", gir->latitude, gir->longitude) < 0)
if (asprintf(coord, "%f,%f", gir->latitude,
gir->longitude) < 0)
*coord = NULL;
pGeoIP_delete(gi);
} else {
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV0_V6, GEOIP_STANDARD | GEOIP_SILENCE);
gi = pGeoIP_open_type(GEOIP_CITY_EDITION_REV0_V6,
GEOIP_STANDARD | GEOIP_SILENCE);
if (gi != NULL) {
gi->charset = GEOIP_CHARSET_UTF8;
@@ -166,7 +177,8 @@ void geo_ipv6_lookup(struct in6_addr *ip, char **country, char **city, char **co
*city = strdup(gir->city);
if (gir && gir->longitude != 0 && gir->longitude != 0)
if (asprintf(coord, "%f,%f", gir->latitude, gir->longitude) < 0)
if (asprintf(coord, "%f,%f", gir->latitude,
gir->longitude) < 0)
*coord = NULL;
pGeoIP_delete(gi);
@@ -174,7 +186,7 @@ void geo_ipv6_lookup(struct in6_addr *ip, char **country, char **city, char **co
}
}
char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
char *geo_lookup(const char *ip, char *buf, unsigned int buf_size)
{
char *country = NULL;
char *city = NULL;
@@ -209,7 +221,7 @@ char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
return buf;
fail:
fail:
free(country);
free(city);
free(coord);
@@ -218,7 +230,7 @@ char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
}
#else
char * geo_lookup(const char *ip, char *buf, unsigned buf_size)
char *geo_lookup(const char *ip, char *buf, unsigned int buf_size)
{
return "unknown";
}

View File

@@ -18,8 +18,8 @@
*/
#ifndef GEOIP_H
# define GEOIP_H
#define GEOIP_H
char * geo_lookup(const char *ip, char *buf, unsigned buf_size);
char *geo_lookup(const char *ip, char *buf, unsigned int buf_size);
#endif

View File

@@ -28,45 +28,49 @@
typedef struct ip_entries_st {
char ip[MAX_IP_STR];
unsigned ip_size;
unsigned int ip_size;
} ip_entries_st;
static ip_entries_st *ip_entries = NULL;
static unsigned ip_entries_size = 0;
static unsigned max_ip_entries_size = 0;
static ip_entries_st *ip_entries;
static unsigned int ip_entries_size;
static unsigned int max_ip_entries_size;
void ip_entries_clear(void)
{
unsigned i;
unsigned int i;
for (i=0;i<ip_entries_size;i++) {
for (i = 0; i < ip_entries_size; i++) {
ip_entries[i].ip_size = 0;
}
ip_entries_size = 0;
}
void ip_entries_add(void *pool, const char* ip, unsigned ip_size)
void ip_entries_add(void *pool, const char *ip, unsigned int ip_size)
{
if (ip_entries_size+1 > max_ip_entries_size) {
if (ip_entries_size + 1 > max_ip_entries_size) {
max_ip_entries_size += 128;
ip_entries = talloc_realloc_size(pool, ip_entries, sizeof(ip_entries_st)*max_ip_entries_size);
ip_entries = talloc_realloc_size(pool, ip_entries,
sizeof(ip_entries_st) *
max_ip_entries_size);
}
strlcpy(ip_entries[ip_entries_size].ip, ip, sizeof(ip_entries[ip_entries_size].ip));
strlcpy(ip_entries[ip_entries_size].ip, ip,
sizeof(ip_entries[ip_entries_size].ip));
ip_entries[ip_entries_size].ip_size = ip_size;
ip_entries_size++;
}
char* search_for_ip(unsigned idx, const char* match, int match_size)
char *search_for_ip(unsigned int idx, const char *match, int match_size)
{
unsigned i;
unsigned int i;
if (idx >= ip_entries_size)
return NULL;
for (i=idx;i<ip_entries_size;i++) {
for (i = idx; i < ip_entries_size; i++) {
if (match_size <= ip_entries[i].ip_size) {
if (strncasecmp(match, ip_entries[i].ip, match_size) == 0)
if (strncasecmp(match, ip_entries[i].ip, match_size) ==
0)
return strdup(ip_entries[i].ip);
}
}

View File

@@ -26,21 +26,22 @@
/* Escapes @val and stores it in tmp. A fixed string is returned
* in case tmp is too small.
*/
char *json_escape_val(char *tmp, unsigned tmp_size, const char *val)
char *json_escape_val(char *tmp, unsigned int tmp_size, const char *val)
{
unsigned val_len = strlen(val);
unsigned i, j;
unsigned int val_len = strlen(val);
unsigned int i, j;
for (i=j=0;i<val_len;i++) {
for (i = j = 0; i < val_len; i++) {
if (j + 7 >= tmp_size)
return "(invalid)";
if (val[i] == '"' || val[i] == '\\') {
snprintf(&tmp[j], 3, "\\%c", val[i]);
j+=2;
snprintf(&tmp[j], 3, "\\%c", val[i]);
j += 2;
} else if (val[i] <= 0x1F) {
snprintf(&tmp[j], 7, "\\u00%02x", (unsigned)val[i]);
j+=6;
} else tmp[j++] = val[i];
snprintf(&tmp[j], 7, "\\u00%02x", (unsigned int)val[i]);
j += 6;
} else
tmp[j++] = val[i];
}
tmp[j] = 0;

View File

@@ -20,7 +20,7 @@
*/
#ifndef JSON_H
# define JSON_H
char *json_escape_val(char *tmp, unsigned tmp_size, const char *val);
#define JSON_H
char *json_escape_val(char *tmp, unsigned int tmp_size, const char *val);
#endif

View File

@@ -38,21 +38,21 @@
#define MAXMINDDB_LOCATION_CITY "/usr/share/GeoIP/GeoLite2-City.mmdb"
#endif
#define pMMDB_close MMDB_close
#define pMMDB_get_value MMDB_get_value
#define pMMDB_close MMDB_close
#define pMMDB_get_value MMDB_get_value
#define pMMDB_lookup_string MMDB_lookup_string
#define pMMDB_open MMDB_open
#define pMMDB_open MMDB_open
void process_result_from_mmdb_lookup(MMDB_entry_data_s * entry_data, int status,
void process_result_from_mmdb_lookup(MMDB_entry_data_s *entry_data, int status,
char **output)
{
if (MMDB_SUCCESS == status) {
if (status == MMDB_SUCCESS) {
if (entry_data->has_data) {
if (entry_data->type == MMDB_DATA_TYPE_UTF8_STRING) {
*output =
(char *)calloc(entry_data->data_size + 1,
sizeof(char));
if (NULL != *output) {
*output = (char *)calloc(entry_data->data_size +
1,
sizeof(char));
if (*output != NULL) {
memcpy(*output, entry_data->utf8_string,
entry_data->data_size);
} else {
@@ -66,7 +66,7 @@ void process_result_from_mmdb_lookup(MMDB_entry_data_s * entry_data, int status,
/* Else fail silently */
}
char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
char *geo_lookup(const char *ip, char *buf, unsigned int buf_size)
{
MMDB_s mmdb;
MMDB_entry_data_s entry_data;
@@ -74,33 +74,30 @@ char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
double latitude, longitude;
char *country = NULL, *ccode = NULL;
char *coord = NULL;
unsigned found = 0;
unsigned int found = 0;
/* Open the system maxmind database with countries */
status = pMMDB_open(MAXMINDDB_LOCATION_COUNTRY, MMDB_MODE_MMAP, &mmdb);
if (MMDB_SUCCESS == status) {
if (status == MMDB_SUCCESS) {
/* Lookup IP address in the database */
MMDB_lookup_result_s result =
pMMDB_lookup_string(&mmdb, ip, &gai_error, &mmdb_error);
if (MMDB_SUCCESS == mmdb_error) {
pMMDB_lookup_string(&mmdb, ip, &gai_error, &mmdb_error);
if (mmdb_error == MMDB_SUCCESS) {
/* If the lookup was successful and an entry was found */
if (result.found_entry) {
memset(&entry_data, 0,
sizeof(MMDB_entry_data_s));
/* Travel the path in the tree like structure of the MMDB and store the value if found */
status =
pMMDB_get_value(&result.entry, &entry_data,
"country", "names", "en",
NULL);
process_result_from_mmdb_lookup(&entry_data,
status,
&country);
status = pMMDB_get_value(&result.entry,
&entry_data, "country",
"names", "en", NULL);
process_result_from_mmdb_lookup(
&entry_data, status, &country);
memset(&entry_data, 0,
sizeof(MMDB_entry_data_s));
status =
pMMDB_get_value(&result.entry, &entry_data,
"country", "iso_code",
NULL);
status = pMMDB_get_value(&result.entry,
&entry_data, "country",
"iso_code", NULL);
process_result_from_mmdb_lookup(&entry_data,
status, &ccode);
}
@@ -112,11 +109,11 @@ char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
/* Open the system maxmind database with cities - which actually does not contain names of the cities */
status = pMMDB_open(MAXMINDDB_LOCATION_CITY, MMDB_MODE_MMAP, &mmdb);
if (MMDB_SUCCESS == status) {
if (status == MMDB_SUCCESS) {
/* Lookup IP address in the database */
MMDB_lookup_result_s result =
pMMDB_lookup_string(&mmdb, ip, &gai_error, &mmdb_error);
if (MMDB_SUCCESS == mmdb_error) {
pMMDB_lookup_string(&mmdb, ip, &gai_error, &mmdb_error);
if (mmdb_error == MMDB_SUCCESS) {
/* If the lookup was successful and an entry was found */
if (result.found_entry) {
memset(&entry_data, 0,
@@ -124,32 +121,32 @@ char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
// NOTE: Information about the city is not available in the free database, so there is not way
// for me to implement this functionality right now, but it should be easy to add for anyone with
// access to the paid databases.
status =
pMMDB_get_value(&result.entry, &entry_data,
"location", "latitude",
NULL);
if (MMDB_SUCCESS == status) {
status = pMMDB_get_value(&result.entry,
&entry_data,
"location", "latitude",
NULL);
if (status == MMDB_SUCCESS) {
if (entry_data.has_data) {
if (entry_data.type ==
MMDB_DATA_TYPE_DOUBLE) {
latitude =
entry_data.
double_value;
entry_data
.double_value;
++coordinates;
}
}
}
status =
pMMDB_get_value(&result.entry, &entry_data,
"location", "longitude",
NULL);
if (MMDB_SUCCESS == status) {
status = pMMDB_get_value(&result.entry,
&entry_data,
"location",
"longitude", NULL);
if (status == MMDB_SUCCESS) {
if (entry_data.has_data) {
if (entry_data.type ==
MMDB_DATA_TYPE_DOUBLE) {
longitude =
entry_data.
double_value;
entry_data
.double_value;
++coordinates;
}
}
@@ -161,7 +158,6 @@ char *geo_lookup(const char *ip, char *buf, unsigned buf_size)
}
}
}
}
pMMDB_close(&mmdb);
}

View File

@@ -33,12 +33,12 @@
#include <netlink/route/link.h>
#include <inttypes.h>
static struct nl_sock *sock = NULL;
static int nl_failed = 0;
static struct nl_sock *sock;
static int nl_failed;
static int open_netlink(void)
{
int err;
int err;
if (sock != NULL)
return 0;
@@ -52,7 +52,8 @@ int err;
goto error;
}
if ((err = nl_connect(sock, NETLINK_ROUTE)) < 0) {
err = nl_connect(sock, NETLINK_ROUTE);
if (err < 0) {
fprintf(stderr, "nl: error in nl_connect (%d)", err);
goto error;
}
@@ -68,8 +69,8 @@ error:
return -1;
}
static void
value2speed(unsigned long bytes, time_t time, char* output, unsigned output_size)
static void value2speed(unsigned long bytes, time_t time, char *output,
unsigned int output_size)
{
unsigned long speed;
@@ -80,7 +81,8 @@ value2speed(unsigned long bytes, time_t time, char* output, unsigned output_size
bytes2human(speed, output, output_size, "/s");
}
void print_iface_stats(const char *iface, time_t since, FILE * out, cmd_params_st *params, unsigned have_more)
void print_iface_stats(const char *iface, time_t since, FILE *out,
cmd_params_st *params, unsigned int have_more)
{
uint64_t tx, rx;
char buf1[32], buf2[32];
@@ -106,21 +108,30 @@ void print_iface_stats(const char *iface, time_t since, FILE * out, cmd_params_s
bytes2human(rx, buf1, sizeof(buf1), NULL);
bytes2human(tx, buf2, sizeof(buf2), NULL);
if (HAVE_JSON(params)) {
fprintf(out, " \"RX\": \"%"PRIu64"\",\n \"TX\": \"%"PRIu64"\",\n", rx, tx);
fprintf(out, " \"_RX\": \"%s\",\n \"_TX\": \"%s\",\n", buf1, buf2);
fprintf(out,
" \"RX\": \"%" PRIu64 "\",\n \"TX\": \"%" PRIu64
"\",\n",
rx, tx);
fprintf(out, " \"_RX\": \"%s\",\n \"_TX\": \"%s\",\n",
buf1, buf2);
} else
fprintf(out, "\tRX: %"PRIu64" (%s) TX: %"PRIu64" (%s)\n", rx, buf1, tx, buf2);
fprintf(out, "\tRX: %" PRIu64 " (%s) TX: %" PRIu64 " (%s)\n",
rx, buf1, tx, buf2);
value2speed(rx, diff, buf1, sizeof(buf1));
value2speed(tx, diff, buf2, sizeof(buf2));
if (HAVE_JSON(params))
fprintf(out, " \"Average RX\": \"%s\",\n \"Average TX\": \"%s\"%s\n", buf1, buf2, have_more?",":"");
fprintf(out,
" \"Average RX\": \"%s\",\n \"Average TX\": \"%s\"%s\n",
buf1, buf2, have_more ? "," : "");
else
fprintf(out, "\tAverage bandwidth RX: %s TX: %s\n", buf1, buf2);
fprintf(out, "\tAverage bandwidth RX: %s TX: %s\n", buf1,
buf2);
}
#else
void print_iface_stats(const char *iface, time_t since, FILE * out, cmd_params_st *params, unsigned have_more)
void print_iface_stats(const char *iface, time_t since, FILE *out,
cmd_params_st *params, unsigned int have_more)
{
}
#endif

View File

@@ -30,15 +30,18 @@
#include <locale.h>
#include <occtl/occtl.h>
int syslog_open = 0;
int syslog_open;
static int handle_reset_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
static int handle_help_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
static int handle_exit_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
static int handle_reset_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
static int handle_help_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
static int handle_exit_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
typedef struct {
char *name;
unsigned name_size;
unsigned int name_size;
char *arg;
cmd_func func;
char *doc;
@@ -47,15 +50,15 @@ typedef struct {
} commands_st;
#define ENTRY(name, arg, func, doc, show, npc) \
{name, sizeof(name)-1, arg, func, doc, show, npc}
{ name, sizeof(name) - 1, arg, func, doc, show, npc }
static const commands_st commands[] = {
ENTRY("disconnect user", "[NAME]", handle_disconnect_user_cmd,
"Disconnect the specified user", 1, 1),
ENTRY("disconnect id", "[ID]", handle_disconnect_id_cmd,
"Disconnect the specified ID", 1, 1),
ENTRY("unban ip", "[IP]", handle_unban_ip_cmd,
"Unban the specified IP", 1, 1),
ENTRY("unban ip", "[IP]", handle_unban_ip_cmd, "Unban the specified IP",
1, 1),
ENTRY("reload", NULL, handle_reload_cmd,
"Reloads the server configuration", 1, 1),
ENTRY("show status", NULL, handle_status_cmd,
@@ -80,8 +83,7 @@ static const commands_st commands[] = {
"Prints information on the specified ID", 1, 1),
ENTRY("show events", NULL, handle_events_cmd,
"Provides information about connecting users", 1, 1),
ENTRY("stop", "now", handle_stop_cmd,
"Terminates the server", 1, 1),
ENTRY("stop", "now", handle_stop_cmd, "Terminates the server", 1, 1),
ENTRY("reset", NULL, handle_reset_cmd, "Resets the screen and terminal",
0, 0),
ENTRY("help", "or ?", handle_help_cmd, "Prints this help", 0, 0),
@@ -93,10 +95,10 @@ static const commands_st commands[] = {
"Alias for show sessions all", -1, 1),
ENTRY("show cookies valid", NULL, handle_list_valid_sessions_cmd,
"Alias for show sessions valid", -1, 1),
{NULL, 0, NULL, NULL}
{ NULL, 0, NULL, NULL }
};
static void print_commands(unsigned interactive)
static void print_commands(unsigned int interactive)
{
unsigned int i;
@@ -121,10 +123,10 @@ static void print_commands(unsigned interactive)
}
#ifndef HAVE_ORIG_READLINE
# define whitespace(x) c_isspace(x)
#define whitespace(x) c_isspace(x)
#endif
unsigned need_help(const char *arg)
unsigned int need_help(const char *arg)
{
while (whitespace(*arg))
arg++;
@@ -135,11 +137,11 @@ unsigned need_help(const char *arg)
return 0;
}
unsigned check_cmd_help(const char *line)
unsigned int check_cmd_help(const char *line)
{
unsigned int i;
unsigned len = (line!=NULL)?strlen(line):0;
unsigned status = 0, tlen;
unsigned len = (line != NULL) ? strlen(line) : 0;
unsigned int status = 0, tlen;
while (len > 0 && (line[len - 1] == '?' || whitespace(line[len - 1])))
len--;
@@ -167,8 +169,7 @@ unsigned check_cmd_help(const char *line)
return status;
}
static
void usage(void)
static void usage(void)
{
printf("occtl: [OPTIONS...] {COMMAND}\n\n");
printf(" -s --socket-file Specify the server's occtl socket file\n");
@@ -181,18 +182,16 @@ void usage(void)
printf("\n");
}
static
void version(void)
static void version(void)
{
fprintf(stderr,
"OpenConnect server control (occtl) version %s\n", VERSION);
fprintf(stderr, "OpenConnect server control (occtl) version %s\n",
VERSION);
fprintf(stderr, "Copyright (C) 2014-2017 Red Hat and others.\n");
fprintf(stderr,
"ocserv comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
fprintf(stderr,
"and you are welcome to redistribute it under the conditions of the\n");
fprintf(stderr,
"GNU General Public License version 2.\n");
fprintf(stderr, "GNU General Public License version 2.\n");
fprintf(stderr, "\nFor help type ? or 'help'\n");
fprintf(stderr,
"==================================================================\n");
@@ -217,47 +216,50 @@ static char *rl_gets(char *line_read)
return line_read;
}
void
bytes2human(unsigned long bytes, char* output, unsigned output_size, const char* suffix)
void bytes2human(unsigned long bytes, char *output, unsigned int output_size,
const char *suffix)
{
double data;
double data;
if (suffix == NULL)
suffix = "";
if (bytes > 1000 && bytes < 1000 * 1000) {
data = ((double) bytes) / 1000;
data = ((double)bytes) / 1000;
snprintf(output, output_size, "%.1f kB%s", data, suffix);
} else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000) {
data = ((double) bytes) / (1000 * 1000);
data = ((double)bytes) / (1000 * 1000);
snprintf(output, output_size, "%.1f MB%s", data, suffix);
} else if (bytes >= 1000 * 1000 * 1000) {
data = ((double) bytes) / (1000 * 1000 * 1000);
data = ((double)bytes) / (1000 * 1000 * 1000);
snprintf(output, output_size, "%.1f GB%s", data, suffix);
} else {
snprintf(output, output_size, "%lu bytes%s", bytes, suffix);
}
}
void
time2human(uint64_t microseconds, char* output, unsigned output_size)
void time2human(uint64_t microseconds, char *output, unsigned int output_size)
{
if (microseconds < 1000) {
snprintf(output, output_size, "<1ms");
} else if (microseconds < 1000000) {
snprintf(output, output_size, "%" PRIu64 "ms", microseconds / 1000);
snprintf(output, output_size, "%" PRIu64 "ms",
microseconds / 1000);
} else {
snprintf(output, output_size, "%" PRIu64 "s", microseconds / 1000000);
snprintf(output, output_size, "%" PRIu64 "s",
microseconds / 1000000);
}
}
static int handle_help_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params)
static int handle_help_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params)
{
print_commands(1);
return 0;
}
static int handle_reset_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params)
static int handle_reset_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params)
{
rl_reset_terminal(NULL);
#ifdef HAVE_ORIG_READLINE
@@ -267,7 +269,8 @@ static int handle_reset_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *pa
return 0;
}
static int handle_exit_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params)
static int handle_exit_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params)
{
exit(EXIT_SUCCESS);
}
@@ -275,14 +278,13 @@ static int handle_exit_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *par
/* checks whether an input command of type " list users" matches
* the given cmd (e.g., "list users"). If yes it executes func() and returns true.
*/
static
unsigned check_cmd(const char *cmd, const char *input,
CONN_TYPE * conn, int need_preconn, cmd_func func, int *status,
cmd_params_st *params)
static unsigned int check_cmd(const char *cmd, const char *input,
CONN_TYPE *conn, int need_preconn, cmd_func func,
int *status, cmd_params_st *params)
{
char *t, *p;
unsigned len, tlen;
unsigned i, ret = 0;
unsigned int len, tlen;
unsigned int i, ret = 0;
char prev;
while (whitespace(*input))
@@ -310,7 +312,8 @@ unsigned check_cmd(const char *cmd, const char *input,
if (len == 0)
goto cleanup;
if (tlen >= len && strncasecmp(cmd, t, len) == 0 && cmd[len] == 0) { /* match */
if (tlen >= len && strncasecmp(cmd, t, len) == 0 &&
cmd[len] == 0) { /* match */
p = t + len;
while (whitespace(*p))
p++;
@@ -331,7 +334,7 @@ unsigned check_cmd(const char *cmd, const char *input,
conn_posthandle(conn);
}
cleanup:
cleanup:
talloc_free(t);
return ret;
@@ -341,7 +344,8 @@ char *stripwhite(char *string)
{
register char *s, *t;
for (s = string; whitespace(*s); s++) ;
for (s = string; whitespace(*s); s++)
;
if (*s == 0)
return (s);
@@ -354,8 +358,7 @@ char *stripwhite(char *string)
return s;
}
static
int handle_cmd(CONN_TYPE * conn, char *line, cmd_params_st *params)
static int handle_cmd(CONN_TYPE *conn, char *line, cmd_params_st *params)
{
char *cline;
unsigned int i;
@@ -370,17 +373,15 @@ int handle_cmd(CONN_TYPE * conn, char *line, cmd_params_st *params)
if (commands[i].name == NULL)
goto error;
if (check_cmd
(commands[i].name, cline, conn,
commands[i].need_preconn,
commands[i].func,
&status, params) != 0)
if (check_cmd(commands[i].name, cline, conn,
commands[i].need_preconn, commands[i].func,
&status, params) != 0)
break;
}
return status;
error:
error:
if (check_cmd_help(line) == 0) {
fprintf(stderr, "unknown command: %s\n", line);
fprintf(stderr,
@@ -394,9 +395,9 @@ int handle_cmd(CONN_TYPE * conn, char *line, cmd_params_st *params)
*/
static char *merge_args(int argc, char **argv)
{
unsigned size = 0;
unsigned int size = 0;
char *data, *p;
unsigned i, len;
unsigned int i, len;
for (i = 1; i < argc; i++) {
size += strlen(argv[i]) + 1;
@@ -423,12 +424,12 @@ static char *merge_args(int argc, char **argv)
return data;
}
static unsigned int cmd_start = 0;
static unsigned int cmd_start;
static char *command_generator(const char *text, int state)
{
static int list_index, len;
static int entries_idx;
unsigned name_size;
unsigned int name_size;
char *name, *arg;
char *ret;
@@ -450,35 +451,29 @@ static char *command_generator(const char *text, int state)
if (cmd_start > name_size) {
/* check for user or ID options */
if (rl_line_buffer != NULL &&
strncasecmp(rl_line_buffer, name, name_size) == 0
&&
strncasecmp(rl_line_buffer, name, name_size) == 0 &&
/* make sure only one argument is appended */
rl_line_buffer[name_size] != 0 &&
strchr(&rl_line_buffer[name_size + 1],
' ') == NULL) {
strchr(&rl_line_buffer[name_size + 1], ' ') ==
NULL) {
if (arg != NULL) {
ret = NULL;
if (strcmp(arg, "[NAME]") == 0)
ret =
search_for_user(entries_idx,
text, len);
ret = search_for_user(
entries_idx, text, len);
else if (strcmp(arg, "[ID]") == 0)
ret =
search_for_id(entries_idx,
text, len);
ret = search_for_id(entries_idx,
text, len);
else if (strcmp(arg, "[IP]") == 0)
ret =
search_for_ip(entries_idx,
text, len);
ret = search_for_ip(entries_idx,
text, len);
else if (strcmp(arg, "[SID]") == 0)
ret =
search_for_session(entries_idx,
text, len);
ret = search_for_session(
entries_idx, text, len);
if (ret != NULL) {
entries_idx++;
}
list_index--; /* restart at the same cmd */
list_index--; /* restart at the same cmd */
return ret;
}
}
@@ -489,8 +484,8 @@ static char *command_generator(const char *text, int state)
if (cmd_start > 0 && name[cmd_start - 1] != ' ')
continue;
if (rl_line_buffer != NULL
&& strncasecmp(rl_line_buffer, name, cmd_start) != 0)
if (rl_line_buffer != NULL &&
strncasecmp(rl_line_buffer, name, cmd_start) != 0)
continue;
name += cmd_start;
@@ -530,7 +525,8 @@ void initialize_readline(void)
ocsignal(SIGINT, handle_sigint);
}
static int single_cmd(int argc, char **argv, void *pool, const char *file, cmd_params_st *params)
static int single_cmd(int argc, char **argv, void *pool, const char *file,
cmd_params_st *params)
{
CONN_TYPE *conn;
char *line;
@@ -545,7 +541,6 @@ static int single_cmd(int argc, char **argv, void *pool, const char *file, cmd_p
return ret;
}
int main(int argc, char **argv)
{
char *line = NULL;
@@ -573,14 +568,14 @@ int main(int argc, char **argv)
if (argc > 1) {
while (argc > 1 && argv[1][0] == '-') {
if (argv[1][1] == 'j'
|| (argv[1][1] == '-' && argv[1][2] == 'j')) {
if (argv[1][1] == 'j' ||
(argv[1][1] == '-' && argv[1][2] == 'j')) {
params.json = 1;
argv += 1;
argc -= 1;
} else if (argv[1][1] == 'n'
|| (argv[1][1] == '-' && argv[1][2] == 'n')) {
} else if (argv[1][1] == 'n' ||
(argv[1][1] == '-' && argv[1][2] == 'n')) {
params.no_pager = 1;
argv += 1;
@@ -595,12 +590,13 @@ int main(int argc, char **argv)
params.json = 0;
goto interactive;
}
} else if (argv[1][1] == 'v'
|| (argv[1][1] == '-' && argv[1][2] == 'v')) {
} else if (argv[1][1] == 'v' ||
(argv[1][1] == '-' && argv[1][2] == 'v')) {
version();
exit(EXIT_SUCCESS);
} else if (argc > 2 && (argv[1][1] == 's'
|| (argv[1][1] == '-' && argv[1][2] == 's'))) {
} else if (argc > 2 &&
(argv[1][1] == 's' ||
(argv[1][1] == '-' && argv[1][2] == 's'))) {
file = talloc_strdup(gl_pool, argv[2]);
if (argc == 3) {
@@ -622,7 +618,7 @@ int main(int argc, char **argv)
exit(ret);
}
interactive:
interactive:
conn = conn_init(gl_pool, file);
initialize_readline();

View File

@@ -1,15 +1,15 @@
#ifndef OCCTL_H
# define OCCTL_H
#define OCCTL_H
#include <stdlib.h>
#include <time.h>
#include "common.h"
#ifdef HAVE_ORIG_READLINE
# include <readline/readline.h>
# include <readline/history.h>
#include <readline/readline.h>
#include <readline/history.h>
#else
# include <readline.h>
#include <readline.h>
#endif
#define DATE_TIME_FMT "%Y-%m-%d %H:%M"
@@ -19,87 +19,110 @@
#define HAVE_JSON(params) (params && params->json)
typedef struct cmd_params_st {
unsigned json;
unsigned no_pager;
unsigned debug;
unsigned int json;
unsigned int no_pager;
unsigned int debug;
} cmd_params_st;
FILE* pager_start(cmd_params_st *params);
void pager_stop(FILE* fp);
FILE *pager_start(cmd_params_st *params);
void pager_stop(FILE *fp);
void print_time_ival7(char output[MAX_TMPSTR_SIZE], time_t t1, time_t t2);
void print_iface_stats(const char *iface, time_t since, FILE * out, cmd_params_st *params, unsigned have_more);
int print_list_entries(FILE* out, cmd_params_st *params, const char* name, char **val, unsigned vsize, unsigned have_more);
int print_fwport_entries(FILE* out, cmd_params_st *params, const char* name, FwPortSt **val, unsigned vsize, unsigned have_more);
void print_iface_stats(const char *iface, time_t since, FILE *out,
cmd_params_st *params, unsigned int have_more);
int print_list_entries(FILE *out, cmd_params_st *params, const char *name,
char **val, unsigned int vsize, unsigned int have_more);
int print_fwport_entries(FILE *out, cmd_params_st *params, const char *name,
FwPortSt **val, unsigned int vsize,
unsigned int have_more);
void print_start_block(FILE *out, cmd_params_st *params);
void print_end_block(FILE *out, cmd_params_st *params, unsigned have_more);
void print_end_block(FILE *out, cmd_params_st *params, unsigned int have_more);
void print_array_block(FILE *out, cmd_params_st *params);
void print_end_array_block(FILE *out, cmd_params_st *params);
void print_separator(FILE *out, cmd_params_st *params);
void print_single_value(FILE *out, cmd_params_st *params, const char *name, const char *value, unsigned have_more);
void print_single_value_int(FILE *out, cmd_params_st *params, const char *name, long i, unsigned have_more);
void print_single_value_ex(FILE *out, cmd_params_st *params, const char *name, const char *value, const char *ex, unsigned have_more);
void print_pair_value(FILE *out, cmd_params_st *params, const char *name1, const char *value1, const char *name2, const char *value2, unsigned have_more);
void print_single_value(FILE *out, cmd_params_st *params, const char *name,
const char *value, unsigned int have_more);
void print_single_value_int(FILE *out, cmd_params_st *params, const char *name,
long i, unsigned int have_more);
void print_single_value_ex(FILE *out, cmd_params_st *params, const char *name,
const char *value, const char *ex,
unsigned int have_more);
void print_pair_value(FILE *out, cmd_params_st *params, const char *name1,
const char *value1, const char *name2, const char *value2,
unsigned int have_more);
void bytes2human(unsigned long bytes, char *output, unsigned int output_size,
const char *suffix);
void
bytes2human(unsigned long bytes, char* output, unsigned output_size, const char* suffix);
void time2human(uint64_t microseconds, char *output, unsigned int output_size);
void
time2human(uint64_t microseconds, char* output, unsigned output_size);
char* search_for_id(unsigned idx, const char* match, int match_size);
char* search_for_user(unsigned idx, const char* match, int match_size);
void entries_add(void *pool, const char* user, unsigned user_size, unsigned id);
char *search_for_id(unsigned int idx, const char *match, int match_size);
char *search_for_user(unsigned int idx, const char *match, int match_size);
void entries_add(void *pool, const char *user, unsigned int user_size,
unsigned int id);
void entries_clear(void);
void session_entries_add(void *pool, const char* session);
void session_entries_add(void *pool, const char *session);
void session_entries_clear(void);
char* search_for_session(unsigned idx, const char* match, int match_size);
char *search_for_session(unsigned int idx, const char *match, int match_size);
char* search_for_ip(unsigned idx, const char* match, int match_size);
void ip_entries_add(void *pool, const char* ip, unsigned ip_size);
char *search_for_ip(unsigned int idx, const char *match, int match_size);
void ip_entries_add(void *pool, const char *ip, unsigned int ip_size);
void ip_entries_clear(void);
#define DEFAULT_TIMEOUT (10*1000)
#define DEFAULT_TIMEOUT (10 * 1000)
#define NO_GROUP "(none)"
#define NO_USER "(none)"
#define ERR_SERVER_UNREACHABLE "could not send message; possibly insufficient permissions or server is offline.\n"
#define ERR_SERVER_UNREACHABLE \
"could not send message; possibly insufficient permissions or server is offline.\n"
unsigned need_help(const char *arg);
unsigned check_cmd_help(const char *line);
unsigned int need_help(const char *arg);
unsigned int check_cmd_help(const char *line);
#ifdef HAVE_DBUS
# include <dbus/dbus.h>
# define CONN_TYPE struct dbus_ctx
#include <dbus/dbus.h>
#define CONN_TYPE struct dbus_ctx
#else
# define CONN_TYPE struct unix_ctx
#define CONN_TYPE struct unix_ctx
#endif
CONN_TYPE *conn_init(void *pool, const char *socket_file);
void conn_close(CONN_TYPE*);
void conn_close(CONN_TYPE *);
int conn_prehandle(CONN_TYPE *ctx);
void conn_posthandle(CONN_TYPE *ctx);
typedef int (*cmd_func) (CONN_TYPE * conn, const char *arg, cmd_params_st *params);
typedef int (*cmd_func)(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_status_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_list_users_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_list_iroutes_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_list_banned_ips_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_list_all_sessions_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_list_valid_sessions_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_show_session_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_status_cmd(CONN_TYPE *conn, const char *arg, cmd_params_st *params);
int handle_list_users_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_list_iroutes_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_list_banned_ips_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_list_all_sessions_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_list_valid_sessions_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_show_session_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_list_banned_points_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_show_user_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_show_id_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_disconnect_user_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_unban_ip_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_disconnect_id_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_reload_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_stop_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_events_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params);
int handle_list_banned_points_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_show_user_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_show_id_cmd(CONN_TYPE *conn, const char *arg, cmd_params_st *params);
int handle_disconnect_user_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_unban_ip_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_disconnect_id_cmd(CONN_TYPE *conn, const char *arg,
cmd_params_st *params);
int handle_reload_cmd(CONN_TYPE *conn, const char *arg, cmd_params_st *params);
int handle_stop_cmd(CONN_TYPE *conn, const char *arg, cmd_params_st *params);
int handle_events_cmd(struct unix_ctx *ctx, const char *arg,
cmd_params_st *params);
#endif

View File

@@ -26,9 +26,9 @@
#include <unistd.h>
#include <occtl/occtl.h>
static const char* get_pager(void)
static const char *get_pager(void)
{
char* pager;
char *pager;
pager = getenv("OCCTL_PAGER");
if (pager == NULL)
@@ -40,7 +40,7 @@ static const char* get_pager(void)
}
/* Always succeeds */
FILE* pager_start(cmd_params_st *params)
FILE *pager_start(cmd_params_st *params)
{
FILE *fp;
const char *pager;
@@ -64,14 +64,15 @@ FILE* pager_start(cmd_params_st *params)
fp = popen(pager, "w");
if (fp == NULL) { /* no pager */
fprintf(stderr, "unable to start pager; check your $PAGER environment variable\n");
fprintf(stderr,
"unable to start pager; check your $PAGER environment variable\n");
fp = stdout;
}
return fp;
}
void pager_stop(FILE* fp)
void pager_stop(FILE *fp)
{
if (fp != stdout)
pclose(fp);

View File

@@ -36,28 +36,29 @@
#define escape_val json_escape_val
int print_list_entries(FILE* out, cmd_params_st *params, const char* name, char **val, unsigned vsize, unsigned have_more)
int print_list_entries(FILE *out, cmd_params_st *params, const char *name,
char **val, unsigned int vsize, unsigned int have_more)
{
const char * tmp;
const char *tmp;
unsigned int i = 0;
if (HAVE_JSON(params)) {
fprintf(out, " \"%s\":\t[", name);
for (i=0;i<vsize;i++) {
for (i = 0; i < vsize; i++) {
tmp = val[i];
if (tmp != NULL) {
if (i==0)
if (i == 0)
fprintf(out, "\"%s\"", tmp);
else
fprintf(out, ", \"%s\"", tmp);
}
}
fprintf(out, "]%s\n", have_more?",":"");
fprintf(out, "]%s\n", have_more ? "," : "");
} else {
for (i=0;i<vsize;i++) {
for (i = 0; i < vsize; i++) {
tmp = val[i];
if (tmp != NULL) {
if (i==0)
if (i == 0)
fprintf(out, "\t%s: %s\n", name, tmp);
else
fprintf(out, "\t\t%s\n", tmp);
@@ -68,32 +69,44 @@ int print_list_entries(FILE* out, cmd_params_st *params, const char* name, char
return i;
}
int print_fwport_entries(FILE* out, cmd_params_st *params, const char* name, FwPortSt **val, unsigned vsize, unsigned have_more)
int print_fwport_entries(FILE *out, cmd_params_st *params, const char *name,
FwPortSt **val, unsigned int vsize,
unsigned int have_more)
{
unsigned int i = 0;
char tmp[64];
if (HAVE_JSON(params)) {
fprintf(out, " \"%s\":\t[", name);
for (i=0;i<vsize;i++) {
for (i = 0; i < vsize; i++) {
if (val[i]->port)
snprintf(tmp, sizeof(tmp), "%s%s(%d)", val[i]->negate?"!":"", proto_to_str(val[i]->proto), val[i]->port);
snprintf(tmp, sizeof(tmp), "%s%s(%d)",
val[i]->negate ? "!" : "",
proto_to_str(val[i]->proto),
val[i]->port);
else
snprintf(tmp, sizeof(tmp), "%s%s()", val[i]->negate?"!":"", proto_to_str(val[i]->proto));
snprintf(tmp, sizeof(tmp), "%s%s()",
val[i]->negate ? "!" : "",
proto_to_str(val[i]->proto));
if (i==0)
if (i == 0)
fprintf(out, "\"%s\"", tmp);
else
fprintf(out, ", \"%s\"", tmp);
}
fprintf(out, "]%s\n", have_more?",":"");
fprintf(out, "]%s\n", have_more ? "," : "");
} else {
for (i=0;i<vsize;i++) {
for (i = 0; i < vsize; i++) {
if (val[i]->port)
snprintf(tmp, sizeof(tmp), "%s%s(%d)", val[i]->negate?"!":"", proto_to_str(val[i]->proto), val[i]->port);
snprintf(tmp, sizeof(tmp), "%s%s(%d)",
val[i]->negate ? "!" : "",
proto_to_str(val[i]->proto),
val[i]->port);
else
snprintf(tmp, sizeof(tmp), "%s%s()", val[i]->negate?"!":"", proto_to_str(val[i]->proto));
if (i==0)
snprintf(tmp, sizeof(tmp), "%s%s()",
val[i]->negate ? "!" : "",
proto_to_str(val[i]->proto));
if (i == 0)
fprintf(out, "\t%s: %s", name, tmp);
else
fprintf(out, ", %s", tmp);
@@ -110,10 +123,10 @@ void print_start_block(FILE *out, cmd_params_st *params)
fprintf(out, " {\n");
}
void print_end_block(FILE *out, cmd_params_st *params, unsigned have_more)
void print_end_block(FILE *out, cmd_params_st *params, unsigned int have_more)
{
if (HAVE_JSON(params))
fprintf(out, " }%s\n", have_more?",":"");
fprintf(out, " }%s\n", have_more ? "," : "");
}
void print_array_block(FILE *out, cmd_params_st *params)
@@ -134,53 +147,72 @@ void print_separator(FILE *out, cmd_params_st *params)
fprintf(out, "\n");
}
void print_single_value(FILE *out, cmd_params_st *params, const char *name, const char *value, unsigned have_more)
void print_single_value(FILE *out, cmd_params_st *params, const char *name,
const char *value, unsigned int have_more)
{
char tmp[MAX_STR_SIZE];
if (value[0] == 0)
return;
if (HAVE_JSON(params))
fprintf(out, " \"%s\": \"%s\"%s\n", name, escape_val(tmp, sizeof(tmp), value), have_more?",":"");
fprintf(out, " \"%s\": \"%s\"%s\n", name,
escape_val(tmp, sizeof(tmp), value),
have_more ? "," : "");
else
fprintf(out, "\t%s: %s\n", name, value);
}
void print_single_value_int(FILE *out, cmd_params_st *params, const char *name, long i, unsigned have_more)
void print_single_value_int(FILE *out, cmd_params_st *params, const char *name,
long i, unsigned int have_more)
{
if (HAVE_JSON(params))
fprintf(out, " \"%s\": \%lu%s\n", name, i, have_more?",":"");
fprintf(out, " \"%s\": \%lu%s\n", name, i,
have_more ? "," : "");
else
fprintf(out, "\t%s: %lu\n", name, i);
}
void print_single_value_ex(FILE *out, cmd_params_st *params, const char *name, const char *value, const char *ex, unsigned have_more)
void print_single_value_ex(FILE *out, cmd_params_st *params, const char *name,
const char *value, const char *ex,
unsigned int have_more)
{
char tmp[MAX_STR_SIZE];
if (value[0] == 0)
return;
if (HAVE_JSON(params)) {
fprintf(out, " \"%s\": \"%s\",\n", name, escape_val(tmp, sizeof(tmp), value));
fprintf(out, " \"_%s\": \"%s\"%s\n", name, escape_val(tmp, sizeof(tmp), ex), have_more?",":"");
fprintf(out, " \"%s\": \"%s\",\n", name,
escape_val(tmp, sizeof(tmp), value));
fprintf(out, " \"_%s\": \"%s\"%s\n", name,
escape_val(tmp, sizeof(tmp), ex), have_more ? "," : "");
} else
fprintf(out, "\t%s: %s (%s)\n", name, value, ex);
}
void print_pair_value(FILE *out, cmd_params_st *params, const char *name1, const char *value1, const char *name2, const char *value2, unsigned have_more)
void print_pair_value(FILE *out, cmd_params_st *params, const char *name1,
const char *value1, const char *name2, const char *value2,
unsigned int have_more)
{
char tmp[MAX_STR_SIZE];
if (HAVE_JSON(params)) {
if (value1 && value1[0] != 0)
fprintf(out, " \"%s\": \"%s\"%s\n", name1, escape_val(tmp, sizeof(tmp), value1), have_more?",":"");
fprintf(out, " \"%s\": \"%s\"%s\n", name1,
escape_val(tmp, sizeof(tmp), value1),
have_more ? "," : "");
if (value2 && value2[0] != 0)
fprintf(out, " \"%s\": \"%s\"%s\n", name2, escape_val(tmp, sizeof(tmp), value2), have_more?",":"");
fprintf(out, " \"%s\": \"%s\"%s\n", name2,
escape_val(tmp, sizeof(tmp), value2),
have_more ? "," : "");
} else {
if (value1 && value1[0] != 0)
fprintf(out, "\t%s: %s", name1, value1);
if (value2 && value2[0] != 0) {
const char *sep;
if (name1)
sep = " ";
else

View File

@@ -30,35 +30,39 @@ typedef struct session_entries_st {
char session[SAFE_ID_SIZE];
} session_entries_st;
static session_entries_st *session_entries = NULL;
static unsigned session_entries_size = 0;
static unsigned max_session_entries_size = 0;
static session_entries_st *session_entries;
static unsigned int session_entries_size;
static unsigned int max_session_entries_size;
void session_entries_clear(void)
{
session_entries_size = 0;
}
void session_entries_add(void *pool, const char* session)
void session_entries_add(void *pool, const char *session)
{
if (session_entries_size+1 > max_session_entries_size) {
if (session_entries_size + 1 > max_session_entries_size) {
max_session_entries_size += 128;
session_entries = talloc_realloc_size(pool, session_entries, sizeof(session_entries_st)*max_session_entries_size);
session_entries = talloc_realloc_size(
pool, session_entries,
sizeof(session_entries_st) * max_session_entries_size);
}
strlcpy(session_entries[session_entries_size].session, session, sizeof(session_entries[session_entries_size].session));
strlcpy(session_entries[session_entries_size].session, session,
sizeof(session_entries[session_entries_size].session));
session_entries_size++;
}
char* search_for_session(unsigned idx, const char* match, int match_size)
char *search_for_session(unsigned int idx, const char *match, int match_size)
{
unsigned i;
unsigned int i;
if (idx >= session_entries_size)
return NULL;
for (i=idx;i<session_entries_size;i++) {
if (strncasecmp(match, session_entries[i].session, MIN(match_size, SAFE_ID_SIZE)) == 0)
for (i = idx; i < session_entries_size; i++) {
if (strncasecmp(match, session_entries[i].session,
MIN(match_size, SAFE_ID_SIZE)) == 0)
return strdup(session_entries[i].session);
}

View File

@@ -44,17 +44,19 @@ void print_time_ival7(char output[MAX_TMPSTR_SIZE], time_t t1, time_t t2)
if (t >= 48 * 60 * 60)
/* 2 days or more */
snprintf(output, MAX_TMPSTR_SIZE, _("%2ludays"), (long)t / (24 * 60 * 60));
snprintf(output, MAX_TMPSTR_SIZE, _("%2ludays"),
(long)t / (24 * 60 * 60));
else if (t >= 60 * 60)
/* 1 hour or more */
/* Translation Hint: Hours:Minutes */
snprintf(output, MAX_TMPSTR_SIZE, _("%2luh:%02um"), (long)t / (60 * 60),
(unsigned)((t / 60) % 60));
/* Translation Hint: Hours:Minutes */
snprintf(output, MAX_TMPSTR_SIZE, _("%2luh:%02um"),
(long)t / (60 * 60), (unsigned int)((t / 60) % 60));
else if (t > 60)
/* 1 minute or more */
/* Translation Hint: Minutes:Seconds */
snprintf(output, MAX_TMPSTR_SIZE, "%2lum:%02us", (long)t / 60, (unsigned)t % 60);
/* Translation Hint: Minutes:Seconds */
snprintf(output, MAX_TMPSTR_SIZE, "%2lum:%02us", (long)t / 60,
(unsigned int)t % 60);
else
/* Translation Hint: Seconds:Centiseconds */
/* Translation Hint: Seconds:Centiseconds */
snprintf(output, MAX_TMPSTR_SIZE, _("%5lus"), (long)t);
}

File diff suppressed because it is too large Load Diff

View File

@@ -25,14 +25,14 @@
#include <stdint.h>
#include <unistd.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h> /* for random */
#include <gnutls/crypto.h> /* for random */
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#ifdef HAVE_CRYPT_H
/* libcrypt in Fedora28 does not provide prototype
/* libcrypt in Fedora28 does not provide prototype
* in unistd.h */
# include <crypt.h>
#include <crypt.h>
#endif
#include <locale.h>
@@ -42,18 +42,17 @@ static const char alphabet[] =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./";
#define SALT_SIZE 16
static void
crypt_int(const char *fpasswd, const char *username, const char *groupname,
const char *passwd)
static void crypt_int(const char *fpasswd, const char *username,
const char *groupname, const char *passwd)
{
uint8_t _salt[SALT_SIZE];
char salt[SALT_SIZE+16];
char salt[SALT_SIZE + 16];
char *p, *cr_passwd;
char *tmp_passwd;
unsigned i;
unsigned fpasswd_len = strlen(fpasswd);
unsigned tmp_passwd_len;
unsigned username_len = strlen(username);
unsigned int i;
unsigned int fpasswd_len = strlen(fpasswd);
unsigned int tmp_passwd_len;
unsigned int username_len = strlen(username);
struct stat st;
FILE *fd, *fd2;
char *line = NULL;
@@ -121,14 +120,17 @@ crypt_int(const char *fpasswd, const char *username, const char *groupname,
fprintf(fd2, "%s:%s:%s\n", username, groupname, cr_passwd);
} else {
int found = 0;
while ((len = getline(&line, &line_size, fd)) > 0) {
p = strchr(line, ':');
if (p == NULL)
continue;
l = p-line;
if (l == username_len && strncmp(line, username, l) == 0) {
fprintf(fd2, "%s:%s:%s\n", username, groupname, cr_passwd); /* lgtm[cpp/cleartext-storage-file] */
l = p - line;
if (l == username_len &&
strncmp(line, username, l) == 0) {
fprintf(fd2, "%s:%s:%s\n", username, groupname,
cr_passwd); /* lgtm[cpp/cleartext-storage-file] */
found = 1;
} else {
fwrite(line, 1, len, fd2);
@@ -138,7 +140,8 @@ crypt_int(const char *fpasswd, const char *username, const char *groupname,
fclose(fd);
if (found == 0)
fprintf(fd2, "%s:%s:%s\n", username, groupname, cr_passwd); /* lgtm[cpp/cleartext-storage-file] */
fprintf(fd2, "%s:%s:%s\n", username, groupname,
cr_passwd); /* lgtm[cpp/cleartext-storage-file] */
}
fclose(fd2);
@@ -151,15 +154,14 @@ crypt_int(const char *fpasswd, const char *username, const char *groupname,
free(tmp_passwd);
}
static void
delete_user(const char *fpasswd, const char *username)
static void delete_user(const char *fpasswd, const char *username)
{
FILE * fd, *fd2;
FILE *fd, *fd2;
char *tmp_passwd;
char *line, *p;
unsigned fpasswd_len = strlen(fpasswd);
unsigned tmp_passwd_len;
unsigned username_len = strlen(username);
unsigned int fpasswd_len = strlen(fpasswd);
unsigned int tmp_passwd_len;
unsigned int username_len = strlen(username);
int ret;
ssize_t len, l;
size_t line_size;
@@ -196,7 +198,7 @@ delete_user(const char *fpasswd, const char *username)
if (p == NULL)
continue;
l = p-line;
l = p - line;
if (l == username_len && strncmp(line, username, l) == 0) {
continue;
} else {
@@ -216,15 +218,14 @@ delete_user(const char *fpasswd, const char *username)
free(tmp_passwd);
}
static void
lock_user(const char *fpasswd, const char *username)
static void lock_user(const char *fpasswd, const char *username)
{
FILE * fd, *fd2;
FILE *fd, *fd2;
char *tmp_passwd;
char *line, *p;
unsigned fpasswd_len = strlen(fpasswd);
unsigned tmp_passwd_len;
unsigned username_len = strlen(username);
unsigned int fpasswd_len = strlen(fpasswd);
unsigned int tmp_passwd_len;
unsigned int username_len = strlen(username);
int ret;
ssize_t len, l;
size_t line_size;
@@ -261,18 +262,18 @@ lock_user(const char *fpasswd, const char *username)
if (p == NULL)
continue;
l = p-line;
l = p - line;
if (l == username_len && strncmp(line, username, l) == 0) {
p = strchr(p+1, ':');
p = strchr(p + 1, ':');
if (p == NULL)
continue;
p++;
if (*p != '!') {
l = p-line;
l = p - line;
fwrite(line, 1, l, fd2);
fputc('!', fd2);
fwrite(p, 1, len-l, fd2);
fwrite(p, 1, len - l, fd2);
} else {
fwrite(line, 1, len, fd2);
}
@@ -293,15 +294,14 @@ lock_user(const char *fpasswd, const char *username)
free(tmp_passwd);
}
static void
unlock_user(const char *fpasswd, const char *username)
static void unlock_user(const char *fpasswd, const char *username)
{
FILE * fd, *fd2;
FILE *fd, *fd2;
char *tmp_passwd;
char *line, *p;
unsigned fpasswd_len = strlen(fpasswd);
unsigned tmp_passwd_len;
unsigned username_len = strlen(username);
unsigned int fpasswd_len = strlen(fpasswd);
unsigned int tmp_passwd_len;
unsigned int username_len = strlen(username);
int ret;
ssize_t len, l;
size_t line_size;
@@ -338,19 +338,20 @@ unlock_user(const char *fpasswd, const char *username)
if (p == NULL)
continue;
l = p-line;
l = p - line;
if (l == username_len && strncmp(line, username, l) == 0) {
p = strchr(p+1, ':');
p = strchr(p + 1, ':');
if (p == NULL)
continue;
p++;
l = p-line;
l = p - line;
fwrite(line, 1, l, fd2);
if (*p=='!') p++;
l = p-line;
fwrite(p, 1, len-l, fd2);
if (*p == '!')
p++;
l = p - line;
fwrite(p, 1, len - l, fd2);
} else {
fwrite(line, 1, len, fd2);
}
@@ -369,63 +370,67 @@ unlock_user(const char *fpasswd, const char *username)
}
static const struct option long_options[] = {
{"passwd", 1, 0, 'c'},
{"groupname", 1, 0, 'g'},
{"delete", 0, 0, 'd'},
{"lock", 0, 0, 'l'},
{"unlock", 0, 0, 'u'},
{"help", 0, 0, 'h'},
{"version", 0, 0, 'v'},
{NULL, 0, 0, 0}
{ "passwd", 1, 0, 'c' }, { "groupname", 1, 0, 'g' },
{ "delete", 0, 0, 'd' }, { "lock", 0, 0, 'l' },
{ "unlock", 0, 0, 'u' }, { "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' }, { NULL, 0, 0, 0 }
};
static
void usage(void)
static void usage(void)
{
fprintf(stderr, "ocpasswd - OpenConnect server password utility\n");
fprintf(stderr, "Usage: ocpasswd [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [username]\n");
fprintf(stderr,
"Usage: ocpasswd [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [username]\n");
fprintf(stderr, "\n");
fprintf(stderr, " -c, --passwd=file Password file\n");
fprintf(stderr, " -g, --groupname=str User's group name\n");
fprintf(stderr, " -d, --delete Delete user\n");
fprintf(stderr, " -l, --lock Lock user\n");
fprintf(stderr, " -u, --unlock Unlock user\n");
fprintf(stderr, " -v, --version output version information and exit\n");
fprintf(stderr, " -h, --help display extended usage information and exit\n");
fprintf(stderr,
" -v, --version output version information and exit\n");
fprintf(stderr,
" -h, --help display extended usage information and exit\n");
fprintf(stderr, "\n");
fprintf(stderr, "Options are specified by doubled hyphens and their name or by a single\n");
fprintf(stderr,
"Options are specified by doubled hyphens and their name or by a single\n");
fprintf(stderr, "hyphen and the flag character.\n\n");
fprintf(stderr, "This program is openconnect password (ocpasswd) utility. It allows the\n");
fprintf(stderr, "generation and handling of a 'plain' password file used by ocserv.\n\n");
fprintf(stderr, "Please file bug reports at: "PACKAGE_BUGREPORT"\n");
fprintf(stderr,
"This program is openconnect password (ocpasswd) utility. It allows the\n");
fprintf(stderr,
"generation and handling of a 'plain' password file used by ocserv.\n\n");
fprintf(stderr, "Please file bug reports at: " PACKAGE_BUGREPORT "\n");
}
static
void version(void)
static void version(void)
{
fprintf(stderr, "ocpasswd - "VERSION"\n");
fprintf(stderr, "Copyright (C) 2013-2017 Nikos Mavrogiannopoulos, all rights reserved.\n");
fprintf(stderr, "This is free software. It is licensed for use, modification and\n");
fprintf(stderr, "redistribution under the terms of the GNU General Public License,\n");
fprintf(stderr, "ocpasswd - " VERSION "\n");
fprintf(stderr,
"Copyright (C) 2013-2017 Nikos Mavrogiannopoulos, all rights reserved.\n");
fprintf(stderr,
"This is free software. It is licensed for use, modification and\n");
fprintf(stderr,
"redistribution under the terms of the GNU General Public License,\n");
fprintf(stderr, "version 2 <http://gnu.org/licenses/gpl.html>\n\n");
fprintf(stderr, "Please file bug reports at: "PACKAGE_BUGREPORT"\n");
fprintf(stderr, "Please file bug reports at: " PACKAGE_BUGREPORT "\n");
}
#define FLAG_DELETE 1
#define FLAG_LOCK (1<<1)
#define FLAG_UNLOCK (1<<2)
#define FLAG_LOCK (1 << 1)
#define FLAG_UNLOCK (1 << 2)
int main(int argc, char **argv)
{
int ret, c;
const char *username = NULL;
char *groupname = NULL, *fpasswd = NULL;
char* passwd = NULL;
unsigned free_passwd = 0;
char *passwd = NULL;
unsigned int free_passwd = 0;
size_t l, i;
unsigned flags = 0;
unsigned int flags = 0;
if ((ret = gnutls_global_init()) < 0) {
ret = gnutls_global_init();
if (ret < 0) {
fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret));
exit(EXIT_FAILURE);
}
@@ -440,14 +445,16 @@ int main(int argc, char **argv)
switch (c) {
case 'c':
if (fpasswd) {
fprintf(stderr, "-c option cannot be specified multiple time\n");
fprintf(stderr,
"-c option cannot be specified multiple time\n");
exit(EXIT_FAILURE);
}
fpasswd = strdup(optarg);
break;
case 'g':
if (groupname) {
fprintf(stderr, "-g option cannot be specified multiple time\n");
fprintf(stderr,
"-g option cannot be specified multiple time\n");
exit(EXIT_FAILURE);
}
groupname = strdup(optarg);
@@ -482,7 +489,7 @@ int main(int argc, char **argv)
}
}
if (optind < argc && argc-optind == 1) {
if (optind < argc && argc - optind == 1) {
username = argv[optind++];
} else {
usage();
@@ -511,7 +518,7 @@ int main(int argc, char **argv)
} else { /* set password */
if (isatty(STDIN_FILENO)) {
char* p2;
char *p2;
passwd = getpass("Enter password: ");
if (passwd == NULL) {
@@ -519,7 +526,6 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
p2 = strdup(passwd);
passwd = getpass("Re-enter password: ");
if (passwd == NULL) {
@@ -541,8 +547,8 @@ int main(int argc, char **argv)
}
free_passwd = 1;
if (passwd[l-1] == '\n')
passwd[l-1] = 0;
if (passwd[l - 1] == '\n')
passwd[l - 1] = 0;
}
crypt_int(fpasswd, username, groupname, passwd);

View File

@@ -25,48 +25,47 @@
struct find_ip_st {
struct sockaddr_storage *sockaddr;
unsigned sockaddr_size;
unsigned found_ips;
unsigned int sockaddr_size;
unsigned int found_ips;
};
struct find_dtls_id_st {
const uint8_t *dtls_id;
unsigned dtls_id_size;
unsigned int dtls_id_size;
};
struct find_sid_st {
const uint8_t *sid;
};
static size_t rehash_ip(const void* _p, void* unused)
static size_t rehash_ip(const void *_p, void *unused)
{
const struct proc_st * proc = _p;
const struct proc_st *proc = _p;
return hash_any(
SA_IN_P_GENERIC(&proc->remote_addr, proc->remote_addr_len),
SA_IN_SIZE(proc->remote_addr_len), 0);
return hash_any(SA_IN_P_GENERIC(&proc->remote_addr,
proc->remote_addr_len),
SA_IN_SIZE(proc->remote_addr_len), 0);
}
static size_t rehash_dtls_ip(const void* _p, void* unused)
static size_t rehash_dtls_ip(const void *_p, void *unused)
{
const struct proc_st * proc = _p;
const struct proc_st *proc = _p;
return hash_any(
SA_IN_P_GENERIC(&proc->dtls_remote_addr, proc->dtls_remote_addr_len),
SA_IN_SIZE(proc->dtls_remote_addr_len), 0);
return hash_any(SA_IN_P_GENERIC(&proc->dtls_remote_addr,
proc->dtls_remote_addr_len),
SA_IN_SIZE(proc->dtls_remote_addr_len), 0);
}
static size_t rehash_dtls_id(const void* _p, void* unused)
static size_t rehash_dtls_id(const void *_p, void *unused)
{
const struct proc_st * proc = _p;
const struct proc_st *proc = _p;
return hash_any(proc->dtls_session_id, proc->dtls_session_id_size, 0);
}
static size_t rehash_sid(const void* _p, void* unused)
static size_t rehash_sid(const void *_p, void *unused)
{
const struct proc_st * proc = _p;
const struct proc_st *proc = _p;
return hash_any(proc->sid, sizeof(proc->sid), 0);
}
@@ -113,7 +112,8 @@ int proc_table_add(main_server_st *s, struct proc_st *proc)
return -1;
}
if (htable_add(s->proc_table.db_sid, rehash_sid(proc, NULL), proc) == 0) {
if (htable_add(s->proc_table.db_sid, rehash_sid(proc, NULL), proc) ==
0) {
htable_del(s->proc_table.db_ip, ip_hash, proc);
htable_del(s->proc_table.db_dtls_id, dtls_id_hash, proc);
return -1;
@@ -124,19 +124,21 @@ int proc_table_add(main_server_st *s, struct proc_st *proc)
return 0;
}
int proc_table_update_ip(main_server_st *s, struct proc_st *proc, struct sockaddr_storage *addr,
unsigned addr_size)
int proc_table_update_ip(main_server_st *s, struct proc_st *proc,
struct sockaddr_storage *addr, unsigned int addr_size)
{
char buf[MAX_IP_STR];
unsigned removed;
unsigned int removed;
/* only update if we can remove the old IP */
if (addr_size != proc->remote_addr_len ||
memcmp(addr, &proc->remote_addr, addr_size) != 0) {
mslog(s, proc, LOG_INFO, "updating remote IP to %s",
human_addr2((struct sockaddr*)addr, addr_size, buf, sizeof(buf), 0));
human_addr2((struct sockaddr *)addr, addr_size, buf,
sizeof(buf), 0));
removed = htable_del(s->proc_table.db_ip, rehash_ip(proc, NULL), proc);
removed = htable_del(s->proc_table.db_ip, rehash_ip(proc, NULL),
proc);
memcpy(&proc->remote_addr, addr, addr_size);
proc->remote_addr_len = addr_size;
@@ -147,8 +149,8 @@ int proc_table_update_ip(main_server_st *s, struct proc_st *proc, struct sockadd
memcmp(SA_IN_P_GENERIC(addr, addr_size),
SA_IN_P_GENERIC(&proc->dtls_remote_addr, addr_size),
SA_IN_SIZE(addr_size)) == 0) {
if (htable_del(s->proc_table.db_dtls_ip, rehash_dtls_ip(proc, NULL), proc) != 0)
if (htable_del(s->proc_table.db_dtls_ip,
rehash_dtls_ip(proc, NULL), proc) != 0)
proc->dtls_remote_addr_len = 0;
}
@@ -156,7 +158,8 @@ int proc_table_update_ip(main_server_st *s, struct proc_st *proc, struct sockadd
* we may be called even before that entry is added, and we don't want
* duplicates */
if (removed) {
if (htable_add(s->proc_table.db_ip, rehash_ip(proc, NULL), proc) == 0)
if (htable_add(s->proc_table.db_ip,
rehash_ip(proc, NULL), proc) == 0)
return -1;
}
}
@@ -167,7 +170,9 @@ int proc_table_update_ip(main_server_st *s, struct proc_st *proc, struct sockadd
/* Adds the IP of the DTLS channel into the DTLS IP hash table. It
* only adds the IP if it is different than the CSTP channel IP.
*/
int proc_table_update_dtls_ip(main_server_st *s, struct proc_st *proc, struct sockaddr_storage *addr, unsigned addr_size)
int proc_table_update_dtls_ip(main_server_st *s, struct proc_st *proc,
struct sockaddr_storage *addr,
unsigned int addr_size)
{
if (proc->dtls_remote_addr_len) {
if (proc->dtls_remote_addr_len == addr_size &&
@@ -176,7 +181,8 @@ int proc_table_update_dtls_ip(main_server_st *s, struct proc_st *proc, struct so
SA_IN_SIZE(addr_size)) == 0) {
return -1; /* DTLS address is already up to date */
}
htable_del(s->proc_table.db_dtls_ip, rehash_dtls_ip(proc, NULL), proc);
htable_del(s->proc_table.db_dtls_ip, rehash_dtls_ip(proc, NULL),
proc);
}
proc->dtls_remote_addr_len = 0;
@@ -193,7 +199,8 @@ int proc_table_update_dtls_ip(main_server_st *s, struct proc_st *proc, struct so
proc->dtls_remote_addr_len = addr_size;
memcpy(&proc->dtls_remote_addr, addr, addr_size);
if (htable_add(s->proc_table.db_dtls_ip, rehash_dtls_ip(proc, NULL), proc) == 0)
if (htable_add(s->proc_table.db_dtls_ip, rehash_dtls_ip(proc, NULL),
proc) == 0)
return -1;
return 0;
@@ -202,24 +209,26 @@ int proc_table_update_dtls_ip(main_server_st *s, struct proc_st *proc, struct so
void proc_table_del(main_server_st *s, struct proc_st *proc)
{
if (proc->dtls_remote_addr_len > 0)
htable_del(s->proc_table.db_dtls_ip, rehash_dtls_ip(proc, NULL), proc);
htable_del(s->proc_table.db_dtls_ip, rehash_dtls_ip(proc, NULL),
proc);
htable_del(s->proc_table.db_ip, rehash_ip(proc, NULL), proc);
htable_del(s->proc_table.db_dtls_id, rehash_dtls_id(proc, NULL), proc);
htable_del(s->proc_table.db_sid, rehash_sid(proc, NULL), proc);
}
static bool local_ip_cmp(const void* _c1, void* _c2)
static bool local_ip_cmp(const void *_c1, void *_c2)
{
const struct proc_st* c1 = _c1;
struct find_ip_st* c2 = _c2;
const struct proc_st *c1 = _c1;
struct find_ip_st *c2 = _c2;
if (c2->sockaddr_size == 0)
return 0;
/* Test if peer IP matches DTLS IP */
if (c1->dtls_remote_addr_len == c2->sockaddr_size &&
memcmp(SA_IN_P_GENERIC(&c1->dtls_remote_addr, c1->dtls_remote_addr_len),
memcmp(SA_IN_P_GENERIC(&c1->dtls_remote_addr,
c1->dtls_remote_addr_len),
SA_IN_P_GENERIC(c2->sockaddr, c2->sockaddr_size),
SA_IN_SIZE(c1->dtls_remote_addr_len)) == 0) {
c2->found_ips++;
@@ -242,7 +251,7 @@ static bool local_ip_cmp(const void* _c1, void* _c2)
*/
struct proc_st *proc_search_single_ip(struct main_server_st *s,
struct sockaddr_storage *sockaddr,
unsigned sockaddr_size)
unsigned int sockaddr_size)
{
struct proc_st *proc;
struct find_ip_st fip;
@@ -252,7 +261,7 @@ struct proc_st *proc_search_single_ip(struct main_server_st *s,
fip.sockaddr_size = sockaddr_size;
h = hash_any(SA_IN_P_GENERIC(sockaddr, sockaddr_size),
SA_IN_SIZE(sockaddr_size), 0);
SA_IN_SIZE(sockaddr_size), 0);
fip.found_ips = 0;
proc = htable_get(s->proc_table.db_dtls_ip, h, local_ip_cmp, &fip);
@@ -267,16 +276,15 @@ struct proc_st *proc_search_single_ip(struct main_server_st *s,
return NULL;
}
static bool dtls_id_cmp(const void* _c1, void* _c2)
static bool dtls_id_cmp(const void *_c1, void *_c2)
{
const struct proc_st* c1 = _c1;
struct find_dtls_id_st* c2 = _c2;
const struct proc_st *c1 = _c1;
struct find_dtls_id_st *c2 = _c2;
if (c1->dtls_session_id_size != c2->dtls_id_size)
return 0;
if (memcmp(c1->dtls_session_id,
c2->dtls_id,
if (memcmp(c1->dtls_session_id, c2->dtls_id,
c1->dtls_session_id_size) == 0) {
return 1;
}
@@ -284,25 +292,24 @@ static bool dtls_id_cmp(const void* _c1, void* _c2)
return 0;
}
struct proc_st *proc_search_dtls_id(struct main_server_st *s,
const uint8_t *id, unsigned id_size)
struct proc_st *proc_search_dtls_id(struct main_server_st *s, const uint8_t *id,
unsigned int id_size)
{
struct find_dtls_id_st fdtls_id;
fdtls_id.dtls_id = id;
fdtls_id.dtls_id_size = id_size;
return htable_get(s->proc_table.db_dtls_id, hash_any(id, id_size, 0), dtls_id_cmp, &fdtls_id);
return htable_get(s->proc_table.db_dtls_id, hash_any(id, id_size, 0),
dtls_id_cmp, &fdtls_id);
}
static bool sid_cmp(const void* _c1, void* _c2)
static bool sid_cmp(const void *_c1, void *_c2)
{
const struct proc_st* c1 = _c1;
struct find_sid_st* c2 = _c2;
const struct proc_st *c1 = _c1;
struct find_sid_st *c2 = _c2;
if (memcmp(c1->sid,
c2->sid,
sizeof(c1->sid)) == 0) {
if (memcmp(c1->sid, c2->sid, sizeof(c1->sid)) == 0) {
return 1;
}
@@ -310,10 +317,12 @@ static bool sid_cmp(const void* _c1, void* _c2)
}
struct proc_st *proc_search_sid(struct main_server_st *s,
const uint8_t sid[SID_SIZE])
const uint8_t sid[SID_SIZE])
{
struct find_sid_st fsid;
fsid.sid = sid;
return htable_get(s->proc_table.db_sid, hash_any(sid, SID_SIZE, 0), sid_cmp, &fsid);
return htable_get(s->proc_table.db_sid, hash_any(sid, SID_SIZE, 0),
sid_cmp, &fsid);
}

View File

@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_PROC_SEARCH_H
# define OC_PROC_SEARCH_H
#define OC_PROC_SEARCH_H
#include <vpn.h>
#include <string.h>
@@ -28,17 +28,21 @@
#include <main.h>
struct proc_st *proc_search_single_ip(struct main_server_st *s,
struct sockaddr_storage *sockaddr,
unsigned sockaddr_size);
struct proc_st *proc_search_dtls_id(struct main_server_st *s, const uint8_t *id, unsigned id_size);
struct sockaddr_storage *sockaddr,
unsigned int sockaddr_size);
struct proc_st *proc_search_dtls_id(struct main_server_st *s, const uint8_t *id,
unsigned int id_size);
struct proc_st *proc_search_sid(struct main_server_st *s,
const uint8_t id[SID_SIZE]);
const uint8_t id[SID_SIZE]);
void proc_table_init(main_server_st *s);
void proc_table_deinit(main_server_st *s);
int proc_table_add(main_server_st *s, struct proc_st *proc);
void proc_table_del(main_server_st *s, struct proc_st *proc);
int proc_table_update_ip(main_server_st *s, struct proc_st *proc, struct sockaddr_storage *addr, unsigned addr_size);
int proc_table_update_dtls_ip(main_server_st *s, struct proc_st *proc, struct sockaddr_storage *addr, unsigned addr_size);
int proc_table_update_ip(main_server_st *s, struct proc_st *proc,
struct sockaddr_storage *addr, unsigned int addr_size);
int proc_table_update_dtls_ip(main_server_st *s, struct proc_st *proc,
struct sockaddr_storage *addr,
unsigned int addr_size);
#endif

View File

@@ -34,11 +34,10 @@
#include <str.h>
#include <common.h>
static
int call_script(main_server_st *s, proc_st *proc, const char *cmd)
static int call_script(main_server_st *s, proc_st *proc, const char *cmd)
{
pid_t pid;
int ret, status = 0;
pid_t pid;
int ret, status = 0;
if (cmd == NULL)
return 0;
@@ -50,7 +49,8 @@ int ret, status = 0;
mslog(s, proc, LOG_DEBUG, "executing route script %s", cmd);
ret = execl("/bin/sh", "sh", "-c", cmd, NULL);
if (ret == -1) {
mslog(s, proc, LOG_ERR, "Could not execute route script %s", cmd);
mslog(s, proc, LOG_ERR,
"Could not execute route script %s", cmd);
exit(EXIT_FAILURE);
}
@@ -72,17 +72,16 @@ int ret, status = 0;
}
if (WEXITSTATUS(status)) {
mslog(s, proc, LOG_INFO, "cmd: %s: exited with error %d", cmd, WEXITSTATUS(ret));
mslog(s, proc, LOG_INFO, "cmd: %s: exited with error %d", cmd,
WEXITSTATUS(ret));
return ERR_EXEC;
}
return 0;
}
static
int replace_cmd(struct main_server_st* s, proc_st *proc,
char **cmd, const char* pattern,
const char* route, const char* dev)
static int replace_cmd(struct main_server_st *s, proc_st *proc, char **cmd,
const char *pattern, const char *route, const char *dev)
{
str_st str;
int ret;
@@ -106,23 +105,23 @@ int replace_cmd(struct main_server_st* s, proc_st *proc,
if (ret < 0)
goto fail;
*cmd = (char*)str.data;
*cmd = (char *)str.data;
return 0;
fail:
fail:
str_clear(&str);
return ERR_MEM;
}
static
int route_adddel(struct main_server_st* s, proc_st *proc,
const char* pattern, const char* route, const char* dev)
static int route_adddel(struct main_server_st *s, proc_st *proc,
const char *pattern, const char *route, const char *dev)
{
int ret;
char *cmd = NULL;
int ret;
char *cmd = NULL;
if (pattern == 0) {
mslog(s, NULL, LOG_WARNING, "route-add-cmd or route-del-cmd are not set.");
mslog(s, NULL, LOG_WARNING,
"route-add-cmd or route-del-cmd are not set.");
return 0;
}
@@ -133,25 +132,27 @@ char *cmd = NULL;
ret = call_script(s, proc, cmd);
if (ret < 0) {
int e = errno;
mslog(s, NULL, LOG_INFO, "failed to spawn cmd: %s: %s", cmd, strerror(e));
mslog(s, NULL, LOG_INFO, "failed to spawn cmd: %s: %s", cmd,
strerror(e));
ret = ERR_EXEC;
goto fail;
}
ret = 0;
fail:
fail:
talloc_free(cmd);
return ret;
}
static
int route_add(struct main_server_st* s, proc_st *proc, const char* route, const char* dev)
static int route_add(struct main_server_st *s, proc_st *proc, const char *route,
const char *dev)
{
return route_adddel(s, proc, GETCONFIG(s)->route_add_cmd, route, dev);
}
static
int route_del(struct main_server_st* s, proc_st *proc, const char* route, const char* dev)
static int route_del(struct main_server_st *s, proc_st *proc, const char *route,
const char *dev)
{
return route_adddel(s, proc, GETCONFIG(s)->route_del_cmd, route, dev);
}
@@ -159,25 +160,27 @@ int route_del(struct main_server_st* s, proc_st *proc, const char* route, const
/* Executes the commands required to apply all the configured routes
* for this client locally.
*/
int apply_iroutes(struct main_server_st* s, struct proc_st *proc)
int apply_iroutes(struct main_server_st *s, struct proc_st *proc)
{
unsigned i, j;
int ret;
unsigned int i, j;
int ret;
if (proc->config->n_iroutes == 0)
return 0;
for (i=0;i<proc->config->n_iroutes;i++) {
ret = route_add(s, proc, proc->config->iroutes[i], proc->tun_lease.name);
for (i = 0; i < proc->config->n_iroutes; i++) {
ret = route_add(s, proc, proc->config->iroutes[i],
proc->tun_lease.name);
if (ret < 0)
goto fail;
}
proc->applied_iroutes = 1;
return 0;
fail:
for (j=0;j<i;j++)
route_del(s, proc, proc->config->iroutes[j], proc->tun_lease.name);
fail:
for (j = 0; j < i; j++)
route_del(s, proc, proc->config->iroutes[j],
proc->tun_lease.name);
return -1;
}
@@ -185,15 +188,17 @@ int ret;
/* Executes the commands required to removed all the configured routes
* for this client.
*/
void remove_iroutes(struct main_server_st* s, struct proc_st *proc)
void remove_iroutes(struct main_server_st *s, struct proc_st *proc)
{
unsigned i;
unsigned int i;
if (proc->config == NULL || proc->config->n_iroutes == 0 || proc->applied_iroutes == 0)
if (proc->config == NULL || proc->config->n_iroutes == 0 ||
proc->applied_iroutes == 0)
return;
for (i=0;i<proc->config->n_iroutes;i++) {
route_del(s, proc, proc->config->iroutes[i], proc->tun_lease.name);
for (i = 0; i < proc->config->n_iroutes; i++) {
route_del(s, proc, proc->config->iroutes[i],
proc->tun_lease.name);
}
proc->applied_iroutes = 0;
}

View File

@@ -19,12 +19,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_ROUTE_ADD_H
# define OC_ROUTE_ADD_H
#define OC_ROUTE_ADD_H
#include <vpn.h>
#include <main.h>
int apply_iroutes(struct main_server_st* s, struct proc_st *proc);
void remove_iroutes(struct main_server_st* s, struct proc_st *proc);
int apply_iroutes(struct main_server_st *s, struct proc_st *proc);
void remove_iroutes(struct main_server_st *s, struct proc_st *proc);
#endif

View File

@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_SCRIPT_LIST_H
# define OC_SCRIPT_LIST_H
#define OC_SCRIPT_LIST_H
#include <main.h>
#include <sys/types.h>
@@ -28,10 +28,10 @@
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, struct proc_st* proc)
inline static void add_to_script_list(main_server_st *s, pid_t pid,
struct proc_st *proc)
{
struct script_wait_st *stmp;
struct script_wait_st *stmp;
stmp = talloc(s, struct script_wait_st);
if (stmp == NULL)
@@ -49,12 +49,14 @@ struct script_wait_st *stmp;
/* Removes the tracked connect script, and kills it. It returns the pid
* of the removed script or -1.
*/
inline static pid_t remove_from_script_list(main_server_st* s, struct proc_st* proc)
inline static pid_t remove_from_script_list(main_server_st *s,
struct proc_st *proc)
{
struct script_wait_st *stmp = NULL, *spos;
pid_t ret = -1;
list_for_each_safe(&s->script_list.head, stmp, spos, list) {
list_for_each_safe(&s->script_list.head, stmp, spos, list)
{
if (stmp->proc == proc) {
list_del(&stmp->list);
ev_child_stop(main_loop, &stmp->ev_child);

View File

@@ -19,21 +19,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_SEC_MOD_ACCT_H
# define OC_SEC_MOD_ACCT_H
#define OC_SEC_MOD_ACCT_H
#include <main.h>
#include <sec-mod-auth.h>
typedef struct acct_mod_st {
unsigned int type; /* ACCT_TYPE_ */
unsigned int auth_types; /* or of the AUTH_TYPEs which are compatible with this */
void (*vhost_init)(void **vctx, void *pool, void* additional);
unsigned int
auth_types; /* or of the AUTH_TYPEs which are compatible with this */
void (*vhost_init)(void **vctx, void *pool, void *additional);
void (*vhost_deinit)(void *vctx);
/* The context provided below is of the authentication method */
int (*open_session)(void *vctx, unsigned auth_method, const common_acct_info_st *ai, const void *sid, unsigned sid_size); /* optional, may be null */
void (*session_stats)(void *vctx, unsigned auth_method, const common_acct_info_st *ai, struct stats_st *stats); /* optional, may be null */
void (*close_session)(void *vctx, unsigned auth_method, const common_acct_info_st *ai, struct stats_st *stats, unsigned discon_reason/*REASON_*/); /* optional may be null */
int (*open_session)(void *vctx, unsigned int auth_method,
const common_acct_info_st *ai, const void *sid,
unsigned int sid_size); /* optional, may be null */
void (*session_stats)(
void *vctx, unsigned int auth_method,
const common_acct_info_st *ai,
struct stats_st *stats); /* optional, may be null */
void (*close_session)(
void *vctx, unsigned int auth_method,
const common_acct_info_st *ai, struct stats_st *stats,
unsigned discon_reason /*REASON_*/); /* optional may be null */
} acct_mod_st;
/* The accounting messages exchanged with the worker thread are shown in ipc.proto.

View File

@@ -54,33 +54,40 @@
#include <hmac.h>
#ifdef HAVE_GSSAPI
# include <gssapi/gssapi.h>
# include <gssapi/gssapi_ext.h>
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_ext.h>
#endif
/* initializes vhost acct and auth modules if not already initialized
*/
void sec_auth_init(struct vhost_cfg_st *vhost)
{
unsigned i;
unsigned int i;
void *pool = vhost;
for (i=0;i<vhost->perm_config.auth_methods;i++) {
if (vhost->perm_config.auth[i].enabled && vhost->perm_config.auth[i].amod &&
vhost->perm_config.auth[i].amod->vhost_init && vhost->perm_config.auth[i].auth_ctx == NULL) {
vhost->perm_config.auth[i].amod->vhost_init(&vhost->perm_config.auth[i].auth_ctx, pool, vhost->perm_config.auth[i].additional);
for (i = 0; i < vhost->perm_config.auth_methods; i++) {
if (vhost->perm_config.auth[i].enabled &&
vhost->perm_config.auth[i].amod &&
vhost->perm_config.auth[i].amod->vhost_init &&
vhost->perm_config.auth[i].auth_ctx == NULL) {
vhost->perm_config.auth[i].amod->vhost_init(
&vhost->perm_config.auth[i].auth_ctx, pool,
vhost->perm_config.auth[i].additional);
}
}
if (vhost->perm_config.acct.amod && vhost->perm_config.acct.amod->vhost_init &&
if (vhost->perm_config.acct.amod &&
vhost->perm_config.acct.amod->vhost_init &&
vhost->perm_config.acct.acct_ctx == NULL)
vhost->perm_config.acct.amod->vhost_init(&vhost->perm_config.acct.acct_ctx, pool, vhost->perm_config.acct.additional);
vhost->perm_config.acct.amod->vhost_init(
&vhost->perm_config.acct.acct_ctx, pool,
vhost->perm_config.acct.additional);
}
/* returns a negative number if we have reached the score for this client.
*/
static
void sec_mod_add_score_to_ip(sec_mod_st *sec, client_entry_st *e, const char *ip, unsigned points)
static void sec_mod_add_score_to_ip(sec_mod_st *sec, client_entry_st *e,
const char *ip, unsigned int points)
{
void *lpool = talloc_new(e);
int ret, err;
@@ -90,7 +97,7 @@ void sec_mod_add_score_to_ip(sec_mod_st *sec, client_entry_st *e, const char *ip
if (e->vhost->perm_config.config->max_ban_score == 0)
return;
msg.ip = (char*)ip;
msg.ip = (char *)ip;
msg.score = points;
msg.sid.data = e->sid;
msg.sid.len = sizeof(e->sid);
@@ -101,19 +108,20 @@ void sec_mod_add_score_to_ip(sec_mod_st *sec, client_entry_st *e, const char *ip
}
ret = send_msg(lpool, sec->cmd_fd, CMD_SECM_BAN_IP, &msg,
(pack_size_func) ban_ip_msg__get_packed_size,
(pack_func) ban_ip_msg__pack);
(pack_size_func)ban_ip_msg__get_packed_size,
(pack_func)ban_ip_msg__pack);
if (ret < 0) {
err = errno;
seclog(sec, LOG_WARNING, "error in sending BAN IP message: %s", strerror(err));
seclog(sec, LOG_WARNING, "error in sending BAN IP message: %s",
strerror(err));
goto fail;
}
fail:
fail:
talloc_free(lpool);
}
static void update_auth_time_stats(sec_mod_st * sec, time_t secs)
static void update_auth_time_stats(sec_mod_st *sec, time_t secs)
{
if (secs < 0)
return;
@@ -127,11 +135,15 @@ static void update_auth_time_stats(sec_mod_st * sec, time_t secs)
if (secs > sec->max_auth_time)
sec->max_auth_time = secs;
sec->avg_auth_time = ((uint64_t)sec->avg_auth_time*((uint64_t)(sec->total_authentications-1))+secs) / (uint64_t)sec->total_authentications;
sec->avg_auth_time =
((uint64_t)sec->avg_auth_time *
((uint64_t)(sec->total_authentications - 1)) +
secs) /
(uint64_t)sec->total_authentications;
}
static
int send_sec_auth_reply(int cfd, sec_mod_st * sec, client_entry_st * entry, AUTHREP r)
static int send_sec_auth_reply(int cfd, sec_mod_st *sec, client_entry_st *entry,
AUTHREP r)
{
SecAuthReplyMsg msg = SEC_AUTH_REPLY_MSG__INIT;
int ret;
@@ -157,25 +169,24 @@ int send_sec_auth_reply(int cfd, sec_mod_st * sec, client_entry_st * entry, AUTH
msg.dtls_session_id.data = entry->dtls_session_id;
msg.dtls_session_id.len = sizeof(entry->dtls_session_id);
ret = send_msg(entry, cfd, CMD_SEC_AUTH_REPLY,
&msg,
(pack_size_func)
sec_auth_reply_msg__get_packed_size,
(pack_func) sec_auth_reply_msg__pack);
ret = send_msg(
entry, cfd, CMD_SEC_AUTH_REPLY, &msg,
(pack_size_func)sec_auth_reply_msg__get_packed_size,
(pack_func)sec_auth_reply_msg__pack);
} else {
sec->auth_failures++;
msg.reply = AUTH__REP__FAILED;
ret = send_msg(entry, cfd, CMD_SEC_AUTH_REPLY,
&msg,
(pack_size_func)
sec_auth_reply_msg__get_packed_size,
(pack_func) sec_auth_reply_msg__pack);
ret = send_msg(
entry, cfd, CMD_SEC_AUTH_REPLY, &msg,
(pack_size_func)sec_auth_reply_msg__get_packed_size,
(pack_func)sec_auth_reply_msg__pack);
}
if (ret < 0) {
int e = errno;
seclog(sec, LOG_ERR, "send_msg: %s", strerror(e));
return ret;
}
@@ -186,8 +197,7 @@ int send_sec_auth_reply(int cfd, sec_mod_st * sec, client_entry_st * entry, AUTH
return 0;
}
static
int send_sec_auth_reply_msg(int cfd, sec_mod_st * sec, client_entry_st * e)
static int send_sec_auth_reply_msg(int cfd, sec_mod_st *sec, client_entry_st *e)
{
SecAuthReplyMsg msg = SEC_AUTH_REPLY_MSG__INIT;
int ret;
@@ -204,8 +214,8 @@ int send_sec_auth_reply_msg(int cfd, sec_mod_st * sec, client_entry_st * e)
msg.sid.len = sizeof(e->sid);
ret = send_msg(e, cfd, CMD_SEC_AUTH_REPLY, &msg,
(pack_size_func) sec_auth_reply_msg__get_packed_size,
(pack_func) sec_auth_reply_msg__pack);
(pack_size_func)sec_auth_reply_msg__get_packed_size,
(pack_func)sec_auth_reply_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR, "send_auth_reply_msg error");
}
@@ -216,47 +226,69 @@ int send_sec_auth_reply_msg(int cfd, sec_mod_st * sec, client_entry_st * e)
return ret;
}
static int check_cert_user_group_status(sec_mod_st * sec, client_entry_st * e)
static int check_cert_user_group_status(sec_mod_st *sec, client_entry_st *e)
{
unsigned found, i;
unsigned int found, i;
if (e->auth_type & AUTH_TYPE_CERTIFICATE) {
if (e->tls_auth_ok == 0) {
seclog(sec, LOG_INFO, "user %s "SESSION_STR" presented no certificate; rejecting",
seclog(sec, LOG_INFO,
"user %s " SESSION_STR
" presented no certificate; rejecting",
e->acct_info.username, e->acct_info.safe_id);
return -1;
}
if (e->acct_info.username[0] == 0 && e->vhost->perm_config.config->cert_user_oid != NULL) {
if (e->acct_info.username[0] == 0 &&
e->vhost->perm_config.config->cert_user_oid != NULL) {
if (e->cert_user_name[0] == 0) {
seclog(sec, LOG_INFO, "no username in the certificate; rejecting");
return -1;
}
strlcpy(e->acct_info.username, e->cert_user_name, sizeof(e->acct_info.username));
if (e->cert_group_names_size > 0 && e->vhost->perm_config.config->cert_group_oid != NULL && e->acct_info.groupname[0] == 0)
strlcpy(e->acct_info.groupname, e->cert_group_names[0], sizeof(e->acct_info.groupname));
} else {
if (e->vhost->perm_config.config->cert_user_oid != NULL && e->cert_user_name[0] && strcmp(e->acct_info.username, e->cert_user_name) != 0) {
seclog(sec, LOG_INFO,
"user '%s' "SESSION_STR" presented a certificate which is for user '%s'; rejecting",
e->acct_info.username, e->acct_info.safe_id, e->cert_user_name);
"no username in the certificate; rejecting");
return -1;
}
if (e->vhost->perm_config.config->cert_group_oid != NULL) {
strlcpy(e->acct_info.username, e->cert_user_name,
sizeof(e->acct_info.username));
if (e->cert_group_names_size > 0 &&
e->vhost->perm_config.config->cert_group_oid !=
NULL &&
e->acct_info.groupname[0] == 0)
strlcpy(e->acct_info.groupname,
e->cert_group_names[0],
sizeof(e->acct_info.groupname));
} else {
if (e->vhost->perm_config.config->cert_user_oid !=
NULL &&
e->cert_user_name[0] &&
strcmp(e->acct_info.username, e->cert_user_name) !=
0) {
seclog(sec, LOG_INFO,
"user '%s' " SESSION_STR
" presented a certificate which is for user '%s'; rejecting",
e->acct_info.username,
e->acct_info.safe_id, e->cert_user_name);
return -1;
}
if (e->vhost->perm_config.config->cert_group_oid !=
NULL) {
found = 0;
for (i=0;i<e->cert_group_names_size;i++) {
if (strcmp(e->acct_info.groupname, e->cert_group_names[i]) == 0) {
for (i = 0; i < e->cert_group_names_size; i++) {
if (strcmp(e->acct_info.groupname,
e->cert_group_names[i]) ==
0) {
found++;
break;
}
}
if (found == 0) {
seclog(sec, LOG_INFO,
"user '%s' "SESSION_STR" presented a certificate from group '%s' but he isn't a member of it; rejecting",
e->acct_info.username, e->acct_info.safe_id, e->acct_info.groupname);
return -1;
"user '%s' " SESSION_STR
" presented a certificate from group '%s' but he isn't a member of it; rejecting",
e->acct_info.username,
e->acct_info.safe_id,
e->acct_info.groupname);
return -1;
}
}
}
@@ -265,8 +297,7 @@ static int check_cert_user_group_status(sec_mod_st * sec, client_entry_st * e)
return 0;
}
static
int check_group(sec_mod_st * sec, client_entry_st * e)
static int check_group(sec_mod_st *sec, client_entry_st *e)
{
int ret;
const char *req_group = NULL;
@@ -275,9 +306,9 @@ int check_group(sec_mod_st * sec, client_entry_st * e)
req_group = e->req_group_name;
if (e->module && e->module->auth_group) {
ret =
e->module->auth_group(e->auth_ctx, req_group, e->acct_info.groupname,
sizeof(e->acct_info.groupname));
ret = e->module->auth_group(e->auth_ctx, req_group,
e->acct_info.groupname,
sizeof(e->acct_info.groupname));
if (ret != 0) {
return -1;
}
@@ -286,27 +317,31 @@ int check_group(sec_mod_st * sec, client_entry_st * e)
/* set group name using the certificate info */
if (e->auth_type & AUTH_TYPE_CERTIFICATE) {
if (e->acct_info.groupname[0] == 0 && req_group != NULL && e->vhost->perm_config.config->cert_group_oid != NULL) {
unsigned i, found = 0;
if (e->acct_info.groupname[0] == 0 && req_group != NULL &&
e->vhost->perm_config.config->cert_group_oid != NULL) {
unsigned int i, found = 0;
for (i=0;i<e->cert_group_names_size;i++) {
if (strcmp(req_group, e->cert_group_names[i]) == 0) {
strlcpy(e->acct_info.groupname, e->cert_group_names[i], sizeof(e->acct_info.groupname));
for (i = 0; i < e->cert_group_names_size; i++) {
if (strcmp(req_group, e->cert_group_names[i]) ==
0) {
strlcpy(e->acct_info.groupname,
e->cert_group_names[i],
sizeof(e->acct_info.groupname));
found = 1;
break;
}
}
if (found == 0) {
seclog(sec, LOG_NOTICE, "user '%s' requested group '%s' but is not included on his certificate groups",
e->acct_info.username, req_group);
seclog(sec, LOG_NOTICE,
"user '%s' requested group '%s' but is not included on his certificate groups",
e->acct_info.username, req_group);
return -1;
}
}
}
ret =
check_cert_user_group_status(sec, e);
ret = check_cert_user_group_status(sec, e);
if (ret < 0) {
return -1;
}
@@ -320,8 +355,8 @@ int check_group(sec_mod_st * sec, client_entry_st * e)
* @cmd: the command received
* @result: the auth result
*/
static
int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int result)
static int handle_sec_auth_res(int cfd, sec_mod_st *sec, client_entry_st *e,
int result)
{
int ret;
passwd_msg_st pst;
@@ -344,8 +379,12 @@ int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int resu
if (result == ERR_AUTH_CONTINUE) {
/* if the module allows multiple retries for the password and the password refers to the same stage */
if (e->status != PS_AUTH_INIT && e->module && e->module->allows_retries && passwd_retries == 1) {
sec_mod_add_score_to_ip(sec, e, e->acct_info.remote_ip, e->vhost->perm_config.config->ban_points_wrong_password);
if (e->status != PS_AUTH_INIT && e->module &&
e->module->allows_retries && passwd_retries == 1) {
sec_mod_add_score_to_ip(
sec, e, e->acct_info.remote_ip,
e->vhost->perm_config.config
->ban_points_wrong_password);
}
ret = send_sec_auth_reply_msg(cfd, sec, e);
@@ -354,7 +393,7 @@ int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int resu
seclog(sec, LOG_ERR, "could not send reply auth cmd.");
return ret;
}
return 0; /* wait for another command */
return 0; /* wait for another command */
} else if (result == 0 && e->status != PS_AUTH_FAILED) {
/* we checked status for PS_AUTH_FAILED, because status may
* change async if we receive a message from main that the
@@ -374,9 +413,13 @@ int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int resu
sizeof(e->acct_info.username));
}
seclog(sec, LOG_DEBUG, "auth complete %sfor user '%s' "SESSION_STR" of group: '%s'",
(e->auth_type & AUTH_TYPE_CERTIFICATE)?"(with cert)":"",
e->acct_info.username, e->acct_info.safe_id, e->acct_info.groupname);
seclog(sec, LOG_DEBUG,
"auth complete %sfor user '%s' " SESSION_STR
" of group: '%s'",
(e->auth_type & AUTH_TYPE_CERTIFICATE) ? "(with cert)" :
"",
e->acct_info.username, e->acct_info.safe_id,
e->acct_info.groupname);
ret = send_sec_auth_reply(cfd, sec, e, AUTH__REP__OK);
if (ret < 0) {
@@ -389,7 +432,9 @@ int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int resu
} else {
e->status = PS_AUTH_FAILED;
sec_mod_add_score_to_ip(sec, e, e->acct_info.remote_ip, e->vhost->perm_config.config->ban_points_wrong_password);
sec_mod_add_score_to_ip(
sec, e, e->acct_info.remote_ip,
e->vhost->perm_config.config->ban_points_wrong_password);
ret = send_sec_auth_reply(cfd, sec, e, AUTH__REP__FAILED);
if (ret < 0) {
@@ -400,7 +445,8 @@ int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int resu
if (result < 0) {
ret = result;
} else {
seclog(sec, LOG_ERR, "unexpected auth result: %d\n", result);
seclog(sec, LOG_ERR, "unexpected auth result: %d\n",
result);
ret = ERR_BAD_COMMAND;
}
}
@@ -415,8 +461,7 @@ static void stats_add_to(stats_st *dst, stats_st *src1, stats_st *src2)
dst->uptime = src1->uptime + src2->uptime;
}
static
int send_failed_session_open_reply(sec_mod_st *sec, int fd)
static int send_failed_session_open_reply(sec_mod_st *sec, int fd)
{
SecmSessionReplyMsg rep = SECM_SESSION_REPLY_MSG__INIT;
void *lpool;
@@ -430,8 +475,8 @@ int send_failed_session_open_reply(sec_mod_st *sec, int fd)
}
ret = send_msg(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
(pack_size_func) secm_session_reply_msg__get_packed_size,
(pack_func) secm_session_reply_msg__pack);
(pack_size_func)secm_session_reply_msg__get_packed_size,
(pack_func)secm_session_reply_msg__pack);
if (ret < 0) {
seclog(sec, LOG_WARNING, "error in sending session reply");
ret = ERR_BAD_COMMAND; /* we desynced */
@@ -441,7 +486,8 @@ int send_failed_session_open_reply(sec_mod_st *sec, int fd)
return ret;
}
int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenMsg *req)
int handle_secm_session_open_cmd(sec_mod_st *sec, int fd,
const SecmSessionOpenMsg *req)
{
client_entry_st *e;
void *lpool;
@@ -452,38 +498,53 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
rep.config = &_cfg;
if (req->sid.len != SID_SIZE) {
seclog(sec, LOG_ERR, "auth session open but with illegal sid size (%d)!",
seclog(sec, LOG_ERR,
"auth session open but with illegal sid size (%d)!",
(int)req->sid.len);
return send_failed_session_open_reply(sec, fd);
}
e = find_client_entry(sec, req->sid.data);
if (e == NULL) {
seclog(sec, LOG_INFO, "session open but with non-existing SID!");
seclog(sec, LOG_INFO,
"session open but with non-existing SID!");
return send_failed_session_open_reply(sec, fd);
}
if (e->status != PS_AUTH_COMPLETED) {
seclog(sec, LOG_ERR, "session open received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_ERR,
"session open received in unauthenticated client %s " SESSION_STR
"!",
e->acct_info.username, e->acct_info.safe_id);
return send_failed_session_open_reply(sec, fd);
}
if IS_CLIENT_ENTRY_EXPIRED(sec, e, time(NULL)) {
seclog(sec, LOG_ERR, "session expired; denied session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
if IS_CLIENT_ENTRY_EXPIRED (sec, e, time(NULL)) {
seclog(sec, LOG_ERR,
"session expired; denied session for user '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
e->status = PS_AUTH_FAILED;
return send_failed_session_open_reply(sec, fd);
}
if (req->ipv4)
strlcpy(e->acct_info.ipv4, req->ipv4, sizeof(e->acct_info.ipv4));
strlcpy(e->acct_info.ipv4, req->ipv4,
sizeof(e->acct_info.ipv4));
if (req->ipv6)
strlcpy(e->acct_info.ipv6, req->ipv6, sizeof(e->acct_info.ipv6));
strlcpy(e->acct_info.ipv6, req->ipv6,
sizeof(e->acct_info.ipv6));
if (e->vhost->perm_config.acct.amod != NULL && e->vhost->perm_config.acct.amod->open_session != NULL && e->session_is_open == 0) {
ret = e->vhost->perm_config.acct.amod->open_session(e->vhost_acct_ctx, e->auth_type, &e->acct_info, req->sid.data, req->sid.len);
if (e->vhost->perm_config.acct.amod != NULL &&
e->vhost->perm_config.acct.amod->open_session != NULL &&
e->session_is_open == 0) {
ret = e->vhost->perm_config.acct.amod->open_session(
e->vhost_acct_ctx, e->auth_type, &e->acct_info,
req->sid.data, req->sid.len);
if (ret < 0) {
e->status = PS_AUTH_FAILED;
seclog(sec, LOG_INFO, "denied session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_INFO,
"denied session for user '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
return send_failed_session_open_reply(sec, fd);
}
}
@@ -500,9 +561,11 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
/* Fixme: possibly we should allow for completely random seeds */
if (e->vhost->perm_config.config->predictable_ips != 0) {
rep.ipv4_seed = hash_any(e->acct_info.username, strlen(e->acct_info.username), 0);
rep.ipv4_seed = hash_any(e->acct_info.username,
strlen(e->acct_info.username), 0);
} else {
ret = gnutls_rnd(GNUTLS_RND_NONCE, &rep.ipv4_seed, sizeof(rep.ipv4_seed));
ret = gnutls_rnd(GNUTLS_RND_NONCE, &rep.ipv4_seed,
sizeof(rep.ipv4_seed));
if (ret < 0)
return -1;
}
@@ -517,68 +580,80 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
return ERR_BAD_COMMAND; /* we desync */
}
if (e->vhost->config_module && e->vhost->config_module->get_sup_config) {
ret = e->vhost->config_module->get_sup_config(e->vhost->perm_config.config, e, &rep, lpool);
if (e->vhost->config_module &&
e->vhost->config_module->get_sup_config) {
ret = e->vhost->config_module->get_sup_config(
e->vhost->perm_config.config, e, &rep, lpool);
if (ret < 0) {
seclog(sec, LOG_ERR, "error reading additional configuration for '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_ERR,
"error reading additional configuration for '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
talloc_free(lpool);
return send_failed_session_open_reply(sec, fd);
}
}
ret = send_msg(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
(pack_size_func) secm_session_reply_msg__get_packed_size,
(pack_func) secm_session_reply_msg__pack);
(pack_size_func)secm_session_reply_msg__get_packed_size,
(pack_func)secm_session_reply_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR, "error in sending session reply");
return ERR_BAD_COMMAND; /* we desync */
}
talloc_free(lpool);
seclog(sec, LOG_INFO, "%sinitiating session for user '%s' "SESSION_STR, PREFIX_VHOST(e->vhost), e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_INFO, "%sinitiating session for user '%s' " SESSION_STR,
PREFIX_VHOST(e->vhost), e->acct_info.username,
e->acct_info.safe_id);
/* refresh cookie validity */
e->exptime = time(NULL) + e->vhost->perm_config.config->cookie_timeout + AUTH_SLACK_TIME;
e->exptime = time(NULL) + e->vhost->perm_config.config->cookie_timeout +
AUTH_SLACK_TIME;
e->in_use++;
return 0;
}
int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionCloseMsg *req)
int handle_secm_session_close_cmd(sec_mod_st *sec, int fd,
const SecmSessionCloseMsg *req)
{
client_entry_st *e;
int ret;
CliStatsMsg rep = CLI_STATS_MSG__INIT;
if (req->sid.len != SID_SIZE) {
seclog(sec, LOG_ERR, "auth session close but with illegal sid size (%d)!",
seclog(sec, LOG_ERR,
"auth session close but with illegal sid size (%d)!",
(int)req->sid.len);
return ERR_BAD_COMMAND;
}
e = find_client_entry(sec, req->sid.data);
if (e == NULL) {
seclog(sec, LOG_INFO, "session close but with non-existing SID");
seclog(sec, LOG_INFO,
"session close but with non-existing SID");
return send_msg(sec, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
(pack_size_func)cli_stats_msg__get_packed_size,
(pack_func)cli_stats_msg__pack);
}
if (e->status < PS_AUTH_COMPLETED) {
seclog(sec, LOG_DEBUG, "session close received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_DEBUG,
"session close received in unauthenticated client %s " SESSION_STR
"!",
e->acct_info.username, e->acct_info.safe_id);
return send_msg(e, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
(pack_size_func)cli_stats_msg__get_packed_size,
(pack_func)cli_stats_msg__pack);
}
if (req->has_uptime && req->uptime > e->stats.uptime) {
e->stats.uptime = req->uptime;
e->stats.uptime = req->uptime;
}
if (req->has_bytes_in && req->bytes_in > e->stats.bytes_in) {
e->stats.bytes_in = req->bytes_in;
e->stats.bytes_in = req->bytes_in;
}
if (req->has_bytes_out && req->bytes_out > e->stats.bytes_out) {
e->stats.bytes_out = req->bytes_out;
e->stats.bytes_out = req->bytes_out;
}
if (req->server_disconnected) {
@@ -592,8 +667,8 @@ int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionClos
rep.discon_reason = e->discon_reason;
ret = send_msg(e, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
(pack_size_func)cli_stats_msg__get_packed_size,
(pack_func)cli_stats_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR, "error in sending session stats");
return ERR_BAD_COMMAND;
@@ -612,7 +687,8 @@ void handle_sec_auth_ban_ip_reply(sec_mod_st *sec, const BanIpReplyMsg *msg)
client_entry_st *e;
if (msg->sid.len != SID_SIZE) {
seclog(sec, LOG_ERR, "ban IP reply but with illegal sid size (%d)!",
seclog(sec, LOG_ERR,
"ban IP reply but with illegal sid size (%d)!",
(int)msg->sid.len);
return;
}
@@ -627,25 +703,31 @@ void handle_sec_auth_ban_ip_reply(sec_mod_st *sec, const BanIpReplyMsg *msg)
}
}
int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req, pid_t pid)
int handle_sec_auth_stats_cmd(sec_mod_st *sec, const CliStatsMsg *req,
pid_t pid)
{
client_entry_st *e;
stats_st totals;
if (req->sid.len != SID_SIZE) {
seclog(sec, LOG_ERR, "auth session stats but with illegal sid size (%d)!",
seclog(sec, LOG_ERR,
"auth session stats but with illegal sid size (%d)!",
(int)req->sid.len);
return -1;
}
e = find_client_entry(sec, req->sid.data);
if (e == NULL) {
seclog(sec, LOG_INFO, "session stats but with non-existing SID");
seclog(sec, LOG_INFO,
"session stats but with non-existing SID");
return -1;
}
if (e->status != PS_AUTH_COMPLETED) {
seclog(sec, LOG_ERR, "session stats received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_ERR,
"session stats received in unauthenticated client %s " SESSION_STR
"!",
e->acct_info.username, e->acct_info.safe_id);
return -1;
}
@@ -664,29 +746,35 @@ int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req, pid_t p
/* update PID */
e->acct_info.id = pid;
if (e->vhost->perm_config.acct.amod == NULL || e->vhost->perm_config.acct.amod->session_stats == NULL)
if (e->vhost->perm_config.acct.amod == NULL ||
e->vhost->perm_config.acct.amod->session_stats == NULL)
return 0;
stats_add_to(&totals, &e->stats, &e->saved_stats);
if (req->remote_ip)
strlcpy(e->acct_info.remote_ip, req->remote_ip, sizeof(e->acct_info.remote_ip));
strlcpy(e->acct_info.remote_ip, req->remote_ip,
sizeof(e->acct_info.remote_ip));
if (req->ipv4)
strlcpy(e->acct_info.ipv4, req->ipv4, sizeof(e->acct_info.ipv4));
strlcpy(e->acct_info.ipv4, req->ipv4,
sizeof(e->acct_info.ipv4));
if (req->ipv6)
strlcpy(e->acct_info.ipv6, req->ipv6, sizeof(e->acct_info.ipv6));
strlcpy(e->acct_info.ipv6, req->ipv6,
sizeof(e->acct_info.ipv6));
e->vhost->perm_config.acct.amod->session_stats(e->vhost_acct_ctx, e->auth_type, &e->acct_info, &totals);
e->vhost->perm_config.acct.amod->session_stats(
e->vhost_acct_ctx, e->auth_type, &e->acct_info, &totals);
return 0;
}
int handle_sec_auth_cont(int cfd, sec_mod_st * sec, const SecAuthContMsg * req)
int handle_sec_auth_cont(int cfd, sec_mod_st *sec, const SecAuthContMsg *req)
{
client_entry_st *e;
int ret;
if (req->sid.len != SID_SIZE) {
seclog(sec, LOG_ERR, "auth cont but with illegal sid size (%d)!",
seclog(sec, LOG_ERR,
"auth cont but with illegal sid size (%d)!",
(int)req->sid.len);
return -1;
}
@@ -698,17 +786,22 @@ int handle_sec_auth_cont(int cfd, sec_mod_st * sec, const SecAuthContMsg * req)
}
if (e->status != PS_AUTH_INIT && e->status != PS_AUTH_CONT) {
seclog(sec, LOG_ERR, "auth cont received for %s "SESSION_STR" but we are on state %s(%u)!",
e->acct_info.username, e->acct_info.safe_id, ps_status_to_str(e->status, 0), e->status);
seclog(sec, LOG_ERR,
"auth cont received for %s " SESSION_STR
" but we are on state %s(%u)!",
e->acct_info.username, e->acct_info.safe_id,
ps_status_to_str(e->status, 0), e->status);
ret = -1;
goto cleanup;
}
seclog(sec, LOG_DEBUG, "auth cont for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_DEBUG, "auth cont for user '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
if (req->password == NULL) {
seclog(sec, LOG_ERR, "no password given in auth cont for user '%s' "SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_ERR,
"no password given in auth cont for user '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
ret = -1;
goto cleanup;
}
@@ -721,40 +814,45 @@ int handle_sec_auth_cont(int cfd, sec_mod_st * sec, const SecAuthContMsg * req)
e->status = PS_AUTH_CONT;
ret =
e->module->auth_pass(e->auth_ctx, req->password,
strlen(req->password));
ret = e->module->auth_pass(e->auth_ctx, req->password,
strlen(req->password));
if (ret < 0) {
if (ret != ERR_AUTH_CONTINUE) {
seclog(sec, LOG_DEBUG,
"error in password given in auth cont for user '%s' "SESSION_STR,
"error in password given in auth cont for user '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
}
goto cleanup;
}
cleanup:
cleanup:
return handle_sec_auth_res(cfd, sec, e, ret);
}
static
int set_module(sec_mod_st * sec, vhost_cfg_st *vhost, client_entry_st *e, unsigned auth_type)
static int set_module(sec_mod_st *sec, vhost_cfg_st *vhost, client_entry_st *e,
unsigned int auth_type)
{
unsigned i;
unsigned int i;
if (auth_type == 0)
return -1;
/* Find the first configured authentication method which contains
* the method asked by the worker, and use that. */
for (i=0;i<vhost->perm_config.auth_methods;i++) {
if (vhost->perm_config.auth[i].enabled && (vhost->perm_config.auth[i].type & auth_type) == auth_type) {
for (i = 0; i < vhost->perm_config.auth_methods; i++) {
if (vhost->perm_config.auth[i].enabled &&
(vhost->perm_config.auth[i].type & auth_type) ==
auth_type) {
e->module = vhost->perm_config.auth[i].amod;
e->auth_type = vhost->perm_config.auth[i].type;
e->vhost_auth_ctx = vhost->perm_config.auth[i].auth_ctx;
e->vhost_acct_ctx = vhost->perm_config.acct.acct_ctx;
seclog(sec, LOG_INFO, "%susing '%s' authentication to authenticate user "SESSION_STR, PREFIX_VHOST(vhost), vhost->perm_config.auth[i].name, e->acct_info.safe_id);
seclog(sec, LOG_INFO,
"%susing '%s' authentication to authenticate user " SESSION_STR,
PREFIX_VHOST(vhost),
vhost->perm_config.auth[i].name,
e->acct_info.safe_id);
return 0;
}
}
@@ -762,12 +860,13 @@ int set_module(sec_mod_st * sec, vhost_cfg_st *vhost, client_entry_st *e, unsign
return -1;
}
int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pid_t pid)
int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req,
pid_t pid)
{
int ret = -1;
client_entry_st *e;
unsigned i;
unsigned need_continue = 0;
unsigned int i;
unsigned int need_continue = 0;
vhost_cfg_st *vhost;
hmac_component_st hmac_components[3];
uint8_t computed_hmac[HMAC_DIGEST_SIZE];
@@ -780,27 +879,33 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
}
/* Authenticate the client parameters */
session_start_time = (time_t)req->session_start_time; // avoid time_t size problem
session_start_time =
(time_t)req->session_start_time; // avoid time_t size problem
hmac_components[0].data = req->orig_remote_ip;
hmac_components[0].data = req->orig_remote_ip;
// req->ip is required and protobuf doesn't permit null for required parameters
hmac_components[0].length = strlen(req->orig_remote_ip);
hmac_components[1].data = req->our_ip;
hmac_components[1].length = req->our_ip ? strlen(req->our_ip) : 0;
hmac_components[2].data = (void*)&session_start_time;
hmac_components[2].data = (void *)&session_start_time;
hmac_components[2].length = sizeof(session_start_time);
generate_hmac(sizeof(sec->hmac_key), sec->hmac_key, ARRAY_SIZE(hmac_components), hmac_components, computed_hmac);
generate_hmac(sizeof(sec->hmac_key), sec->hmac_key,
ARRAY_SIZE(hmac_components), hmac_components,
computed_hmac);
if (memcmp(computed_hmac, req->hmac.data, req->hmac.len) != 0) {
seclog(sec, LOG_NOTICE, "hmac presented by client doesn't match parameters provided - possible replay");
seclog(sec, LOG_NOTICE,
"hmac presented by client doesn't match parameters provided - possible replay");
return -1;
}
vhost = find_vhost(sec->vconfig, req->vhost);
if ((now - session_start_time) > vhost->perm_config.config->auth_timeout) {
seclog(sec, LOG_NOTICE, "hmac presented by client expired - possible replay");
if ((now - session_start_time) >
vhost->perm_config.config->auth_timeout) {
seclog(sec, LOG_NOTICE,
"hmac presented by client expired - possible replay");
return -1;
}
@@ -812,7 +917,8 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
ret = set_module(sec, vhost, e, req->auth_type);
if (ret < 0) {
seclog(sec, LOG_ERR, "no module found for auth type %u", (unsigned)req->auth_type);
seclog(sec, LOG_ERR, "no module found for auth type %u",
(unsigned int)req->auth_type);
goto cleanup;
}
@@ -825,8 +931,8 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
st.user_agent = req->user_agent;
st.id = pid;
ret =
e->module->auth_init(&e->auth_ctx, e, e->vhost_auth_ctx, &st);
ret = e->module->auth_init(&e->auth_ctx, e, e->vhost_auth_ctx,
&st);
if (ret == ERR_AUTH_CONTINUE) {
need_continue = 1;
} else if (ret < 0) {
@@ -837,38 +943,46 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
e->tls_auth_ok = req->tls_auth_ok;
if (req->device_platform != NULL) {
strlcpy(e->acct_info.device_platform, req->device_platform, sizeof(e->acct_info.device_platform));
strlcpy(e->acct_info.device_platform, req->device_platform,
sizeof(e->acct_info.device_platform));
}
if (req->device_type != NULL) {
strlcpy(e->acct_info.device_type, req->device_type, sizeof(e->acct_info.device_type));
strlcpy(e->acct_info.device_type, req->device_type,
sizeof(e->acct_info.device_type));
}
if (req->user_agent != NULL)
strlcpy(e->acct_info.user_agent, req->user_agent, sizeof(e->acct_info.user_agent));
strlcpy(e->acct_info.user_agent, req->user_agent,
sizeof(e->acct_info.user_agent));
// Real user name is retrieved after auth.
if (!(req->auth_type & CONFIDENTIAL_USER_NAME_AUTH_TYPES)) {
if (req->user_name != NULL) {
strlcpy(e->acct_info.username, req->user_name, sizeof(e->acct_info.username));
strlcpy(e->acct_info.username, req->user_name,
sizeof(e->acct_info.username));
}
}
if (req->our_ip != NULL) {
strlcpy(e->acct_info.our_ip, req->our_ip, sizeof(e->acct_info.our_ip));
strlcpy(e->acct_info.our_ip, req->our_ip,
sizeof(e->acct_info.our_ip));
}
if (req->group_name != NULL) {
strlcpy(e->req_group_name, req->group_name, sizeof(e->req_group_name));
strlcpy(e->req_group_name, req->group_name,
sizeof(e->req_group_name));
}
if (req->cert_user_name != NULL) {
strlcpy(e->cert_user_name, req->cert_user_name, sizeof(e->cert_user_name));
strlcpy(e->cert_user_name, req->cert_user_name,
sizeof(e->cert_user_name));
}
e->cert_group_names_size = MIN(MAX_GROUPS,req->n_cert_group_names);
for (i=0;i<e->cert_group_names_size;i++) {
e->cert_group_names[i] = talloc_strdup(e, req->cert_group_names[i]);
e->cert_group_names_size = MIN(MAX_GROUPS, req->n_cert_group_names);
for (i = 0; i < e->cert_group_names_size; i++) {
e->cert_group_names[i] =
talloc_strdup(e, req->cert_group_names[i]);
if (e->cert_group_names[i] == NULL) {
e->cert_group_names_size = 0;
break;
@@ -876,9 +990,11 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
}
e->status = PS_AUTH_INIT;
seclog(sec, LOG_DEBUG, "auth init %sfor user '%s' "SESSION_STR" of group: '%s' from '%s'",
req->tls_auth_ok?"(with cert) ":"",
e->acct_info.username, e->acct_info.safe_id, e->acct_info.groupname, req->remote_ip);
seclog(sec, LOG_DEBUG,
"auth init %sfor user '%s' " SESSION_STR
" of group: '%s' from '%s'",
req->tls_auth_ok ? "(with cert) " : "", e->acct_info.username,
e->acct_info.safe_id, e->acct_info.groupname, req->remote_ip);
if (need_continue != 0) {
ret = ERR_AUTH_CONTINUE;
@@ -886,7 +1002,7 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
}
ret = 0;
cleanup:
cleanup:
return handle_sec_auth_res(cfd, sec, e, ret);
}
@@ -896,9 +1012,15 @@ void sec_auth_user_deinit(sec_mod_st *sec, client_entry_st *e)
vhost = e->vhost;
seclog(sec, LOG_DEBUG, "permanently closing session of user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
if (vhost->perm_config.acct.amod != NULL && vhost->perm_config.acct.amod->close_session != NULL && e->session_is_open != 0) {
vhost->perm_config.acct.amod->close_session(e->vhost_acct_ctx, e->auth_type, &e->acct_info, &e->saved_stats, e->discon_reason);
seclog(sec, LOG_DEBUG,
"permanently closing session of user '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
if (vhost->perm_config.acct.amod != NULL &&
vhost->perm_config.acct.amod->close_session != NULL &&
e->session_is_open != 0) {
vhost->perm_config.acct.amod->close_session(
e->vhost_acct_ctx, e->auth_type, &e->acct_info,
&e->saved_stats, e->discon_reason);
}
if (e->auth_ctx != NULL) {

View File

@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_SEC_MOD_AUTH_H
# define OC_SEC_MOD_AUTH_H
#define OC_SEC_MOD_AUTH_H
#include <main.h>
#include <sec-mod.h>
@@ -28,26 +28,30 @@
typedef struct passwd_msg_st {
char *msg_str;
unsigned counter;
unsigned int counter;
} passwd_msg_st;
typedef struct auth_mod_st {
unsigned int type;
unsigned int allows_retries; /* whether the module allows retries of the same password */
void (*vhost_init)(void **vctx, void *pool, void* additional);
unsigned int
allows_retries; /* whether the module allows retries of the same password */
void (*vhost_init)(void **vctx, void *pool, void *additional);
void (*vhost_deinit)(void *vctx);
int (*auth_init)(void **ctx, void *pool, void *vctx, const common_auth_init_st *);
int (*auth_msg)(void* ctx, void *pool, passwd_msg_st *);
int (*auth_pass)(void* ctx, const char* pass, unsigned pass_len);
int (*auth_group)(void* ctx, const char *suggested, char *groupname, int groupname_size);
int (*auth_user)(void* ctx, char *groupname, int groupname_size);
int (*auth_init)(void **ctx, void *pool, void *vctx,
const common_auth_init_st *);
int (*auth_msg)(void *ctx, void *pool, passwd_msg_st *);
int (*auth_pass)(void *ctx, const char *pass, unsigned int pass_len);
int (*auth_group)(void *ctx, const char *suggested, char *groupname,
int groupname_size);
int (*auth_user)(void *ctx, char *groupname, int groupname_size);
void (*auth_deinit)(void* ctx);
void (*group_list)(void *pool, void *additional, char ***groupname, unsigned *groupname_size);
void (*auth_deinit)(void *ctx);
void (*group_list)(void *pool, void *additional, char ***groupname,
unsigned int *groupname_size);
} auth_mod_st;
void main_auth_init(main_server_st *s);
void proc_auth_deinit(main_server_st* s, struct proc_st* proc);
void proc_auth_deinit(main_server_st *s, struct proc_st *proc);
/* The authentication with the worker thread is shown in ipc.proto.
*/

View File

@@ -32,11 +32,13 @@ static void send_empty_reply(void *pool, int fd, sec_mod_st *sec)
SecmListCookiesReplyMsg msg = SECM_LIST_COOKIES_REPLY_MSG__INIT;
int ret;
ret = send_msg(pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
(pack_size_func) secm_list_cookies_reply_msg__get_packed_size,
(pack_func) secm_list_cookies_reply_msg__pack);
ret = send_msg(
pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
(pack_size_func)secm_list_cookies_reply_msg__get_packed_size,
(pack_func)secm_list_cookies_reply_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR, "Error sending empty show cookies reply to main");
seclog(sec, LOG_ERR,
"Error sending empty show cookies reply to main");
}
}
@@ -57,13 +59,13 @@ void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
seclog(sec, LOG_DEBUG, "sending list cookies reply to main");
msg.cookies = talloc_size(pool, sizeof(CookieIntMsg*)*db->elems);
msg.cookies = talloc_size(pool, sizeof(CookieIntMsg *) * db->elems);
if (msg.cookies == NULL) {
send_empty_reply(pool, fd, sec);
return;
}
cookies = talloc_size(pool, sizeof(CookieIntMsg)*db->elems);
cookies = talloc_size(pool, sizeof(CookieIntMsg) * db->elems);
if (cookies == NULL) {
send_empty_reply(pool, fd, sec);
return;
@@ -71,15 +73,17 @@ void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
t = htable_first(db, &iter);
while (t != NULL) {
if IS_CLIENT_ENTRY_EXPIRED(sec, t, now)
if IS_CLIENT_ENTRY_EXPIRED (sec, t, now)
goto cont;
if (msg.n_cookies >= db->elems)
break;
cookie_int_msg__init(&cookies[msg.n_cookies]);
cookies[msg.n_cookies].safe_id.data = (void*)t->acct_info.safe_id;
cookies[msg.n_cookies].safe_id.len = sizeof(t->acct_info.safe_id);
cookies[msg.n_cookies].safe_id.data =
(void *)t->acct_info.safe_id;
cookies[msg.n_cookies].safe_id.len =
sizeof(t->acct_info.safe_id);
cookies[msg.n_cookies].session_is_open = t->session_is_open;
cookies[msg.n_cookies].tls_auth_ok = t->tls_auth_ok;
@@ -105,15 +109,17 @@ void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
msg.cookies[msg.n_cookies] = &cookies[msg.n_cookies];
msg.n_cookies++;
cont:
cont:
t = htable_next(db, &iter);
}
ret = send_msg(pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
(pack_size_func) secm_list_cookies_reply_msg__get_packed_size,
(pack_func) secm_list_cookies_reply_msg__pack);
ret = send_msg(
pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
(pack_size_func)secm_list_cookies_reply_msg__get_packed_size,
(pack_func)secm_list_cookies_reply_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR, "Error sending show cookies reply to main");
seclog(sec, LOG_ERR,
"Error sending show cookies reply to main");
}
talloc_free(msg.cookies);

View File

@@ -57,6 +57,7 @@ static size_t rehash(const void *_e, void *unused)
void *sec_mod_client_db_init(sec_mod_st *sec)
{
struct htable *db = talloc(sec, struct htable);
if (db == NULL)
return NULL;
@@ -68,16 +69,16 @@ void *sec_mod_client_db_init(sec_mod_st *sec)
void sec_mod_client_db_deinit(sec_mod_st *sec)
{
struct htable *db = sec->client_db;
struct htable *db = sec->client_db;
htable_clear(db);
talloc_free(db);
}
/* The number of elements */
unsigned sec_mod_client_db_elems(sec_mod_st *sec)
unsigned int sec_mod_client_db_elems(sec_mod_st *sec)
{
struct htable *db = sec->client_db;
struct htable *db = sec->client_db;
if (db)
return db->elems;
@@ -85,7 +86,8 @@ struct htable *db = sec->client_db;
return 0;
}
client_entry_st *new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *vhost, const char *ip, unsigned pid)
client_entry_st *new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *vhost,
const char *ip, unsigned int pid)
{
struct htable *db = sec->client_db;
client_entry_st *e, *te;
@@ -99,7 +101,8 @@ client_entry_st *new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *vhost, c
}
if (ip)
strlcpy(e->acct_info.remote_ip, ip, sizeof(e->acct_info.remote_ip));
strlcpy(e->acct_info.remote_ip, ip,
sizeof(e->acct_info.remote_ip));
e->acct_info.id = pid;
e->vhost = vhost;
@@ -111,21 +114,23 @@ client_entry_st *new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *vhost, c
}
e->sid[0] = sec->sec_mod_instance_id;
seclog(sec, LOG_INFO, "sec-mod instance %d issue cookie", sec->sec_mod_instance_id);
seclog(sec, LOG_INFO, "sec-mod instance %d issue cookie",
sec->sec_mod_instance_id);
/* check if in use */
te = find_client_entry(sec, e->sid);
} while (te != NULL && retries-- >= 0);
if (te != NULL) {
seclog(sec, LOG_ERR,
"could not generate a unique SID!");
seclog(sec, LOG_ERR, "could not generate a unique SID!");
goto fail;
}
calc_safe_id(e->sid, SID_SIZE, (char *)e->acct_info.safe_id, sizeof(e->acct_info.safe_id));
calc_safe_id(e->sid, SID_SIZE, (char *)e->acct_info.safe_id,
sizeof(e->acct_info.safe_id));
now = time(NULL);
e->exptime = now + vhost->perm_config.config->cookie_timeout + AUTH_SLACK_TIME;
e->exptime = now + vhost->perm_config.config->cookie_timeout +
AUTH_SLACK_TIME;
e->created = now;
if (htable_add(db, rehash(e, NULL), e) == 0) {
@@ -136,7 +141,7 @@ client_entry_st *new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *vhost, c
return e;
fail:
fail:
talloc_free(e);
return NULL;
}
@@ -161,7 +166,7 @@ client_entry_st *find_client_entry(sec_mod_st *sec, uint8_t sid[SID_SIZE])
return htable_get(db, rehash(&t, NULL), client_entry_cmp, &t);
}
static void clean_entry(sec_mod_st *sec, client_entry_st * e)
static void clean_entry(sec_mod_st *sec, client_entry_st *e)
{
sec_auth_user_deinit(sec, e);
talloc_free(e->msg_str);
@@ -177,16 +182,15 @@ void cleanup_client_entries(sec_mod_st *sec)
t = htable_first(db, &iter);
while (t != NULL) {
if IS_CLIENT_ENTRY_EXPIRED_FULL(sec, t, now, 1) {
if IS_CLIENT_ENTRY_EXPIRED_FULL (sec, t, now, 1) {
htable_delval(db, &iter);
clean_entry(sec, t);
}
t = htable_next(db, &iter);
}
}
void del_client_entry(sec_mod_st *sec, client_entry_st * e)
void del_client_entry(sec_mod_st *sec, client_entry_st *e)
{
struct htable *db = sec->client_db;
@@ -194,16 +198,20 @@ void del_client_entry(sec_mod_st *sec, client_entry_st * e)
clean_entry(sec, e);
}
void expire_client_entry(sec_mod_st *sec, client_entry_st * e)
void expire_client_entry(sec_mod_st *sec, client_entry_st *e)
{
time_t now;
if (e->in_use > 0)
e->in_use--;
if (e->in_use == 0) {
if (e->vhost->perm_config.config->persistent_cookies == 0 && (e->discon_reason == REASON_SERVER_DISCONNECT ||
e->discon_reason == REASON_SESSION_TIMEOUT || (e->session_is_open && e->discon_reason == REASON_USER_DISCONNECT))) {
seclog(sec, LOG_INFO, "invalidating session of user '%s' "SESSION_STR,
if (e->vhost->perm_config.config->persistent_cookies == 0 &&
(e->discon_reason == REASON_SERVER_DISCONNECT ||
e->discon_reason == REASON_SESSION_TIMEOUT ||
(e->session_is_open &&
e->discon_reason == REASON_USER_DISCONNECT))) {
seclog(sec, LOG_INFO,
"invalidating session of user '%s' " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
/* immediately disconnect the user */
del_client_entry(sec, e);
@@ -214,12 +222,19 @@ void expire_client_entry(sec_mod_st *sec, client_entry_st * e)
* explicitly disconnect with the intention to reconnect
* seconds later. */
if (e->discon_reason == REASON_USER_DISCONNECT) {
if (!e->vhost->perm_config.config->persistent_cookies || (now+AUTH_SLACK_TIME >= e->exptime))
if (!e->vhost->perm_config.config
->persistent_cookies ||
(now + AUTH_SLACK_TIME >= e->exptime))
e->exptime = now + AUTH_SLACK_TIME;
} else {
e->exptime = now + e->vhost->perm_config.config->cookie_timeout + AUTH_SLACK_TIME;
e->exptime = now +
e->vhost->perm_config.config
->cookie_timeout +
AUTH_SLACK_TIME;
}
seclog(sec, LOG_INFO, "temporarily closing session for %s "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
seclog(sec, LOG_INFO,
"temporarily closing session for %s " SESSION_STR,
e->acct_info.username, e->acct_info.safe_id);
}
}
}

View File

@@ -39,8 +39,7 @@
#include <ip-util.h>
#include <tlslib.h>
int handle_resume_delete_req(sec_mod_st *sec,
const SessionResumeFetchMsg *req)
int handle_resume_delete_req(sec_mod_st *sec, const SessionResumeFetchMsg *req)
{
tls_cache_st *cache;
struct htable_iter iter;
@@ -53,7 +52,6 @@ int handle_resume_delete_req(sec_mod_st *sec,
if (req->session_id.len == cache->session_id_size &&
memcmp(req->session_id.data, cache->session_id,
req->session_id.len) == 0) {
cache->session_data_size = 0;
cache->session_id_size = 0;
@@ -69,8 +67,7 @@ int handle_resume_delete_req(sec_mod_st *sec,
return 0;
}
int handle_resume_fetch_req(sec_mod_st *sec,
const SessionResumeFetchMsg *req,
int handle_resume_fetch_req(sec_mod_st *sec, const SessionResumeFetchMsg *req,
SessionResumeReplyMsg *rep)
{
tls_cache_st *cache;
@@ -86,28 +83,29 @@ int handle_resume_fetch_req(sec_mod_st *sec,
if (req->session_id.len == cache->session_id_size &&
memcmp(req->session_id.data, cache->session_id,
req->session_id.len) == 0) {
if (req->vhost && cache->vhostname && strcasecmp(req->vhost, cache->vhostname) != 0)
if (req->vhost && cache->vhostname &&
strcasecmp(req->vhost, cache->vhostname) != 0)
return 0;
else if (req->vhost != cache->vhostname)
return 0;
if (req->cli_addr.len == cache->remote_addr_len &&
ip_cmp((struct sockaddr_storage *)req->cli_addr.data, &cache->remote_addr) == 0) {
ip_cmp((struct sockaddr_storage *)req->cli_addr.data,
&cache->remote_addr) == 0) {
rep->reply =
SESSION_RESUME_REPLY_MSG__RESUME__REP__OK;
SESSION_RESUME_REPLY_MSG__RESUME__REP__OK;
rep->has_session_data = 1;
rep->session_data.data =
(void *)cache->session_data;
(void *)cache->session_data;
rep->session_data.len =
cache->session_data_size;
cache->session_data_size;
seclog_hex(sec, LOG_DEBUG, "TLS session DB resuming",
req->session_id.data,
req->session_id.len, 0);
seclog_hex(sec, LOG_DEBUG,
"TLS session DB resuming",
req->session_id.data,
req->session_id.len, 0);
return 0;
}
@@ -117,7 +115,6 @@ int handle_resume_fetch_req(sec_mod_st *sec,
}
return 0;
}
int handle_resume_store_req(sec_mod_st *sec,
@@ -132,17 +129,17 @@ int handle_resume_store_req(sec_mod_st *sec,
if (req->session_data.len > MAX_SESSION_DATA_SIZE)
return -1;
max = MAX(2 * GETCONFIG(sec)->max_clients, DEFAULT_MAX_CACHED_TLS_SESSIONS);
max = MAX(2 * GETCONFIG(sec)->max_clients,
DEFAULT_MAX_CACHED_TLS_SESSIONS);
if (sec->tls_db.entries >= max) {
seclog(sec, LOG_INFO,
"maximum number of stored TLS sessions reached (%u)",
max);
"maximum number of stored TLS sessions reached (%u)",
max);
return -1;
}
if (req->cli_addr.len == 0) {
seclog(sec, LOG_INFO,
"invalid address length");
seclog(sec, LOG_INFO, "invalid address length");
return -1;
}
@@ -167,14 +164,13 @@ int handle_resume_store_req(sec_mod_st *sec,
if (htable_add(sec->tls_db.ht, key, cache) == 0) {
seclog(sec, LOG_INFO,
"could not add TLS session to hash table");
"could not add TLS session to hash table");
talloc_free(cache);
} else {
sec->tls_db.entries++;
seclog_hex(sec, LOG_DEBUG, "TLS session DB storing",
req->session_id.data,
req->session_id.len, 0);
req->session_id.data, req->session_id.len, 0);
}
return 0;
@@ -202,7 +198,8 @@ void expire_tls_sessions(sec_mod_st *sec)
htable_delval(sec->tls_db.ht, &iter);
safe_memset(cache->session_data, 0, cache->session_data_size);
safe_memset(cache->session_data, 0,
cache->session_data_size);
talloc_free(cache);
sec->tls_db.entries--;
}

View File

@@ -19,19 +19,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_SEC_MOD_RESUME_H
# define OC_SEC_MOD_RESUME_H
#define OC_SEC_MOD_RESUME_H
#include <sec-mod.h>
int handle_resume_delete_req(sec_mod_st* sec,
const SessionResumeFetchMsg * req);
int handle_resume_delete_req(sec_mod_st *sec, const SessionResumeFetchMsg *req);
int handle_resume_fetch_req(sec_mod_st* sec,
const SessionResumeFetchMsg * req,
SessionResumeReplyMsg* rep);
int handle_resume_fetch_req(sec_mod_st *sec, const SessionResumeFetchMsg *req,
SessionResumeReplyMsg *rep);
int handle_resume_store_req(sec_mod_st* sec,
const SessionResumeStoreReqMsg *);
int handle_resume_store_req(sec_mod_st *sec, const SessionResumeStoreReqMsg *);
void expire_tls_sessions(sec_mod_st *sec);

View File

@@ -34,13 +34,19 @@ void sup_config_init(sec_mod_st *sec)
{
vhost_cfg_st *vhost = NULL;
list_for_each(sec->vconfig, vhost, list) {
list_for_each(sec->vconfig, vhost, list)
{
if (vhost->perm_config.sup_config_type == SUP_CONFIG_FILE) {
seclog(sec, LOG_INFO, "%sreading supplemental config from files", PREFIX_VHOST(vhost));
seclog(sec, LOG_INFO,
"%sreading supplemental config from files",
PREFIX_VHOST(vhost));
vhost->config_module = &file_sup_config;
#ifdef HAVE_RADIUS
} else if (vhost->perm_config.sup_config_type == SUP_CONFIG_RADIUS) {
seclog(sec, LOG_INFO, "%sreading supplemental config from radius", PREFIX_VHOST(vhost));
} else if (vhost->perm_config.sup_config_type ==
SUP_CONFIG_RADIUS) {
seclog(sec, LOG_INFO,
"%sreading supplemental config from radius",
PREFIX_VHOST(vhost));
vhost->config_module = &radius_sup_config;
#endif
}

View File

@@ -19,15 +19,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_SEC_MOD_SUP_CONFIG_H
# define OC_SEC_MOD_SUP_CONFIG_H
#define OC_SEC_MOD_SUP_CONFIG_H
#include <sec-mod.h>
#define SUP_CONFIG_FILE 1
#define SUP_CONFIG_RADIUS 2
inline static
const char *sup_config_name(unsigned s)
inline static const char *sup_config_name(unsigned int s)
{
switch (s) {
case SUP_CONFIG_FILE:
@@ -43,8 +42,9 @@ const char *sup_config_name(unsigned s)
* proc->username/proc->groupname and save it in proc->config.
*/
struct config_mod_st {
int (*get_sup_config)(struct cfg_st *perm_config, client_entry_st *entry,
SecmSessionReplyMsg *msg, void *pool);
int (*get_sup_config)(struct cfg_st *perm_config,
client_entry_st *entry, SecmSessionReplyMsg *msg,
void *pool);
};
void sup_config_init(sec_mod_st *sec);

View File

@@ -51,41 +51,41 @@
#define MAINTAINANCE_TIME 310
static int need_maintainance = 0;
static int need_reload = 0;
static int need_exit = 0;
static int need_maintainance;
static int need_reload;
static int need_exit;
static void reload_server(sec_mod_st *sec);
static int load_keys(sec_mod_st *sec, unsigned force);
static int load_keys(sec_mod_st *sec, unsigned int force);
static
int pin_callback(void *user, int attempt, const char *token_url,
const char *token_label, unsigned int flags, char *pin,
size_t pin_max)
static int pin_callback(void *user, int attempt, const char *token_url,
const char *token_label, unsigned int flags, char *pin,
size_t pin_max)
{
struct pin_st *ps = user;
int srk = 0;
const char *p;
unsigned len;
unsigned int len;
if (flags & GNUTLS_PIN_FINAL_TRY) {
oc_syslog(LOG_ERR,
"PIN callback: final try before locking; not attempting to unlock");
oc_syslog(
LOG_ERR,
"PIN callback: final try before locking; not attempting to unlock");
return -1;
}
if (flags & GNUTLS_PIN_WRONG) {
oc_syslog(LOG_ERR,
"PIN callback: wrong PIN was entered for '%s' (%s)",
token_label, token_url);
"PIN callback: wrong PIN was entered for '%s' (%s)",
token_label, token_url);
return -1;
}
if (ps->pin[0] == 0) {
oc_syslog(LOG_ERR,
"PIN required for '%s' but pin-file was not set",
token_label);
"PIN required for '%s' but pin-file was not set",
token_label);
return -1;
}
@@ -98,8 +98,8 @@ int pin_callback(void *user, int attempt, const char *token_url,
if (srk != 0 && ps->srk_pin[0] == 0) {
oc_syslog(LOG_ERR,
"PIN required for '%s' but srk-pin-file was not set",
token_label);
"PIN required for '%s' but srk-pin-file was not set",
token_label);
return -1;
}
@@ -115,8 +115,7 @@ int pin_callback(void *user, int attempt, const char *token_url,
return 0;
}
static
int load_pins(struct perm_cfg_st *config, struct pin_st *s)
static int load_pins(struct perm_cfg_st *config, struct pin_st *s)
{
int fd, ret;
@@ -127,7 +126,7 @@ int load_pins(struct perm_cfg_st *config, struct pin_st *s)
fd = open(config->srk_pin_file, O_RDONLY);
if (fd < 0) {
oc_syslog(LOG_ERR, "could not open SRK PIN file '%s'",
config->srk_pin_file);
config->srk_pin_file);
return -1;
}
@@ -135,7 +134,7 @@ int load_pins(struct perm_cfg_st *config, struct pin_st *s)
close(fd);
if (ret <= 1) {
oc_syslog(LOG_ERR, "could not read from PIN file '%s'",
config->srk_pin_file);
config->srk_pin_file);
return -1;
}
@@ -148,7 +147,7 @@ int load_pins(struct perm_cfg_st *config, struct pin_st *s)
fd = open(config->pin_file, O_RDONLY);
if (fd < 0) {
oc_syslog(LOG_ERR, "could not open PIN file '%s'",
config->pin_file);
config->pin_file);
return -1;
}
@@ -156,7 +155,7 @@ int load_pins(struct perm_cfg_st *config, struct pin_st *s)
close(fd);
if (ret <= 1) {
oc_syslog(LOG_ERR, "could not read from PIN file '%s'",
config->pin_file);
config->pin_file);
return -1;
}
@@ -176,8 +175,8 @@ int load_pins(struct perm_cfg_st *config, struct pin_st *s)
return 0;
}
static int handle_op(void *pool, int cfd, sec_mod_st * sec, uint8_t type, uint8_t * rep,
size_t rep_size)
static int handle_op(void *pool, int cfd, sec_mod_st *sec, uint8_t type,
uint8_t *rep, size_t rep_size)
{
SecOpMsg msg = SEC_OP_MSG__INIT;
int ret;
@@ -186,8 +185,8 @@ static int handle_op(void *pool, int cfd, sec_mod_st * sec, uint8_t type, uint8_
msg.data.len = rep_size;
ret = send_msg(pool, cfd, type, &msg,
(pack_size_func) sec_op_msg__get_packed_size,
(pack_func) sec_op_msg__pack);
(pack_size_func)sec_op_msg__get_packed_size,
(pack_func)sec_op_msg__pack);
if (ret < 0) {
seclog(sec, LOG_WARNING, "sec-mod error in sending reply");
}
@@ -195,17 +194,17 @@ static int handle_op(void *pool, int cfd, sec_mod_st * sec, uint8_t type, uint8_
return 0;
}
static
int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_request_t cmd,
uint8_t * buffer, size_t buffer_size)
static int process_worker_packet(void *pool, int cfd, pid_t pid,
sec_mod_st *sec, cmd_request_t cmd,
uint8_t *buffer, size_t buffer_size)
{
unsigned i;
unsigned int i;
gnutls_datum_t data, out;
int ret;
SecOpMsg *op;
vhost_cfg_st *vhost;
#if GNUTLS_VERSION_NUMBER >= 0x030600
unsigned bits;
unsigned int bits;
SecGetPkMsg *pkm;
#endif
PROTOBUF_ALLOCATOR(pa, pool);
@@ -231,7 +230,8 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
i = pkm->key_idx;
if (i >= vhost->key_size) {
seclog(sec, LOG_INFO,
"%sreceived out-of-bounds key index (%d); have %d keys", PREFIX_VHOST(vhost), i, vhost->key_size);
"%sreceived out-of-bounds key index (%d); have %d keys",
PREFIX_VHOST(vhost), i, vhost->key_size);
return -1;
}
@@ -239,8 +239,8 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
pkm->bits = bits;
ret = send_msg(pool, cfd, CMD_SEC_GET_PK, pkm,
(pack_size_func) sec_get_pk_msg__get_packed_size,
(pack_func) sec_get_pk_msg__pack);
(pack_size_func)sec_get_pk_msg__get_packed_size,
(pack_func)sec_get_pk_msg__pack);
sec_get_pk_msg__free_unpacked(pkm, &pa);
@@ -266,7 +266,8 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
i = op->key_idx;
if (op->has_key_idx == 0 || i >= vhost->key_size) {
seclog(sec, LOG_INFO,
"%sreceived out-of-bounds key index (%d); have %d keys", PREFIX_VHOST(vhost), i, vhost->key_size);
"%sreceived out-of-bounds key index (%d); have %d keys",
PREFIX_VHOST(vhost), i, vhost->key_size);
return -1;
}
@@ -274,9 +275,11 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
data.size = op->data.len;
if (cmd == CMD_SEC_SIGN_DATA) {
ret = gnutls_privkey_sign_data2(vhost->key[i], op->sig, 0, &data, &out);
ret = gnutls_privkey_sign_data2(vhost->key[i], op->sig,
0, &data, &out);
} else {
ret = gnutls_privkey_sign_hash2(vhost->key[i], op->sig, 0, &data, &out);
ret = gnutls_privkey_sign_hash2(vhost->key[i], op->sig,
0, &data, &out);
}
sec_op_msg__free_unpacked(op, &pa);
@@ -305,7 +308,8 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
i = op->key_idx;
if (op->has_key_idx == 0 || i >= vhost->key_size) {
seclog(sec, LOG_INFO,
"%sreceived out-of-bounds key index (%d); have %d keys", PREFIX_VHOST(vhost), i, vhost->key_size);
"%sreceived out-of-bounds key index (%d); have %d keys",
PREFIX_VHOST(vhost), i, vhost->key_size);
return -1;
}
@@ -313,14 +317,12 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
data.size = op->data.len;
if (cmd == CMD_SEC_DECRYPT) {
ret =
gnutls_privkey_decrypt_data(vhost->key[i], 0, &data,
&out);
ret = gnutls_privkey_decrypt_data(vhost->key[i], 0,
&data, &out);
} else {
ret =
gnutls_privkey_sign_hash(vhost->key[i], 0,
GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
&data, &out);
ret = gnutls_privkey_sign_hash(
vhost->key[i], 0,
GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, &data, &out);
}
sec_op_msg__free_unpacked(op, &pa);
@@ -335,144 +337,134 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
return ret;
case CMD_SEC_CLI_STATS:{
CliStatsMsg *tmsg;
case CMD_SEC_CLI_STATS: {
CliStatsMsg *tmsg;
tmsg = cli_stats_msg__unpack(&pa, data.size, data.data);
if (tmsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return -1;
}
ret = handle_sec_auth_stats_cmd(sec, tmsg, pid);
cli_stats_msg__free_unpacked(tmsg, &pa);
return ret;
}
break;
case CMD_SEC_AUTH_INIT:{
SecAuthInitMsg *auth_init;
auth_init =
sec_auth_init_msg__unpack(&pa, data.size,
data.data);
if (auth_init == NULL) {
seclog(sec, LOG_INFO, "error unpacking auth init\n");
return -1;
}
ret = handle_sec_auth_init(cfd, sec, auth_init, pid);
sec_auth_init_msg__free_unpacked(auth_init, &pa);
return ret;
}
case CMD_SEC_AUTH_CONT:{
SecAuthContMsg *auth_cont;
auth_cont =
sec_auth_cont_msg__unpack(&pa, data.size,
data.data);
if (auth_cont == NULL) {
seclog(sec, LOG_INFO, "error unpacking auth cont\n");
return -1;
}
ret = handle_sec_auth_cont(cfd, sec, auth_cont);
sec_auth_cont_msg__free_unpacked(auth_cont, &pa);
return ret;
}
case RESUME_STORE_REQ:{
SessionResumeStoreReqMsg *smsg;
smsg =
session_resume_store_req_msg__unpack(&pa, buffer_size,
buffer);
if (smsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return ERR_BAD_COMMAND;
}
ret = handle_resume_store_req(sec, smsg);
/* zeroize the data */
safe_memset(buffer, 0, buffer_size);
safe_memset(smsg->session_data.data, 0, smsg->session_data.len);
session_resume_store_req_msg__free_unpacked(smsg, &pa);
if (ret < 0) {
seclog(sec, LOG_DEBUG,
"could not store resumption data");
}
tmsg = cli_stats_msg__unpack(&pa, data.size, data.data);
if (tmsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return -1;
}
break;
ret = handle_sec_auth_stats_cmd(sec, tmsg, pid);
cli_stats_msg__free_unpacked(tmsg, &pa);
return ret;
} break;
case RESUME_DELETE_REQ:{
SessionResumeFetchMsg *fmsg;
case CMD_SEC_AUTH_INIT: {
SecAuthInitMsg *auth_init;
fmsg =
session_resume_fetch_msg__unpack(&pa, buffer_size,
buffer);
if (fmsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return ERR_BAD_COMMAND;
}
ret = handle_resume_delete_req(sec, fmsg);
session_resume_fetch_msg__free_unpacked(fmsg, &pa);
if (ret < 0) {
seclog(sec, LOG_DEBUG,
"could not delete resumption data.");
}
auth_init =
sec_auth_init_msg__unpack(&pa, data.size, data.data);
if (auth_init == NULL) {
seclog(sec, LOG_INFO, "error unpacking auth init\n");
return -1;
}
break;
case RESUME_FETCH_REQ:{
SessionResumeReplyMsg msg =
SESSION_RESUME_REPLY_MSG__INIT;
SessionResumeFetchMsg *fmsg;
fmsg =
session_resume_fetch_msg__unpack(&pa, buffer_size,
buffer);
if (fmsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return ERR_BAD_COMMAND;
}
ret = handle_resume_fetch_req(sec, fmsg, &msg);
session_resume_fetch_msg__free_unpacked(fmsg, &pa);
if (ret < 0) {
msg.reply =
SESSION_RESUME_REPLY_MSG__RESUME__REP__FAILED;
seclog(sec, LOG_DEBUG,
"could not fetch resumption data.");
} else {
msg.reply =
SESSION_RESUME_REPLY_MSG__RESUME__REP__OK;
}
ret =
send_msg(pool, cfd, RESUME_FETCH_REP, &msg,
(pack_size_func)
session_resume_reply_msg__get_packed_size,
(pack_func)
session_resume_reply_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR,
"could not send reply cmd %d.",
(unsigned)cmd);
return ERR_BAD_COMMAND;
}
ret = handle_sec_auth_init(cfd, sec, auth_init, pid);
sec_auth_init_msg__free_unpacked(auth_init, &pa);
return ret;
}
case CMD_SEC_AUTH_CONT: {
SecAuthContMsg *auth_cont;
auth_cont =
sec_auth_cont_msg__unpack(&pa, data.size, data.data);
if (auth_cont == NULL) {
seclog(sec, LOG_INFO, "error unpacking auth cont\n");
return -1;
}
break;
ret = handle_sec_auth_cont(cfd, sec, auth_cont);
sec_auth_cont_msg__free_unpacked(auth_cont, &pa);
return ret;
}
case RESUME_STORE_REQ: {
SessionResumeStoreReqMsg *smsg;
smsg = session_resume_store_req_msg__unpack(&pa, buffer_size,
buffer);
if (smsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return ERR_BAD_COMMAND;
}
ret = handle_resume_store_req(sec, smsg);
/* zeroize the data */
safe_memset(buffer, 0, buffer_size);
safe_memset(smsg->session_data.data, 0, smsg->session_data.len);
session_resume_store_req_msg__free_unpacked(smsg, &pa);
if (ret < 0) {
seclog(sec, LOG_DEBUG,
"could not store resumption data");
}
}
break;
case RESUME_DELETE_REQ: {
SessionResumeFetchMsg *fmsg;
fmsg = session_resume_fetch_msg__unpack(&pa, buffer_size,
buffer);
if (fmsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return ERR_BAD_COMMAND;
}
ret = handle_resume_delete_req(sec, fmsg);
session_resume_fetch_msg__free_unpacked(fmsg, &pa);
if (ret < 0) {
seclog(sec, LOG_DEBUG,
"could not delete resumption data.");
}
}
break;
case RESUME_FETCH_REQ: {
SessionResumeReplyMsg msg = SESSION_RESUME_REPLY_MSG__INIT;
SessionResumeFetchMsg *fmsg;
fmsg = session_resume_fetch_msg__unpack(&pa, buffer_size,
buffer);
if (fmsg == NULL) {
seclog(sec, LOG_ERR, "error unpacking data");
return ERR_BAD_COMMAND;
}
ret = handle_resume_fetch_req(sec, fmsg, &msg);
session_resume_fetch_msg__free_unpacked(fmsg, &pa);
if (ret < 0) {
msg.reply =
SESSION_RESUME_REPLY_MSG__RESUME__REP__FAILED;
seclog(sec, LOG_DEBUG,
"could not fetch resumption data.");
} else {
msg.reply = SESSION_RESUME_REPLY_MSG__RESUME__REP__OK;
}
ret = send_msg(
pool, cfd, RESUME_FETCH_REP, &msg,
(pack_size_func)
session_resume_reply_msg__get_packed_size,
(pack_func)session_resume_reply_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR, "could not send reply cmd %d.",
(unsigned int)cmd);
return ERR_BAD_COMMAND;
}
}
break;
default:
seclog(sec, LOG_WARNING, "unknown type 0x%.2x", cmd);
@@ -482,12 +474,13 @@ int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st *sec, cmd_r
return 0;
}
static
int process_packet_from_main(void *pool, int fd, sec_mod_st * sec, cmd_request_t cmd,
uint8_t * buffer, size_t buffer_size)
static int process_packet_from_main(void *pool, int fd, sec_mod_st *sec,
cmd_request_t cmd, uint8_t *buffer,
size_t buffer_size)
{
gnutls_datum_t data;
int ret;
PROTOBUF_ALLOCATOR(pa, pool);
seclog(sec, LOG_DEBUG, "cmd [size=%d] %s\n", (int)buffer_size,
@@ -499,10 +492,11 @@ int process_packet_from_main(void *pool, int fd, sec_mod_st * sec, cmd_request_t
case CMD_SECM_RELOAD:
reload_server(sec);
ret = send_msg(pool, fd, CMD_SECM_RELOAD_REPLY, NULL,
NULL, NULL);
ret = send_msg(pool, fd, CMD_SECM_RELOAD_REPLY, NULL, NULL,
NULL);
if (ret < 0) {
seclog(sec, LOG_ERR, "could not send reload reply to main!\n");
seclog(sec, LOG_ERR,
"could not send reload reply to main!\n");
return ERR_BAD_COMMAND;
}
break;
@@ -510,14 +504,13 @@ int process_packet_from_main(void *pool, int fd, sec_mod_st * sec, cmd_request_t
handle_secm_list_cookies_reply(pool, fd, sec);
return 0;
case CMD_SECM_BAN_IP_REPLY:{
case CMD_SECM_BAN_IP_REPLY: {
BanIpReplyMsg *msg = NULL;
msg =
ban_ip_reply_msg__unpack(&pa, data.size,
data.data);
msg = ban_ip_reply_msg__unpack(&pa, data.size, data.data);
if (msg == NULL) {
seclog(sec, LOG_INFO, "error unpacking auth ban ip reply\n");
seclog(sec, LOG_INFO,
"error unpacking auth ban ip reply\n");
return ERR_BAD_COMMAND;
}
@@ -526,38 +519,35 @@ int process_packet_from_main(void *pool, int fd, sec_mod_st * sec, cmd_request_t
return 0;
}
case CMD_SECM_SESSION_OPEN:{
SecmSessionOpenMsg *msg;
case CMD_SECM_SESSION_OPEN: {
SecmSessionOpenMsg *msg;
msg =
secm_session_open_msg__unpack(&pa, data.size,
data.data);
if (msg == NULL) {
seclog(sec, LOG_INFO, "error unpacking session open\n");
return ERR_BAD_COMMAND;
}
ret = handle_secm_session_open_cmd(sec, fd, msg);
secm_session_open_msg__free_unpacked(msg, &pa);
return ret;
msg = secm_session_open_msg__unpack(&pa, data.size, data.data);
if (msg == NULL) {
seclog(sec, LOG_INFO, "error unpacking session open\n");
return ERR_BAD_COMMAND;
}
case CMD_SECM_SESSION_CLOSE:{
SecmSessionCloseMsg *msg;
msg =
secm_session_close_msg__unpack(&pa, data.size,
data.data);
if (msg == NULL) {
seclog(sec, LOG_INFO, "error unpacking session close\n");
return ERR_BAD_COMMAND;
}
ret = handle_secm_session_open_cmd(sec, fd, msg);
secm_session_open_msg__free_unpacked(msg, &pa);
ret = handle_secm_session_close_cmd(sec, fd, msg);
secm_session_close_msg__free_unpacked(msg, &pa);
return ret;
}
case CMD_SECM_SESSION_CLOSE: {
SecmSessionCloseMsg *msg;
return ret;
msg = secm_session_close_msg__unpack(&pa, data.size, data.data);
if (msg == NULL) {
seclog(sec, LOG_INFO,
"error unpacking session close\n");
return ERR_BAD_COMMAND;
}
ret = handle_secm_session_close_cmd(sec, fd, msg);
secm_session_close_msg__free_unpacked(msg, &pa);
return ret;
}
default:
seclog(sec, LOG_WARNING, "unknown type 0x%.2x", cmd);
return ERR_BAD_COMMAND;
@@ -603,8 +593,8 @@ static void send_stats_to_main(sec_mod_st *sec)
msg.secmod_tlsdb_entries = sec->tls_db.entries;
ret = send_msg(sec, sec->cmd_fd, CMD_SECM_STATS, &msg,
(pack_size_func) secm_stats_msg__get_packed_size,
(pack_func) secm_stats_msg__pack);
(pack_size_func)secm_stats_msg__get_packed_size,
(pack_func)secm_stats_msg__pack);
if (ret < 0) {
seclog(sec, LOG_ERR, "error in sending statistics to main");
return;
@@ -619,7 +609,8 @@ static void reload_server(sec_mod_st *sec)
reload_cfg_file(sec, sec->vconfig, 1);
load_keys(sec, 0);
list_for_each(sec->vconfig, vhost, list) {
list_for_each(sec->vconfig, vhost, list)
{
sec_auth_init(vhost);
}
sup_config_init(sec);
@@ -632,9 +623,10 @@ static void check_other_work(sec_mod_st *sec)
vhost_cfg_st *vhost = NULL;
if (need_exit) {
unsigned i;
unsigned int i;
list_for_each(sec->vconfig, vhost, list) {
list_for_each(sec->vconfig, vhost, list)
{
for (i = 0; i < vhost->key_size; i++) {
gnutls_privkey_deinit(vhost->key[i]);
vhost->key[i] = NULL;
@@ -659,14 +651,14 @@ static void check_other_work(sec_mod_st *sec)
expire_tls_sessions(sec);
send_stats_to_main(sec);
seclog(sec, LOG_DEBUG, "active sessions %d",
sec_mod_client_db_elems(sec));
sec_mod_client_db_elems(sec));
alarm(MAINTAINANCE_TIME);
need_maintainance = 0;
}
}
static
int serve_request_main(sec_mod_st *sec, int fd, uint8_t *buffer, unsigned buffer_size)
static int serve_request_main(sec_mod_st *sec, int fd, uint8_t *buffer,
unsigned int buffer_size)
{
int ret, e;
uint8_t cmd;
@@ -685,13 +677,15 @@ int serve_request_main(sec_mod_st *sec, int fd, uint8_t *buffer, unsigned buffer
seclog(sec, LOG_DEBUG, "received request %s", cmd_request_to_str(cmd));
if (cmd <= MIN_SECM_CMD || cmd >= MAX_SECM_CMD) {
seclog(sec, LOG_ERR, "received invalid message from main of %u bytes (cmd: %u)\n",
(unsigned)length, (unsigned)cmd);
seclog(sec, LOG_ERR,
"received invalid message from main of %u bytes (cmd: %u)\n",
(unsigned int)length, (unsigned int)cmd);
return ERR_BAD_COMMAND;
}
if (length > buffer_size) {
seclog(sec, LOG_ERR, "received too big message (%d)", (int)length);
seclog(sec, LOG_ERR, "received too big message (%d)",
(int)length);
ret = ERR_BAD_COMMAND;
goto leave;
}
@@ -700,23 +694,26 @@ int serve_request_main(sec_mod_st *sec, int fd, uint8_t *buffer, unsigned buffer
ret = force_read_timeout(fd, buffer, length, MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
e = errno;
seclog(sec, LOG_ERR, "error receiving msg body of cmd %u with length %u: %s",
cmd, (unsigned)length, strerror(e));
seclog(sec, LOG_ERR,
"error receiving msg body of cmd %u with length %u: %s",
cmd, (unsigned int)length, strerror(e));
ret = ERR_BAD_COMMAND;
goto leave;
}
ret = process_packet_from_main(pool, fd, sec, cmd, buffer, ret);
if (ret < 0) {
seclog(sec, LOG_ERR, "error processing data for '%s' command (%d)", cmd_request_to_str(cmd), ret);
seclog(sec, LOG_ERR,
"error processing data for '%s' command (%d)",
cmd_request_to_str(cmd), ret);
}
leave:
leave:
return ret;
}
static
int serve_request_worker(sec_mod_st *sec, int cfd, pid_t pid, uint8_t *buffer, unsigned buffer_size)
static int serve_request_worker(sec_mod_st *sec, int cfd, pid_t pid,
uint8_t *buffer, unsigned int buffer_size)
{
int ret, e;
uint8_t cmd;
@@ -750,24 +747,33 @@ int serve_request_worker(sec_mod_st *sec, int cfd, pid_t pid, uint8_t *buffer, u
ret = process_worker_packet(pool, cfd, pid, sec, cmd, buffer, ret);
if (ret < 0) {
seclog(sec, LOG_DEBUG, "error processing '%s' command (%d)", cmd_request_to_str(cmd), ret);
seclog(sec, LOG_DEBUG, "error processing '%s' command (%d)",
cmd_request_to_str(cmd), ret);
}
leave:
leave:
return ret;
}
#define CHECK_LOOP_ERR(x) { \
if (force != 0) { GNUTLS_FATAL_ERR(x); } \
else { if (ret < 0) { \
seclog(sec, LOG_ERR, "could not reload key %s", vhost->perm_config.key[i]); \
continue; } \
}}
#define CHECK_LOOP_ERR(x) \
{ \
if (force != 0) { \
GNUTLS_FATAL_ERR(x); \
} else { \
if (ret < 0) { \
seclog(sec, LOG_ERR, \
"could not reload key %s", \
vhost->perm_config.key[i]); \
continue; \
} \
} \
}
static void read_private_key(sec_mod_st *sec, vhost_cfg_st *vhost, unsigned force)
static void read_private_key(sec_mod_st *sec, vhost_cfg_st *vhost,
unsigned int force)
{
int ret;
unsigned i;
unsigned int i;
/* read private keys */
for (i = 0; i < vhost->key_size; i++) {
@@ -778,33 +784,33 @@ static void read_private_key(sec_mod_st *sec, vhost_cfg_st *vhost, unsigned forc
/* load the private key */
if (gnutls_url_is_supported(vhost->perm_config.key[i]) != 0) {
gnutls_privkey_set_pin_function(p,
pin_callback, &vhost->pins);
ret =
gnutls_privkey_import_url(p,
vhost->perm_config.key[i], 0);
gnutls_privkey_set_pin_function(p, pin_callback,
&vhost->pins);
ret = gnutls_privkey_import_url(
p, vhost->perm_config.key[i], 0);
CHECK_LOOP_ERR(ret);
} else {
gnutls_datum_t data;
ret = gnutls_load_file(vhost->perm_config.key[i], &data);
ret = gnutls_load_file(vhost->perm_config.key[i],
&data);
if (ret < 0) {
seclog(sec, LOG_ERR, "error loading file '%s'",
vhost->perm_config.key[i]);
CHECK_LOOP_ERR(ret);
}
ret =
gnutls_privkey_import_x509_raw(p, &data,
GNUTLS_X509_FMT_PEM,
NULL, 0);
ret = gnutls_privkey_import_x509_raw(
p, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
/* GnuTLS 3.7.3 introduces a backwards incompatible change and
* GNUTLS_E_PKCS11_PIN_ERROR is returned when an encrypted
* file is loaded https://gitlab.com/gnutls/gnutls/-/issues/1321 */
if ((ret == GNUTLS_E_DECRYPTION_FAILED || ret == GNUTLS_E_PKCS11_PIN_ERROR) && vhost->pins.pin[0]) {
ret =
gnutls_privkey_import_x509_raw(p, &data,
GNUTLS_X509_FMT_PEM,
vhost->pins.pin, 0);
if ((ret == GNUTLS_E_DECRYPTION_FAILED ||
ret == GNUTLS_E_PKCS11_PIN_ERROR) &&
vhost->pins.pin[0]) {
ret = gnutls_privkey_import_x509_raw(
p, &data, GNUTLS_X509_FMT_PEM,
vhost->pins.pin, 0);
}
CHECK_LOOP_ERR(ret);
gnutls_free(data.data);
@@ -815,21 +821,25 @@ static void read_private_key(sec_mod_st *sec, vhost_cfg_st *vhost, unsigned forc
}
vhost->key[i] = p;
}
seclog(sec, LOG_DEBUG, "%sloaded %d keys\n", PREFIX_VHOST(vhost), vhost->key_size);
seclog(sec, LOG_DEBUG, "%sloaded %d keys\n", PREFIX_VHOST(vhost),
vhost->key_size);
}
static int load_keys(sec_mod_st *sec, unsigned force)
static int load_keys(sec_mod_st *sec, unsigned int force)
{
unsigned i, reload_file;
unsigned int i, reload_file;
int ret;
vhost_cfg_st *vhost = NULL;
list_for_each_rev(sec->vconfig, vhost, list) {
list_for_each_rev(sec->vconfig, vhost, list)
{
if (force == 0) {
reload_file = 0;
for (i = 0; i < vhost->perm_config.key_size; i++) {
if (need_file_reload(vhost->perm_config.key[i], vhost->cert_last_access) != 0) {
if (need_file_reload(vhost->perm_config.key[i],
vhost->cert_last_access) !=
0) {
reload_file = 1;
break;
}
@@ -851,9 +861,12 @@ static int load_keys(sec_mod_st *sec, unsigned force)
*/
if (vhost->key == NULL) {
vhost->key_size = vhost->perm_config.key_size;
vhost->key = talloc_zero_size(sec, sizeof(*vhost->key) * vhost->perm_config.key_size);
vhost->key = talloc_zero_size(
sec, sizeof(*vhost->key) *
vhost->perm_config.key_size);
if (vhost->key == NULL) {
seclog(sec, LOG_ERR, "error in memory allocation");
seclog(sec, LOG_ERR,
"error in memory allocation");
exit(EXIT_FAILURE);
}
}
@@ -892,15 +905,15 @@ static int load_keys(sec_mod_st *sec, unsigned force)
* clients fast without becoming a bottleneck due to private
* key operations.
*/
void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfig,
const char *socket_file, int cmd_fd, int cmd_fd_sync,
size_t hmac_key_length, const uint8_t * hmac_key,
const uint8_t instance_id)
void sec_mod_server(void *main_pool, void *config_pool,
struct list_head *vconfig, const char *socket_file,
int cmd_fd, int cmd_fd_sync, size_t hmac_key_length,
const uint8_t *hmac_key, const uint8_t instance_id)
{
struct sockaddr_un sa;
socklen_t sa_len;
int cfd, ret, e, n;
unsigned buffer_size;
unsigned int buffer_size;
uid_t uid;
uint8_t *buffer;
int sd;
@@ -941,7 +954,7 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
sec->vconfig = vconfig;
sec->config_pool = config_pool;
sec->sec_mod_pool = sec_mod_pool;
memcpy((uint8_t*)sec->hmac_key, hmac_key, hmac_key_length);
memcpy((uint8_t *)sec->hmac_key, hmac_key, hmac_key_length);
sec->sec_mod_instance_id = instance_id;
tls_cache_init(sec, &sec->tls_db);
@@ -962,7 +975,8 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
ocsignal(SIGTERM, handle_sigterm);
ocsignal(SIGALRM, handle_alarm);
list_for_each(sec->vconfig, vhost, list) {
list_for_each(sec->vconfig, vhost, list)
{
sec_auth_init(vhost);
}
@@ -977,8 +991,8 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
sd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sd == -1) {
e = errno;
seclog(sec, LOG_ERR, "could not create socket '%s': %s", SOCKET_FILE,
strerror(e));
seclog(sec, LOG_ERR, "could not create socket '%s': %s",
SOCKET_FILE, strerror(e));
exit(EXIT_FAILURE);
}
set_cloexec_flag(sd, 1);
@@ -987,16 +1001,16 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
ret = bind(sd, (struct sockaddr *)&sa, SUN_LEN(&sa));
if (ret == -1) {
e = errno;
seclog(sec, LOG_ERR, "could not bind socket '%s': %s", SOCKET_FILE,
strerror(e));
seclog(sec, LOG_ERR, "could not bind socket '%s': %s",
SOCKET_FILE, strerror(e));
exit(EXIT_FAILURE);
}
ret = chown(SOCKET_FILE, GETPCONFIG(sec)->uid, GETPCONFIG(sec)->gid);
if (ret == -1) {
e = errno;
seclog(sec, LOG_INFO, "could not chown socket '%s': %s", SOCKET_FILE,
strerror(e));
seclog(sec, LOG_INFO, "could not chown socket '%s': %s",
SOCKET_FILE, strerror(e));
}
ret = listen(sd, 1024);
@@ -1017,7 +1031,6 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
alarm(MAINTAINANCE_TIME);
seclog(sec, LOG_INFO, "sec-mod initialized (socket: %s)", SOCKET_FILE);
for (;;) {
check_other_work(sec);
@@ -1067,17 +1080,21 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
* ping-pong communication where each request is answered immediately. The
* async is for messages sent back and forth in no particular order */
if (FD_ISSET(cmd_fd_sync, &rd_set)) {
ret = serve_request_main(sec, cmd_fd_sync, buffer, buffer_size);
ret = serve_request_main(sec, cmd_fd_sync, buffer,
buffer_size);
if (ret < 0 && ret == ERR_BAD_COMMAND) {
seclog(sec, LOG_ERR, "error processing sync command from main");
seclog(sec, LOG_ERR,
"error processing sync command from main");
exit(EXIT_FAILURE);
}
}
if (FD_ISSET(cmd_fd, &rd_set)) {
ret = serve_request_main(sec, cmd_fd, buffer, buffer_size);
ret = serve_request_main(sec, cmd_fd, buffer,
buffer_size);
if (ret < 0 && ret == ERR_BAD_COMMAND) {
seclog(sec, LOG_ERR, "error processing async command from main");
seclog(sec, LOG_ERR,
"error processing async command from main");
exit(EXIT_FAILURE);
}
}
@@ -1094,22 +1111,25 @@ void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfi
goto cont;
}
}
set_cloexec_flag (cfd, 1);
set_cloexec_flag(cfd, 1);
/* do not allow unauthorized processes to issue commands
*/
ret = check_upeer_id("sec-mod", GETPCONFIG(sec)->log_level, cfd,
GETPCONFIG(sec)->uid, GETPCONFIG(sec)->gid,
&uid, &pid);
ret = check_upeer_id("sec-mod",
GETPCONFIG(sec)->log_level, cfd,
GETPCONFIG(sec)->uid,
GETPCONFIG(sec)->gid, &uid, &pid);
if (ret < 0) {
seclog(sec, LOG_INFO, "rejected unauthorized connection");
seclog(sec, LOG_INFO,
"rejected unauthorized connection");
} else {
memset(buffer, 0, buffer_size);
serve_request_worker(sec, cfd, pid, buffer, buffer_size);
serve_request_worker(sec, cfd, pid, buffer,
buffer_size);
}
close(cfd);
}
cont:
cont:
talloc_free(buffer);
#ifdef DEBUG_LEAKS
talloc_report_full(sec, stderr);

View File

@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_SEC_MOD_H
# define OC_SEC_MOD_H
#define OC_SEC_MOD_H
#include <gnutls/abstract.h>
#include <ccan/htable/htable.h>
@@ -64,11 +64,11 @@ typedef struct common_auth_init_st {
const char *ip;
const char *our_ip;
const char *user_agent;
unsigned id;
unsigned int id;
} common_auth_init_st;
typedef struct common_acct_info_st {
char username[MAX_USERNAME_SIZE*2];
char username[MAX_USERNAME_SIZE * 2];
char groupname[MAX_GROUPNAME_SIZE]; /* the owner's group */
char safe_id[SAFE_ID_SIZE]; /* an ID to be sent to external apps - printable */
char remote_ip[MAX_IP_STR];
@@ -78,11 +78,13 @@ typedef struct common_acct_info_st {
char our_ip[MAX_IP_STR];
char ipv4[MAX_IP_STR];
char ipv6[MAX_IP_STR];
unsigned id;
unsigned int id;
} common_acct_info_st;
#define IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, clean) (e->exptime != -1 && now >= e->exptime && e->in_use == 0)
#define IS_CLIENT_ENTRY_EXPIRED(sec, e, now) IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, 0)
#define IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, clean) \
(e->exptime != -1 && now >= e->exptime && e->in_use == 0)
#define IS_CLIENT_ENTRY_EXPIRED(sec, e, now) \
IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, 0)
typedef struct client_entry_st {
/* A unique session identifier used to distinguish sessions
@@ -93,17 +95,18 @@ typedef struct client_entry_st {
uint8_t sid[SID_SIZE];
void *auth_ctx; /* the context of authentication */
unsigned session_is_open; /* whether open_session was done */
unsigned in_use; /* counter of users of this structure */
unsigned tls_auth_ok;
unsigned int session_is_open; /* whether open_session was done */
unsigned int in_use; /* counter of users of this structure */
unsigned int tls_auth_ok;
char *msg_str;
unsigned passwd_counter; /* if msg_str is for a password this indicates the passwrd number (0,1,2) */
unsigned int
passwd_counter; /* if msg_str is for a password this indicates the passwrd number (0,1,2) */
stats_st saved_stats; /* saved from previous cookie usage */
stats_st stats; /* current */
unsigned status; /* PS_AUTH_ */
unsigned int status; /* PS_AUTH_ */
uint8_t dtls_session_id[GNUTLS_MAX_SESSION_ID];
@@ -113,15 +116,16 @@ typedef struct client_entry_st {
time_t exptime;
/* the auth type associated with the user */
unsigned auth_type;
unsigned discon_reason; /* reason for disconnection */
unsigned int auth_type;
unsigned int discon_reason; /* reason for disconnection */
struct common_acct_info_st acct_info;
/* saved during authentication; used after successful auth */
char req_group_name[MAX_GROUPNAME_SIZE]; /* the requested by the user group */
char req_group_name
[MAX_GROUPNAME_SIZE]; /* the requested by the user group */
char *cert_group_names[MAX_GROUPS];
unsigned cert_group_names_size;
unsigned int cert_group_names_size;
char cert_user_name[MAX_USERNAME_SIZE];
/* the module this entry is using */
@@ -135,28 +139,32 @@ typedef struct client_entry_st {
void *sec_mod_client_db_init(sec_mod_st *sec);
void sec_mod_client_db_deinit(sec_mod_st *sec);
unsigned sec_mod_client_db_elems(sec_mod_st *sec);
client_entry_st * new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *, const char *ip, unsigned pid);
client_entry_st * find_client_entry(sec_mod_st *sec, uint8_t sid[SID_SIZE]);
void del_client_entry(sec_mod_st *sec, client_entry_st * e);
void expire_client_entry(sec_mod_st *sec, client_entry_st * e);
unsigned int sec_mod_client_db_elems(sec_mod_st *sec);
client_entry_st *new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *,
const char *ip, unsigned int pid);
client_entry_st *find_client_entry(sec_mod_st *sec, uint8_t sid[SID_SIZE]);
void del_client_entry(sec_mod_st *sec, client_entry_st *e);
void expire_client_entry(sec_mod_st *sec, client_entry_st *e);
void cleanup_client_entries(sec_mod_st *sec);
void sec_auth_init(struct vhost_cfg_st *vhost);
void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec);
void handle_sec_auth_ban_ip_reply(sec_mod_st *sec, const BanIpReplyMsg *msg);
int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg * req, pid_t pid);
int handle_sec_auth_cont(int cfd, sec_mod_st *sec, const SecAuthContMsg * req);
int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenMsg *req);
int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionCloseMsg *req);
int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req, pid_t pid);
int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req,
pid_t pid);
int handle_sec_auth_cont(int cfd, sec_mod_st *sec, const SecAuthContMsg *req);
int handle_secm_session_open_cmd(sec_mod_st *sec, int fd,
const SecmSessionOpenMsg *req);
int handle_secm_session_close_cmd(sec_mod_st *sec, int fd,
const SecmSessionCloseMsg *req);
int handle_sec_auth_stats_cmd(sec_mod_st *sec, const CliStatsMsg *req,
pid_t pid);
void sec_auth_user_deinit(sec_mod_st *sec, client_entry_st *e);
void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfig,
const char *socket_file,
int cmd_fd, int cmd_fd_sync,
size_t hmac_key_length, const uint8_t * hmac_key,
const uint8_t instance_id);
void sec_mod_server(void *main_pool, void *config_pool,
struct list_head *vconfig, const char *socket_file,
int cmd_fd, int cmd_fd_sync, size_t hmac_key_length,
const uint8_t *hmac_key, const uint8_t instance_id);
#endif

View File

@@ -24,25 +24,25 @@
#if !defined(HAVE_SETPROCTITLE)
# if defined(__linux__)
# include <sys/prctl.h>
#if defined(__linux__)
#include <sys/prctl.h>
/* This sets the process title as shown in top, but not in ps (*@#%@).
* To change the ps name in Linux, one needs to do master black magic
* trickery (see util-linux setproctitle).
*/
void setproctitle (const char *fmt, ...)
void setproctitle(const char *fmt, ...)
{
char name[16];
va_list args;
va_start(args, fmt);
vsnprintf(name, sizeof(name)-1, fmt, args);
vsnprintf(name, sizeof(name) - 1, fmt, args);
va_end(args);
# ifdef PR_SET_NAME
prctl (PR_SET_NAME, name);
# endif
#ifdef PR_SET_NAME
prctl(PR_SET_NAME, name);
#endif
/* Copied systemd's implementation under LGPL by Lennart Poettering */
if (saved_argc > 0) {
int i;
@@ -56,12 +56,12 @@ void setproctitle (const char *fmt, ...)
}
}
}
# else /* not linux */
#else /* not linux */
void setproctitle (const char *fmt, ...)
void setproctitle(const char *fmt, ...)
{
}
# endif /* __linux__ */
#endif /* __linux__ */
#endif /* HAVE_SETPROCTITLE */

View File

@@ -19,20 +19,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OC_SETPROCTITLE_H
# define OC_SETPROCTITLE_H
#define OC_SETPROCTITLE_H
# include <config.h>
#include <config.h>
# ifndef HAVE_SETPROCTILE
#ifndef HAVE_SETPROCTILE
void __attribute__ ((format(printf, 1, 2)))
setproctitle(const char *fmt, ...);
void __attribute__((format(printf, 1, 2))) setproctitle(const char *fmt, ...);
# else
#else
# include <sys/types.h>
# include <unistd.h>
# endif
#include <sys/types.h>
#include <unistd.h>
#endif
#endif

View File

@@ -31,11 +31,11 @@
void trim_trailing_whitespace(char *str)
{
unsigned len = strlen(str);
unsigned int len = strlen(str);
char *p;
if (len > 0) {
p = str+len-1;
p = str + len - 1;
while (p >= str && isspace(*p)) {
*p = 0;
p--;
@@ -43,9 +43,9 @@ void trim_trailing_whitespace(char *str)
}
}
#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
#define MEMSUB(x, y) ((ssize_t)((ptrdiff_t)x - (ptrdiff_t)y))
void str_clear(str_st * str)
void str_clear(str_st *str)
{
if (str == NULL || str->allocd == NULL)
return;
@@ -59,20 +59,19 @@ void str_clear(str_st * str)
#define MIN_CHUNK 64
/* This function makes sure there is an additional byte in dest;
*/
int str_append_size(str_st * dest, size_t data_size)
int str_append_size(str_st *dest, size_t data_size)
{
size_t tot_len = data_size + dest->length;
if (data_size == 0)
return 0;
if (dest->max_length >= tot_len+1) {
if (dest->max_length >= tot_len + 1) {
size_t unused = MEMSUB(dest->data, dest->allocd);
if (dest->max_length - unused <= tot_len) {
if (dest->length && dest->data)
memmove(dest->allocd, dest->data,
dest->length);
memmove(dest->allocd, dest->data, dest->length);
dest->data = dest->allocd;
}
@@ -80,11 +79,11 @@ int str_append_size(str_st * dest, size_t data_size)
return tot_len;
} else {
size_t unused = MEMSUB(dest->data, dest->allocd);
size_t new_len =
MAX(data_size, MIN_CHUNK) + MAX(dest->max_length,
MIN_CHUNK);
size_t new_len = MAX(data_size, MIN_CHUNK) +
MAX(dest->max_length, MIN_CHUNK);
dest->allocd = talloc_realloc_size(dest->pool, dest->allocd, new_len+1);
dest->allocd = talloc_realloc_size(dest->pool, dest->allocd,
new_len + 1);
if (dest->allocd == NULL)
return ERR_MEM;
dest->max_length = new_len;
@@ -100,11 +99,11 @@ int str_append_size(str_st * dest, size_t data_size)
/* This function always null terminates the string in dest.
*/
int str_append_data(str_st * dest, const void *data, size_t data_size)
int str_append_data(str_st *dest, const void *data, size_t data_size)
{
int ret;
int ret;
ret = str_append_size(dest, data_size+1);
ret = str_append_size(dest, data_size + 1);
if (ret < 0)
return ret;
@@ -115,7 +114,7 @@ int str_append_data(str_st * dest, const void *data, size_t data_size)
return 0;
}
int str_append_data_prefix1(str_st * dest, const void *data, size_t data_size)
int str_append_data_prefix1(str_st *dest, const void *data, size_t data_size)
{
int ret;
uint8_t prefix = data_size;
@@ -131,7 +130,7 @@ int str_append_data_prefix1(str_st * dest, const void *data, size_t data_size)
/* Appends the provided string. The null termination byte is appended
* but not included in length.
*/
int str_append_str(str_st * dest, const char *src)
int str_append_str(str_st *dest, const char *src)
{
int ret;
@@ -145,8 +144,7 @@ int str_append_str(str_st * dest, const char *src)
return ret;
}
int
str_append_printf(str_st *dest, const char *fmt, ...)
int str_append_printf(str_st *dest, const char *fmt, ...)
{
va_list args;
int len;
@@ -170,9 +168,9 @@ int str_replace_str(str_st *str, const str_rep_tab *tab)
{
uint8_t *p;
const str_rep_tab *ptab;
unsigned length;
unsigned int length;
char *final;
unsigned final_len;
unsigned int final_len;
int ret;
size_t pos;
@@ -183,25 +181,32 @@ int str_replace_str(str_st *str, const str_rep_tab *tab)
if (p == NULL)
break;
pos = (ptrdiff_t)(p-str->data);
pos = (ptrdiff_t)(p - str->data);
length = str->length - pos;
ptab = tab;
do {
if (length >= ptab->pattern_length &&
memcmp(ptab->pattern, p, ptab->pattern_length) == 0) {
memcmp(ptab->pattern, p, ptab->pattern_length) ==
0) {
/* replace */
final_len = length - ptab->pattern_length;
final = talloc_memdup(str->allocd, p+ptab->pattern_length, final_len);
final = talloc_memdup(str->allocd,
p + ptab->pattern_length,
final_len);
if (final == NULL)
return -1;
str->length -= final_len + ptab->pattern_length;
if (ptab->rep_val)
ret = str_append_str(str, ptab->rep_val);
ret = str_append_str(str,
ptab->rep_val);
else {
char *t = ptab->rep_func(str->pool, ptab->rep_func_input);
char *t = ptab->rep_func(
str->pool,
ptab->rep_func_input);
ret = str_append_str(str, t);
talloc_free(t);
}

View File

@@ -27,17 +27,19 @@
#include <stdint.h>
#define STR_TAB_INIT(t, s_t) memset(t, 0, s_t)
#define STR_TAB_SET(i,pat,val) { \
tab[i].pattern = pat; \
tab[i].pattern_length = sizeof(pat)-1; \
tab[i].rep_val = val; \
#define STR_TAB_SET(i, pat, val) \
{ \
tab[i].pattern = pat; \
tab[i].pattern_length = sizeof(pat) - 1; \
tab[i].rep_val = val; \
}
#define STR_TAB_SET_FUNC(i,pat,func,funcinput) { \
tab[i].pattern = pat; \
tab[i].pattern_length = sizeof(pat)-1; \
tab[i].rep_val = NULL; \
tab[i].rep_func = func; \
tab[i].rep_func_input = funcinput; \
#define STR_TAB_SET_FUNC(i, pat, func, funcinput) \
{ \
tab[i].pattern = pat; \
tab[i].pattern_length = sizeof(pat) - 1; \
tab[i].rep_val = NULL; \
tab[i].rep_func = func; \
tab[i].rep_func_input = funcinput; \
}
#define STR_TAB_TERM(i) tab[i].pattern = NULL
@@ -45,22 +47,22 @@ typedef char *(*str_get_func)(void *pool, const char *input);
typedef struct {
const char *pattern;
unsigned pattern_length;
unsigned int pattern_length;
const char *rep_val;
str_get_func rep_func;
const void *rep_func_input;
} str_rep_tab;
typedef struct {
uint8_t *allocd; /* pointer to allocated data */
uint8_t *data; /* API: pointer to data to copy from */
uint8_t *allocd; /* pointer to allocated data */
uint8_t *data; /* API: pointer to data to copy from */
size_t max_length;
size_t length; /* API: current length */
size_t length; /* API: current length */
void *pool;
} str_st;
/* Initialize a buffer */
inline static void str_init(str_st * str, void *pool)
inline static void str_init(str_st *str, void *pool)
{
str->data = str->allocd = NULL;
str->max_length = 0;
@@ -72,7 +74,7 @@ inline static void str_init(str_st * str, void *pool)
void str_clear(str_st *);
/* Set the buffer data to be of zero length */
inline static void str_reset(str_st * buf)
inline static void str_reset(str_st *buf)
{
buf->data = buf->allocd;
buf->length = 0;
@@ -87,6 +89,8 @@ int str_append_data(str_st *, const void *data, size_t data_size);
int str_append_size(str_st *, size_t data_size);
int str_append_data_prefix1(str_st *, const void *data, size_t data_size);
#define str_append_str_prefix1(s, str) (((str)==NULL)?str_append_data_prefix1(s, NULL, 0):str_append_data_prefix1(s, str, strlen(str)))
#define str_append_str_prefix1(s, str) \
(((str) == NULL) ? str_append_data_prefix1(s, NULL, 0) : \
str_append_data_prefix1(s, str, strlen(str)))
#endif

View File

@@ -29,10 +29,12 @@
#include <vpn.h>
#include "common-config.h"
static void free_expanded_brackets_string(subcfg_val_st out[MAX_SUBOPTIONS], unsigned size)
static void free_expanded_brackets_string(subcfg_val_st out[MAX_SUBOPTIONS],
unsigned int size)
{
unsigned i;
for (i=0;i<size;i++) {
unsigned int i;
for (i = 0; i < size; i++) {
talloc_free(out[i].name);
talloc_free(out[i].value);
}
@@ -40,12 +42,12 @@ static void free_expanded_brackets_string(subcfg_val_st out[MAX_SUBOPTIONS], uns
/* Returns the number of suboptions processed.
*/
static
unsigned expand_brackets_string(void *pool, const char *str, subcfg_val_st out[MAX_SUBOPTIONS])
static unsigned int expand_brackets_string(void *pool, const char *str,
subcfg_val_st out[MAX_SUBOPTIONS])
{
char *p, *p2, *p3;
unsigned len, len2;
unsigned pos = 0, finish = 0;
unsigned int len, len2;
unsigned int pos = 0, finish = 0;
if (str == NULL)
return 0;
@@ -82,19 +84,19 @@ unsigned expand_brackets_string(void *pool, const char *str, subcfg_val_st out[M
len2 = p3 - p2;
if (len > 0) {
while (isspace(p[len-1]))
while (isspace(p[len - 1]))
len--;
}
if (len2 > 0) {
while (isspace(p2[len2-1]))
while (isspace(p2[len2 - 1]))
len2--;
}
out[pos].name = talloc_strndup(pool, p, len);
out[pos].value = talloc_strndup(pool, p2, len2);
pos++;
p = p2+len2;
while (isspace(*p)||*p==',')
p = p2 + len2;
while (isspace(*p) || *p == ',')
p++;
} while (finish == 0 && pos < MAX_SUBOPTIONS);
@@ -102,10 +104,11 @@ unsigned expand_brackets_string(void *pool, const char *str, subcfg_val_st out[M
}
#ifdef HAVE_GSSAPI
void *gssapi_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str)
void *gssapi_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str)
{
subcfg_val_st vals[MAX_SUBOPTIONS];
unsigned vals_size, i;
unsigned int vals_size, i;
gssapi_cfg_st *additional;
additional = talloc_zero(pool, gssapi_cfg_st);
@@ -114,22 +117,27 @@ void *gssapi_get_brackets_string(void *pool, struct perm_cfg_st *config, const c
}
vals_size = expand_brackets_string(pool, str, vals);
for (i=0;i<vals_size;i++) {
for (i = 0; i < vals_size; i++) {
if (strcasecmp(vals[i].name, "keytab") == 0) {
additional->keytab = vals[i].value;
vals[i].value = NULL;
} else if (strcasecmp(vals[i].name, "require-local-user-map") == 0) {
additional->no_local_map = 1-CHECK_TRUE(vals[i].value);
} else if (strcasecmp(vals[i].name, "tgt-freshness-time") == 0) {
} else if (strcasecmp(vals[i].name, "require-local-user-map") ==
0) {
additional->no_local_map =
1 - CHECK_TRUE(vals[i].value);
} else if (strcasecmp(vals[i].name, "tgt-freshness-time") ==
0) {
additional->ticket_freshness_secs = atoi(vals[i].value);
if (additional->ticket_freshness_secs == 0) {
fprintf(stderr, "Invalid value for '%s': %s\n", vals[i].name, vals[i].value);
fprintf(stderr, "Invalid value for '%s': %s\n",
vals[i].name, vals[i].value);
exit(EXIT_FAILURE);
}
} else if (strcasecmp(vals[i].name, "gid-min") == 0) {
additional->gid_min = atoi(vals[i].value);
if (additional->gid_min < 0) {
fprintf(stderr, "error in gid-min value: %d\n", additional->gid_min);
fprintf(stderr, "error in gid-min value: %d\n",
additional->gid_min);
exit(EXIT_FAILURE);
}
} else {
@@ -145,7 +153,7 @@ void *gssapi_get_brackets_string(void *pool, struct perm_cfg_st *config, const c
void *get_brackets_string1(void *pool, const char *str)
{
char *p, *p2;
unsigned len;
unsigned int len;
p = strchr(str, '[');
if (p == NULL) {
@@ -173,7 +181,7 @@ void *get_brackets_string1(void *pool, const char *str)
static void *get_brackets_string2(void *pool, const char *str)
{
char *p, *p2;
unsigned len;
unsigned int len;
p = strchr(str, '[');
if (p == NULL) {
@@ -204,11 +212,12 @@ static void *get_brackets_string2(void *pool, const char *str)
return talloc_strndup(pool, p, len);
}
void *radius_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str)
void *radius_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str)
{
char *p;
subcfg_val_st vals[MAX_SUBOPTIONS];
unsigned vals_size, i;
unsigned int vals_size, i;
radius_cfg_st *additional;
additional = talloc_zero(pool, radius_cfg_st);
@@ -216,13 +225,16 @@ void *radius_get_brackets_string(void *pool, struct perm_cfg_st *config, const c
return NULL;
}
if (str && str[0] == '[' && (str[1] == '/' || str[1] == '.')) { /* legacy format */
if (str && str[0] == '[' &&
(str[1] == '/' || str[1] == '.')) { /* legacy format */
additional->config = get_brackets_string1(pool, str);
p = get_brackets_string2(config, str);
if (p != NULL) {
if (strcasecmp(p, "groupconfig") != 0) {
fprintf(stderr, "No known configuration option: %s\n", p);
fprintf(stderr,
"No known configuration option: %s\n",
p);
exit(EXIT_FAILURE);
}
config->sup_config_type = SUP_CONFIG_RADIUS;
@@ -230,18 +242,22 @@ void *radius_get_brackets_string(void *pool, struct perm_cfg_st *config, const c
} else {
/* new format */
vals_size = expand_brackets_string(pool, str, vals);
for (i=0;i<vals_size;i++) {
for (i = 0; i < vals_size; i++) {
if (strcasecmp(vals[i].name, "config") == 0) {
additional->config = vals[i].value;
vals[i].value = NULL;
} else if (strcasecmp(vals[i].name, "nas-identifier") == 0) {
} else if (strcasecmp(vals[i].name, "nas-identifier") ==
0) {
additional->nas_identifier = vals[i].value;
vals[i].value = NULL;
} else if (strcasecmp(vals[i].name, "groupconfig") == 0) {
} else if (strcasecmp(vals[i].name, "groupconfig") ==
0) {
if (CHECK_TRUE(vals[i].value))
config->sup_config_type = SUP_CONFIG_RADIUS;
config->sup_config_type =
SUP_CONFIG_RADIUS;
} else {
fprintf(stderr, "unknown option '%s'\n", vals[i].name);
fprintf(stderr, "unknown option '%s'\n",
vals[i].name);
exit(EXIT_FAILURE);
}
}
@@ -258,10 +274,11 @@ void *radius_get_brackets_string(void *pool, struct perm_cfg_st *config, const c
#endif
#ifdef HAVE_PAM
void *pam_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str)
void *pam_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str)
{
subcfg_val_st vals[MAX_SUBOPTIONS];
unsigned vals_size, i;
unsigned int vals_size, i;
pam_cfg_st *additional;
additional = talloc_zero(pool, pam_cfg_st);
@@ -271,11 +288,12 @@ void *pam_get_brackets_string(void *pool, struct perm_cfg_st *config, const char
/* new format */
vals_size = expand_brackets_string(pool, str, vals);
for (i=0;i<vals_size;i++) {
for (i = 0; i < vals_size; i++) {
if (strcasecmp(vals[i].name, "gid-min") == 0) {
additional->gid_min = atoi(vals[i].value);
if (additional->gid_min < 0) {
fprintf(stderr, "error in gid-min value: %d\n", additional->gid_min);
fprintf(stderr, "error in gid-min value: %d\n",
additional->gid_min);
exit(EXIT_FAILURE);
}
} else {
@@ -289,10 +307,11 @@ void *pam_get_brackets_string(void *pool, struct perm_cfg_st *config, const char
}
#endif
void *plain_get_brackets_string(void *pool, struct perm_cfg_st *config, const char *str)
void *plain_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str)
{
subcfg_val_st vals[MAX_SUBOPTIONS];
unsigned vals_size, i;
unsigned int vals_size, i;
plain_cfg_st *additional;
additional = talloc_zero(pool, plain_cfg_st);
@@ -300,11 +319,12 @@ void *plain_get_brackets_string(void *pool, struct perm_cfg_st *config, const ch
return NULL;
}
if (str && str[0] == '[' && (str[1] == '/' || str[1] == '.')) { /* legacy format */
if (str && str[0] == '[' &&
(str[1] == '/' || str[1] == '.')) { /* legacy format */
additional->passwd = get_brackets_string1(pool, str);
} else {
vals_size = expand_brackets_string(pool, str, vals);
for (i=0;i<vals_size;i++) {
for (i = 0; i < vals_size; i++) {
if (strcasecmp(vals[i].name, "passwd") == 0) {
additional->passwd = vals[i].value;
vals[i].value = NULL;
@@ -314,7 +334,8 @@ void *plain_get_brackets_string(void *pool, struct perm_cfg_st *config, const ch
vals[i].value = NULL;
#endif
} else {
fprintf(stderr, "unknown option '%s'\n", vals[i].name);
fprintf(stderr, "unknown option '%s'\n",
vals[i].name);
exit(EXIT_FAILURE);
}
}
@@ -329,17 +350,17 @@ void *plain_get_brackets_string(void *pool, struct perm_cfg_st *config, const ch
return additional;
}
void *oidc_get_brackets_string(void * pool, struct perm_cfg_st *config, const char *str)
void *oidc_get_brackets_string(void *pool, struct perm_cfg_st *config,
const char *str)
{
subcfg_val_st vals[MAX_SUBOPTIONS];
char * additional = NULL;
char *additional = NULL;
unsigned vals_size, i;
unsigned int vals_size, i;
vals_size = expand_brackets_string(pool, str, vals);
vals_size = expand_brackets_string(pool, str, vals);
for (i = 0; i < vals_size; i ++) {
for (i = 0; i < vals_size; i++) {
if (strcasecmp(vals[i].name, "config") == 0) {
additional = talloc_strdup(pool, vals[i].value);
}

Some files were not shown because too many files have changed in this diff Show More