Added occtl command to display cookies

This allows to display and examine valid cookies from occtl.
This commit is contained in:
Nikos Mavrogiannopoulos
2016-03-06 10:43:27 +01:00
parent 4541a73d3d
commit f3338e84f7
19 changed files with 649 additions and 41 deletions

View File

@@ -64,7 +64,8 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
proc-search.c proc-search.h http-heads.h ip-util.c ip-util.h \
main-ban.c main-ban.h common-config.h base64-helper.c base64-helper.h \
str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \
sec-mod-acct.h setproctitle.c setproctitle.h sec-mod-resume.h
sec-mod-acct.h setproctitle.c setproctitle.h sec-mod-resume.h \
sec-mod-cookies.c
if ENABLE_COMPRESSION
ocserv_SOURCES += lzs.c lzs.h

View File

@@ -34,6 +34,29 @@
#include "common.h"
/* 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)
{
switch (status) {
case PS_AUTH_COMPLETED:
if (cookie)
return "authenticated";
else
return "connected";
case PS_AUTH_INIT:
case PS_AUTH_CONT:
return "authenticating";
case PS_AUTH_INACTIVE:
return "pre-auth";
case PS_AUTH_FAILED:
return "auth failed";
default:
return "unknown";
}
}
const char *cmd_request_to_str(unsigned _cmd)
{
cmd_request_t cmd = _cmd;
@@ -275,6 +298,91 @@ ssize_t recvmsg_timeout(int sockfd, struct msghdr * msg, int flags,
return ret;
}
int forward_msg32(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout)
{
struct iovec iov[3];
char data[5];
uint32_t length;
ssize_t left;
uint8_t rcmd;
struct msghdr hdr;
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
int ret;
iov[0].iov_base = &rcmd;
iov[0].iov_len = 1;
iov[1].iov_base = &length;
iov[1].iov_len = 4;
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
hdr.msg_iovlen = 2;
hdr.msg_control = control_un.control;
hdr.msg_controllen = sizeof(control_un.control);
ret = recvmsg_timeout(ifd, &hdr, 0, timeout);
if (ret == -1) {
int e = errno;
syslog(LOG_ERR, "%s:%u: recvmsg: %s", __FILE__, __LINE__,
strerror(e));
return ERR_BAD_COMMAND;
}
if (ret == 0) {
syslog(LOG_ERR, "%s:%u: recvmsg returned zero", __FILE__,
__LINE__);
return ERR_PEER_TERMINATED;
}
if (rcmd != icmd) {
syslog(LOG_ERR, "%s:%u: expected %d, received %d", __FILE__,
__LINE__, (int)rcmd, (int)icmd);
return ERR_BAD_COMMAND;
}
data[0] = ocmd;
memcpy(&data[1], &length, 4);
/* send headers */
ret = force_write(ofd, data, 5);
if (ret != 5) {
syslog(LOG_ERR, "%s:%u: cannot send headers: %s", __FILE__,
__LINE__, strerror(errno));
return ERR_BAD_COMMAND;
}
left = length;
while (left > 0) {
char buf[1024];
ret = recv(ifd, buf, sizeof(buf), 0);
if (ret == -1 || ret == 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
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) {
syslog(LOG_ERR, "%s:%u: cannot send between descriptors: %s", __FILE__,
__LINE__, strerror(errno));
return ERR_BAD_COMMAND;
}
left -= ret;
}
return 0;
}
/* Sends message + socketfd */
static
int send_socket_msg(void *pool, int fd, uint8_t cmd,
@@ -300,7 +408,8 @@ int send_socket_msg(void *pool, int fd, uint8_t cmd,
iov[0].iov_base = &cmd;
iov[0].iov_len = 1;
length = get_size(msg);
if (msg)
length = get_size(msg);
if (use_32bit) {
if (length >= UINT32_MAX)
@@ -383,12 +492,13 @@ int send_socket_msg32(void *pool, int fd, uint8_t cmd,
return send_socket_msg(pool, fd, cmd, socketfd, msg, get_size, pack, 1);
}
int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
static
int recv_socket_msg(void *pool, int fd, uint8_t cmd,
int *socketfd, void **msg, unpack_func unpack,
unsigned timeout)
unsigned timeout, unsigned use_32bits)
{
struct iovec iov[3];
uint16_t length;
uint32_t length;
uint8_t rcmd;
struct msghdr hdr;
uint8_t *data = NULL;
@@ -404,7 +514,11 @@ int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
iov[0].iov_len = 1;
iov[1].iov_base = &length;
iov[1].iov_len = 2;
if (use_32bits) {
iov[1].iov_len = 4;
} else {
iov[1].iov_len = 2;
}
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
@@ -433,6 +547,12 @@ int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
return ERR_BAD_COMMAND;
}
if (!use_32bits) {
uint16_t l16;
memcpy(&l16, &length, 2);
length = l16;
}
/* try to receive socket (if any) */
if (socketfd != NULL) {
if ((cmptr = CMSG_FIRSTHDR(&hdr)) != NULL
@@ -488,6 +608,21 @@ int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
return ret;
}
int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
int *socketfd, void **msg, unpack_func unpack,
unsigned timeout)
{
return recv_socket_msg(pool,fd, cmd, socketfd, msg, unpack, timeout, 0);
}
int recv_socket_msg32(void *pool, int fd, uint8_t cmd,
int *socketfd, void **msg, unpack_func unpack,
unsigned timeout)
{
return recv_socket_msg(pool,fd, cmd, socketfd, msg, unpack, timeout, 1);
}
void _talloc_free2(void *ctx, void *ptr)
{
talloc_free(ptr);

View File

@@ -62,6 +62,8 @@ int send_socket_msg32(void *pool, int fd, uint8_t cmd,
int socketfd,
const void* msg, pack_size_func get_size, pack_func pack);
int forward_msg32(void *pool, int ifd, uint8_t icmd, int ofd, uint8_t ocmd, unsigned timeout);
inline static int send_msg16(void *pool, int fd, uint8_t cmd,
const void *msg, pack_size_func get_size, pack_func pack)
{
@@ -79,6 +81,9 @@ int send_msg32(void *pool, int fd, uint8_t cmd,
int recv_socket_msg16(void *pool, int fd, uint8_t cmd,
int *socketfd, void** msg, unpack_func, unsigned timeout);
int recv_socket_msg32(void *pool, int fd, uint8_t cmd,
int *socketfd, void** msg, unpack_func, unsigned timeout);
/* the timeout is in seconds */
inline static int recv_msg16(void *pool, int fd, uint8_t cmd,
void **msg, unpack_func unpack, unsigned timeout)
@@ -86,6 +91,11 @@ inline static int recv_msg16(void *pool, int fd, uint8_t cmd,
return recv_socket_msg16(pool, fd, cmd, NULL, msg, unpack, timeout);
}
inline static int recv_msg32(void *pool, int fd, uint8_t cmd,
void **msg, unpack_func unpack, unsigned timeout)
{
return recv_socket_msg32(pool, fd, cmd, NULL, msg, unpack, timeout);
}
const char* cmd_request_to_str(unsigned cmd);
@@ -128,6 +138,8 @@ void ms_sleep(unsigned ms)
nanosleep(&tv, NULL);
}
const char *ps_status_to_str(int status, unsigned cookie);
#ifndef HAVE_STRLCPY
size_t oc_strlcpy(char *dst, char const *src, size_t siz);
# define strlcpy oc_strlcpy

View File

@@ -279,5 +279,28 @@ message secm_session_reply_msg
required bool tls_auth_ok = 10;
}
/* SEC_BAN_IP: sent from sec-mod to main */
/* internal struct */
message cookie_int_msg
{
required bytes sid = 1;
required bool session_is_open = 2;
required bool tls_auth_ok = 3;
required uint32 last_modified = 4;
required string username = 5;
optional string groupname = 6;
required string user_agent = 7;
required string remote_ip = 8;
required string psid = 9; /* printable form of sid */
optional string status = 10; /* printable version of auth status */
}
/* SECM_LIST_COOKIES - no content */
/* SECM_LIST_COOKIES_REPLY */
message secm_list_cookies_reply_msg
{
repeated cookie_int_msg cookies = 1;
}
/* SECM_BAN_IP: sent from sec-mod to main */
/* same as: ban_ip_msg */

View File

@@ -67,6 +67,8 @@ 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);
typedef void (*method_func) (method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size);
@@ -91,6 +93,7 @@ static const ctl_method_st methods[] = {
ENTRY(CTL_CMD_STOP, method_stop),
ENTRY(CTL_CMD_LIST, method_list_users),
ENTRY(CTL_CMD_LIST_BANNED, method_list_banned),
ENTRY(CTL_CMD_LIST_COOKIES, method_list_cookies),
ENTRY(CTL_CMD_USER_INFO, method_user_info),
ENTRY(CTL_CMD_ID_INFO, method_id_info),
ENTRY(CTL_CMD_UNBAN_IP, method_unban_ip),
@@ -348,17 +351,7 @@ static int append_user_info(method_ctx *ctx,
rep->hostname = ctmp->hostname;
rep->user_agent = ctmp->user_agent;
if (ctmp->status == PS_AUTH_COMPLETED)
strtmp = "connected";
else if (ctmp->status == PS_AUTH_INIT)
strtmp = "auth";
else if (ctmp->status == PS_AUTH_INACTIVE)
strtmp = "pre-auth";
else if (ctmp->status == PS_AUTH_FAILED)
strtmp = "auth failed";
else
strtmp = "unknown";
rep->status = strtmp;
rep->status = (char*)ps_status_to_str(ctmp->status, 0);
rep->tls_ciphersuite = ctmp->tls_ciphersuite;
rep->dtls_ciphersuite = ctmp->dtls_ciphersuite;
@@ -516,6 +509,27 @@ static void method_list_banned(method_ctx *ctx, int cfd, uint8_t * msg,
return;
}
static void method_list_cookies(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size)
{
int ret;
mslog(ctx->s, NULL, LOG_DEBUG, "ctl: list-cookies");
ret = send_msg16(ctx->pool, ctx->s->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!");
}
ret = forward_msg32(ctx->pool, ctx->s->sec_mod_fd_sync, CMD_SECM_LIST_COOKIES_REPLY,
cfd, CTL_CMD_LIST_COOKIES_REP, MAIN_SEC_MOD_TIMEOUT);
if (ret < 0) {
mslog(ctx->s, NULL, LOG_ERR, "error sending list cookies reply");
}
}
static void single_info_common(method_ctx *ctx, int cfd, uint8_t * msg,
unsigned msg_size, const char *user, unsigned id)
{

View File

@@ -59,7 +59,7 @@ int handle_sec_mod_commands(main_server_st * s)
struct iovec iov[3];
uint8_t cmd;
struct msghdr hdr;
uint16_t length;
uint32_t length;
uint8_t *raw;
int ret, raw_len, e;
void *pool = talloc_new(s);
@@ -73,7 +73,7 @@ int handle_sec_mod_commands(main_server_st * s)
iov[0].iov_len = 1;
iov[1].iov_base = &length;
iov[1].iov_len = 2;
iov[1].iov_len = 4;
memset(&hdr, 0, sizeof(hdr));
hdr.msg_iov = iov;
@@ -95,7 +95,7 @@ int handle_sec_mod_commands(main_server_st * s)
return ERR_BAD_COMMAND;
}
if (ret < 3 || cmd <= MIN_SECM_CMD || cmd >= MAX_SECM_CMD) {
if (ret < 5 || cmd <= MIN_SECM_CMD || cmd >= MAX_SECM_CMD) {
mslog(s, NULL, LOG_ERR, "main received invalid message from sec-mod of %u bytes (cmd: %u)\n",
(unsigned)length, (unsigned)cmd);
return ERR_BAD_COMMAND;
@@ -440,7 +440,7 @@ int session_open(main_server_st * s, struct proc_st *proc, const uint8_t *cookie
return -1;
}
ret = recv_msg16(proc, s->sec_mod_fd_sync, CMD_SECM_SESSION_REPLY,
ret = recv_msg32(proc, s->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;
@@ -522,7 +522,7 @@ int session_close(main_server_st * s, struct proc_st *proc)
return -1;
}
ret = recv_msg16(proc, s->sec_mod_fd_sync, CMD_SECM_CLI_STATS,
ret = recv_msg32(proc, s->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;

View File

@@ -79,14 +79,6 @@ struct script_wait_st {
struct proc_st* proc;
};
enum {
PS_AUTH_INACTIVE, /* no comm with worker */
PS_AUTH_FAILED, /* no tried authenticated but failed */
PS_AUTH_INIT, /* worker has sent an auth init msg */
PS_AUTH_CONT, /* worker has sent an auth cont msg */
PS_AUTH_COMPLETED /* successful authentication */
};
/* Each worker process maps to a unique proc_st structure.
*/
typedef struct proc_st {

View File

@@ -16,7 +16,7 @@ EXTRA_DIST = args.def
bin_PROGRAMS = occtl
occtl_SOURCES = occtl.c pager.c occtl.h time.c cache.c ip-cache.c \
nl.c ctl.h print.c json.c json.h
nl.c ctl.h print.c json.c json.h hex.c hex.h
occtl_LDADD = ../../gl/libgnu.a ../common/libcommon.a $(LIBREADLINE_LIBS) \
$(LIBNL3_LIBS) $(LIBPROTOBUF_C_LIBS) $(LIBTALLOC_LIBS) ../ccan/libccan.a \
../libipc.a

View File

@@ -15,6 +15,7 @@ enum {
CTL_CMD_LIST_BANNED,
CTL_CMD_UNBAN_IP,
CTL_CMD_TOP,
CTL_CMD_LIST_COOKIES,
CTL_CMD_STATUS_REP = 101,
CTL_CMD_RELOAD_REP,
@@ -24,7 +25,8 @@ enum {
CTL_CMD_DISCONNECT_ID_REP,
CTL_CMD_UNBAN_IP_REP,
CTL_CMD_LIST_BANNED_REP,
CTL_CMD_TOP_UPDATE_REP
CTL_CMD_TOP_UPDATE_REP,
CTL_CMD_LIST_COOKIES_REP
};
#endif

71
src/occtl/hex.c Normal file
View File

@@ -0,0 +1,71 @@
/* CC0 license (public domain) - see LICENSE file for details */
#include <config.h>
#include <hex.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static bool char_to_hex(unsigned char *val, char c)
{
if (c >= '0' && c <= '9') {
*val = c - '0';
return true;
}
if (c >= 'a' && c <= 'f') {
*val = c - 'a' + 10;
return true;
}
if (c >= 'A' && c <= 'F') {
*val = c - 'A' + 10;
return true;
}
return false;
}
bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize)
{
unsigned char v1, v2;
unsigned char *p = buf;
while (slen > 1) {
if (!char_to_hex(&v1, str[0]) || !char_to_hex(&v2, str[1]))
return false;
if (!bufsize)
return false;
*(p++) = (v1 << 4) | v2;
str += 2;
slen -= 2;
bufsize--;
}
return slen == 0 && bufsize == 0;
}
static char hexchar(unsigned int val)
{
if (val < 10)
return '0' + val;
if (val < 16)
return 'a' + val - 10;
abort();
}
bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize)
{
size_t used = 0;
if (destsize < 1)
return false;
while (used < bufsize) {
unsigned int c = ((const unsigned char *)buf)[used];
if (destsize < 3)
return false;
*(dest++) = hexchar(c >> 4);
*(dest++) = hexchar(c & 0xF);
used++;
destsize -= 2;
}
*dest = '\0';
return used + 1;
}

73
src/occtl/hex.h Normal file
View File

@@ -0,0 +1,73 @@
/* CC0 (Public domain) - see LICENSE file for details */
#ifndef CCAN_HEX_H
#define CCAN_HEX_H
#include "config.h"
#include <stdbool.h>
#include <stdlib.h>
/**
* hex_decode - Unpack a hex string.
* @str: the hexidecimal string
* @slen: the length of @str
* @buf: the buffer to write the data into
* @bufsize: the length of @buf
*
* Returns false if there are any characters which aren't 0-9, a-f or A-F,
* of the string wasn't the right length for @bufsize.
*
* Example:
* unsigned char data[20];
*
* if (!hex_decode(argv[1], strlen(argv[1]), data, 20))
* printf("String is malformed!\n");
*/
bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize);
/**
* hex_encode - Create a nul-terminated hex string
* @buf: the buffer to read the data from
* @bufsize: the length of @buf
* @dest: the string to fill
* @destsize: the max size of the string
*
* Returns true if the string, including terminator, fit in @destsize;
*
* Example:
* unsigned char buf[] = { 0x1F, 0x2F };
* char str[5];
*
* if (!hex_encode(buf, sizeof(buf), str, sizeof(str)))
* abort();
*/
bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize);
/**
* hex_str_size - Calculate how big a nul-terminated hex string is
* @bytes: bytes of data to represent
*
* Example:
* unsigned char buf[] = { 0x1F, 0x2F };
* char str[hex_str_size(sizeof(buf))];
*
* hex_encode(buf, sizeof(buf), str, sizeof(str));
*/
static inline size_t hex_str_size(size_t bytes)
{
return 2 * bytes + 1;
}
/**
* hex_data_size - Calculate how many bytes of data in a hex string
* @strlen: the length of the string (with or without NUL)
*
* Example:
* const char str[] = "1F2F";
* unsigned char buf[hex_data_size(sizeof(str))];
*
* hex_decode(str, strlen(str), buf, sizeof(buf));
*/
static inline size_t hex_data_size(size_t strlen)
{
return strlen / 2;
}
#endif /* PETTYCOIN_HEX_H */

View File

@@ -65,6 +65,8 @@ static const commands_st commands[] = {
"Prints all the known IP addresses which have points", 1, 1),
ENTRY("show iroutes", NULL, handle_list_iroutes_cmd,
"Prints the routes provided by users of the server", 1, 1),
ENTRY("show cookies", NULL, handle_list_cookies_cmd,
"Prints all the cookies", 1, 1),
ENTRY("show user", "[NAME]", handle_show_user_cmd,
"Prints information on the specified user", 1, 1),
ENTRY("show id", "[ID]", handle_show_id_cmd,

View File

@@ -80,6 +80,7 @@ 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_cookies_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);

View File

@@ -33,7 +33,6 @@
#include <common.h>
#include <c-strcase.h>
#include <arpa/inet.h>
#include <system.h>
#include <termios.h>
#include <unistd.h>
@@ -44,9 +43,12 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "hex.h"
static
int common_info_cmd(UserListRep *args, FILE *out, cmd_params_st *params);
static
int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *params);
struct unix_ctx {
int fd;
@@ -59,6 +61,7 @@ static uint8_t msg_map[] = {
[CTL_CMD_RELOAD] = CTL_CMD_RELOAD_REP,
[CTL_CMD_STOP] = CTL_CMD_STOP_REP,
[CTL_CMD_LIST] = CTL_CMD_LIST_REP,
[CTL_CMD_LIST_COOKIES] = CTL_CMD_LIST_COOKIES_REP,
[CTL_CMD_LIST_BANNED] = CTL_CMD_LIST_BANNED_REP,
[CTL_CMD_USER_INFO] = CTL_CMD_LIST_REP,
[CTL_CMD_TOP] = CTL_CMD_LIST_REP,
@@ -642,6 +645,86 @@ int handle_list_users_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *
return ret;
}
void cookie_list(struct unix_ctx *ctx, SecmListCookiesReplyMsg *rep, FILE *out, cmd_params_st *params)
{
unsigned i;
const char *groupname, *username;
char tmpbuf[MAX_TMPSTR_SIZE];
time_t t;
struct tm *tm;
char str_since[65];
if (HAVE_JSON(params)) {
cookie_info_cmd(rep, out, params);
} else for (i=0;i<rep->n_cookies;i++) {
username = rep->cookies[i]->username;
if (username == NULL || username[0] == 0)
username = NO_USER;
/* add header */
if (i == 0) {
fprintf(out, "%6s %8s %8s %14s %24s %8s %8s\n",
"cookie", "user", "group", "ip", "user agent", "updated", "status");
}
t = rep->cookies[i]->last_modified;
tm = localtime(&t);
strftime(str_since, sizeof(str_since), DATE_TIME_FMT, tm);
groupname = rep->cookies[i]->groupname;
if (groupname == NULL || groupname[0] == 0)
groupname = NO_GROUP;
print_time_ival7(tmpbuf, time(0), t);
fprintf(out, "%.6s %8s %8s %14s %.24s %8s %8s\n",
rep->cookies[i]->psid, username, groupname, rep->cookies[i]->remote_ip,
rep->cookies[i]->user_agent, tmpbuf, rep->cookies[i]->status);
}
}
int handle_list_cookies_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
{
int ret;
struct cmd_reply_st raw;
SecmListCookiesReplyMsg *rep = NULL;
FILE *out;
PROTOBUF_ALLOCATOR(pa, ctx);
init_reply(&raw);
entries_clear();
out = pager_start(params);
ret = send_cmd(ctx, CTL_CMD_LIST_COOKIES, NULL, NULL, NULL, &raw);
if (ret < 0) {
goto error;
}
rep = secm_list_cookies_reply_msg__unpack(&pa, raw.data_size, raw.data);
if (rep == NULL)
goto error;
cookie_list(ctx, rep, out, params);
ret = 0;
goto cleanup;
error:
ret = 1;
fprintf(stderr, ERR_SERVER_UNREACHABLE);
cleanup:
if (rep != NULL)
secm_list_cookies_reply_msg__free_unpacked(rep, &pa);
free_reply(&raw);
pager_stop(out);
return ret;
}
int handle_list_iroutes_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
{
int ret;
@@ -1004,6 +1087,86 @@ int common_info_cmd(UserListRep * args, FILE *out, cmd_params_st *params)
return ret;
}
static
int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *params)
{
char *username = "";
char *groupname = "";
char str_since[65];
struct tm *tm;
time_t t;
unsigned at_least_one = 0;
int ret = 1;
unsigned i;
unsigned init_pager = 0;
if (out == NULL) {
out = pager_start(params);
init_pager = 1;
}
if (HAVE_JSON(params))
fprintf(out, "[\n");
for (i=0;i<args->n_cookies;i++) {
if (at_least_one > 0)
fprintf(out, "\n");
print_start_block(out, params);
print_single_value_int(out, params, "session_is_open", args->cookies[i]->session_is_open, 1);
print_single_value_int(out, params, "tls_auth_ok", args->cookies[i]->tls_auth_ok, 1);
print_single_value(out, params, "State", args->cookies[i]->status, 1);
t = args->cookies[i]->last_modified;
tm = localtime(&t);
strftime(str_since, sizeof(str_since), DATE_TIME_FMT, tm);
username = args->cookies[i]->username;
if (username == NULL || username[0] == 0)
username = NO_USER;
groupname = args->cookies[i]->groupname;
if (groupname == NULL || groupname[0] == 0)
groupname = NO_GROUP;
print_pair_value(out, params, "Username", username, "Groupname", groupname, 1);
print_single_value(out, params, "User-Agent", args->cookies[i]->user_agent, 1);
print_single_value(out, params, "Remote IP", args->cookies[i]->remote_ip, 1);
print_single_value(out, params, "Last Modified", str_since, 1);
str_since[0] = 0;
hex_encode(args->cookies[i]->sid.data, args->cookies[i]->sid.len, str_since, sizeof(str_since));
print_single_value(out, params, "cookie", str_since, 1);
print_single_value(out, params, "Printable cookie", args->cookies[i]->psid, 1);
print_single_value(out, params, "Last Modified", str_since, 0);
print_end_block(out, params, i<(args->n_cookies-1)?1:0);
at_least_one = 1;
}
if (HAVE_JSON(params))
fprintf(out, "]\n");
ret = 0;
goto cleanup;
cleanup:
if (at_least_one == 0) {
if (NO_JSON(params))
fprintf(out, "user or ID not found\n");
ret = 2;
}
if (init_pager)
pager_stop(out);
return ret;
}
int handle_show_user_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
{
int ret;

View File

@@ -93,7 +93,7 @@ void sec_mod_add_score_to_ip(sec_mod_st *sec, client_entry_st *e, const char *ip
return;
}
ret = send_msg16(lpool, sec->cmd_fd, CMD_SECM_BAN_IP, &msg,
ret = send_msg32(lpool, sec->cmd_fd, CMD_SECM_BAN_IP, &msg,
(pack_size_func) ban_ip_msg__get_packed_size,
(pack_func) ban_ip_msg__pack);
if (ret < 0) {
@@ -343,7 +343,7 @@ int send_failed_session_open_reply(sec_mod_st *sec, int fd)
return ERR_BAD_COMMAND;
}
ret = send_msg16(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
ret = send_msg32(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
(pack_size_func) secm_session_reply_msg__get_packed_size,
(pack_func) secm_session_reply_msg__pack);
if (ret < 0) {
@@ -439,7 +439,7 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
}
}
ret = send_msg16(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
ret = send_msg32(lpool, fd, CMD_SECM_SESSION_REPLY, &rep,
(pack_size_func) secm_session_reply_msg__get_packed_size,
(pack_func) secm_session_reply_msg__pack);
if (ret < 0) {
@@ -472,14 +472,14 @@ int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionClos
char tmp[BASE64_ENCODE_RAW_LENGTH(SID_SIZE) + 1];
oc_base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp));
seclog(sec, LOG_INFO, "session close but with non-existing SID: %s", tmp);
return send_msg16(e, fd, CMD_SECM_CLI_STATS, &rep,
return send_msg32(e, fd, CMD_SECM_CLI_STATS, &rep,
(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.psid);
return send_msg16(e, fd, CMD_SECM_CLI_STATS, &rep,
return send_msg32(e, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
}
@@ -506,7 +506,7 @@ int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionClos
rep.secmod_tlsdb_entries = sec->tls_db.entries;
rep.has_secmod_tlsdb_entries = 1;
ret = send_msg16(e, fd, CMD_SECM_CLI_STATS, &rep,
ret = send_msg32(e, fd, CMD_SECM_CLI_STATS, &rep,
(pack_size_func) cli_stats_msg__get_packed_size,
(pack_func) cli_stats_msg__pack);
if (ret < 0) {

104
src/sec-mod-cookies.c Normal file
View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2016 Nikos Mavrogiannopoulos
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <vpn.h>
#include <main.h>
#include <sec-mod.h>
#include <ccan/hash/hash.h>
#include <ccan/htable/htable.h>
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_msg32(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");
}
}
void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
{
SecmListCookiesReplyMsg msg = SECM_LIST_COOKIES_REPLY_MSG__INIT;
struct htable *db = sec->client_db;
client_entry_st *t;
struct htable_iter iter;
CookieIntMsg *cookies;
int ret;
if (db == NULL) {
send_empty_reply(pool, fd, sec);
return;
}
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);
if (cookies == NULL) {
send_empty_reply(pool, fd, sec);
return;
}
t = htable_first(db, &iter);
while (t != NULL) {
if (msg.n_cookies >= db->elems)
break;
cookie_int_msg__init(&cookies[msg.n_cookies]);
cookies[msg.n_cookies].sid.data = t->sid;
cookies[msg.n_cookies].sid.len = sizeof(t->sid);
cookies[msg.n_cookies].session_is_open = t->session_is_open;
cookies[msg.n_cookies].tls_auth_ok = t->tls_auth_ok;
cookies[msg.n_cookies].last_modified = t->time;
cookies[msg.n_cookies].username = t->acct_info.username;
cookies[msg.n_cookies].groupname = t->acct_info.groupname;
cookies[msg.n_cookies].user_agent = t->acct_info.user_agent;
cookies[msg.n_cookies].remote_ip = t->acct_info.remote_ip;
cookies[msg.n_cookies].psid = t->acct_info.psid;
cookies[msg.n_cookies].status = (char*)ps_status_to_str(t->status, 1);
msg.cookies[msg.n_cookies] = &cookies[msg.n_cookies];
msg.n_cookies++;
t = htable_next(db, &iter);
}
ret = send_msg32(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");
}
talloc_free(msg.cookies);
talloc_free(cookies);
}

View File

@@ -425,6 +425,10 @@ int process_packet_from_main(void *pool, int fd, sec_mod_st * sec, cmd_request_t
data.size = buffer_size;
switch (cmd) {
case CMD_SECM_LIST_COOKIES:
handle_secm_list_cookies_reply(pool, fd, sec);
return 0;
case CMD_SECM_BAN_IP_REPLY:{
BanIpReplyMsg *msg = NULL;

View File

@@ -26,7 +26,7 @@
#include <nettle/base64.h>
#include <tlslib.h>
#define SESSION_STR "(session: %.5s)"
#define SESSION_STR "(session: %.6s)"
typedef struct sec_mod_st {
struct cfg_st *config;
@@ -130,6 +130,7 @@ void seclog_hex(const struct sec_mod_st* sec, int priority,
void sec_auth_init(sec_mod_st *sec, struct perm_cfg_st *config);
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);

View File

@@ -50,6 +50,14 @@
#define MAX_MSG_SIZE 16*1024
enum {
PS_AUTH_INACTIVE, /* no comm with worker */
PS_AUTH_FAILED, /* no tried authenticated but failed */
PS_AUTH_INIT, /* worker has sent an auth init msg */
PS_AUTH_CONT, /* worker has sent an auth cont msg */
PS_AUTH_COMPLETED /* successful authentication */
};
typedef enum {
SOCK_TYPE_TCP,
SOCK_TYPE_UDP,
@@ -214,6 +222,8 @@ typedef enum {
CMD_SECM_BAN_IP,
CMD_SECM_BAN_IP_REPLY,
CMD_SECM_CLI_STATS,
CMD_SECM_LIST_COOKIES,
CMD_SECM_LIST_COOKIES_REPLY,
MAX_SECM_CMD,
} cmd_request_t;