occtl: introduced 'show session' option

This allows printing information related to a session.

Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
This commit is contained in:
Nikos Mavrogiannopoulos
2018-01-06 20:26:19 +01:00
parent c027d4165b
commit 6abd2dc5e6
5 changed files with 193 additions and 31 deletions

View File

@@ -106,7 +106,8 @@ bin_PROGRAMS = occtl/occtl
occtl_occtl_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/occtl $(LIBNL3_CFLAGS) $(GEOIP_CFLAGS)
occtl_occtl_SOURCES = occtl/occtl.c occtl/pager.c occtl/occtl.h occtl/time.c occtl/cache.c \
occtl/ip-cache.c occtl/nl.c occtl/ctl.h occtl/print.c occtl/json.c occtl/json.h \
occtl/hex.c occtl/hex.h occtl/unix.c occtl/geoip.c occtl/geoip.h
occtl/hex.c occtl/hex.h occtl/unix.c occtl/geoip.c occtl/geoip.h \
occtl/session-cache.c
occtl_occtl_LDADD = ../gl/libgnu.a libcommon.a $(LIBREADLINE_LIBS) \
$(LIBNL3_LIBS) $(NEEDED_LIBPROTOBUF_LIBS) $(LIBTALLOC_LIBS) libccan.a \
libipc.a $(NEEDED_LIBPROTOBUF_LIBS) $(CODE_COVERAGE_LDFLAGS) \

View File

@@ -65,10 +65,12 @@ 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 sessions all", NULL, handle_list_all_cookies_cmd,
ENTRY("show sessions all", NULL, handle_list_all_sessions_cmd,
"Prints all the session IDs", 1, 1),
ENTRY("show sessions valid", NULL, handle_list_valid_cookies_cmd,
ENTRY("show sessions valid", NULL, handle_list_valid_sessions_cmd,
"Prints all the valid for reconnection sessions", 1, 1),
ENTRY("show session", "[SID]", handle_show_session_cmd,
"Prints information on the specified session", 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,
@@ -84,9 +86,9 @@ static const commands_st commands[] = {
/* hidden options */
ENTRY("?", NULL, handle_help_cmd, "Prints this help", -1, 0),
ENTRY("quit", NULL, handle_exit_cmd, "Exits this application", -1, 0),
ENTRY("show cookies all", NULL, handle_list_all_cookies_cmd,
ENTRY("show cookies all", NULL, handle_list_all_sessions_cmd,
"Alias for show sessions all", -1, 1),
ENTRY("show cookies valid", NULL, handle_list_valid_cookies_cmd,
ENTRY("show cookies valid", NULL, handle_list_valid_sessions_cmd,
"Alias for show sessions valid", -1, 1),
{NULL, 0, NULL, NULL}
};
@@ -458,6 +460,10 @@ static char *command_generator(const char *text, int state)
ret =
search_for_ip(entries_idx,
text, len);
else if (strcmp(arg, "[SID]") == 0)
ret =
search_for_session(entries_idx,
text, len);
if (ret != NULL) {
entries_idx++;
}

View File

@@ -49,6 +49,10 @@ 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);
void entries_clear(void);
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_ip(unsigned idx, const char* match, int match_size);
void ip_entries_add(void *pool, const char* ip, unsigned ip_size);
void ip_entries_clear(void);
@@ -81,8 +85,10 @@ 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_cookies_cmd(CONN_TYPE * conn, const char *arg, cmd_params_st *params);
int handle_list_valid_cookies_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);

70
src/occtl/session-cache.c Normal file
View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2018 Nikos Mavrogiannopoulos
*
* Author: Nikos Mavrogiannopoulos
*
* This file is part of ocserv.
*
* ocserv 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.
*
* ocserv 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 <occtl/occtl.h>
#include <c-strcase.h>
#include <minmax.h>
#include <common.h>
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;
void session_entries_clear(void)
{
session_entries_size = 0;
}
void session_entries_add(void *pool, const char* session)
{
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);
}
strlcpy(session_entries[session_entries_size].session, session, sizeof(session_entries[session_entries_size].session));
session_entries_size++;
return;
}
char* search_for_session(unsigned idx, const char* match, int match_size)
{
unsigned i;
if (idx >= session_entries_size)
return NULL;
for (i=idx;i<session_entries_size;i++) {
if (c_strncasecmp(match, session_entries[i].session, MIN(match_size, SAFE_ID_SIZE)) == 0)
return strdup(session_entries[i].session);
}
return NULL;
}

View File

@@ -56,7 +56,9 @@
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, unsigned all);
int session_info_cmd(void *ctx, SecmListCookiesReplyMsg * args, FILE *out,
cmd_params_st *params,
const char *lsid, unsigned all);
struct unix_ctx {
int fd;
@@ -670,12 +672,12 @@ int handle_list_users_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *
return ret;
}
static char *shorten(void *cookie, unsigned cookie_size, unsigned small)
static char *shorten(void *cookie, unsigned session_id_size, unsigned small)
{
static char psid[SAFE_ID_SIZE];
assert(cookie_size <= SAFE_ID_SIZE);
memcpy(psid, cookie, cookie_size);
assert(session_id_size <= SAFE_ID_SIZE);
memcpy(psid, cookie, session_id_size);
if (small)
psid[6] = 0;
@@ -686,7 +688,7 @@ static char *shorten(void *cookie, unsigned cookie_size, unsigned small)
}
static
void cookie_list(struct unix_ctx *ctx, SecmListCookiesReplyMsg *rep, FILE *out, cmd_params_st *params,
void session_list(struct unix_ctx *ctx, SecmListCookiesReplyMsg *rep, FILE *out, cmd_params_st *params,
unsigned all)
{
unsigned i;
@@ -695,9 +697,12 @@ void cookie_list(struct unix_ctx *ctx, SecmListCookiesReplyMsg *rep, FILE *out,
time_t t;
struct tm *tm;
char str_since[65];
const char *sid;
session_entries_clear();
if (HAVE_JSON(params)) {
cookie_info_cmd(rep, out, params, all);
session_info_cmd(ctx, rep, out, params, NULL, all);
} else for (i=0;i<rep->n_cookies;i++) {
if (!all && rep->cookies[i]->status != PS_AUTH_COMPLETED)
continue;
@@ -723,16 +728,17 @@ void cookie_list(struct unix_ctx *ctx, SecmListCookiesReplyMsg *rep, FILE *out,
if (groupname == NULL || groupname[0] == 0)
groupname = NO_GROUP;
sid = shorten(rep->cookies[i]->safe_id.data, rep->cookies[i]->safe_id.len, 1);
session_entries_add(ctx, sid);
fprintf(out, "%.6s %8s %8s %14s %.24s %8s %8s\n",
shorten(rep->cookies[i]->safe_id.data, rep->cookies[i]->safe_id.len, 1),
username, groupname, rep->cookies[i]->remote_ip,
sid, username, groupname, rep->cookies[i]->remote_ip,
rep->cookies[i]->user_agent, tmpbuf, ps_status_to_str(rep->cookies[i]->status, 1));
}
}
static
int handle_list_cookies_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params, unsigned all)
int handle_list_sessions_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params, unsigned all)
{
int ret;
struct cmd_reply_st raw;
@@ -755,7 +761,7 @@ int handle_list_cookies_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st
if (rep == NULL)
goto error;
cookie_list(ctx, rep, out, params, all);
session_list(ctx, rep, out, params, all);
ret = 0;
goto cleanup;
@@ -774,14 +780,62 @@ int handle_list_cookies_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st
return ret;
}
int handle_list_valid_cookies_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
int handle_show_session_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
{
return handle_list_cookies_cmd(ctx, arg, params, 0);
int ret;
struct cmd_reply_st raw;
SecmListCookiesReplyMsg *rep = NULL;
FILE *out;
const char *sid = (void*)arg;
PROTOBUF_ALLOCATOR(pa, ctx);
if (arg == NULL || need_help(arg)) {
check_cmd_help(rl_line_buffer);
return 1;
}
int handle_list_all_cookies_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
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;
session_info_cmd(ctx, rep, out, params, sid, 0);
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_valid_sessions_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
{
return handle_list_cookies_cmd(ctx, arg, params, 1);
return handle_list_sessions_cmd(ctx, arg, params, 0);
}
int handle_list_all_sessions_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
{
return handle_list_sessions_cmd(ctx, arg, params, 1);
}
int handle_list_iroutes_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *params)
@@ -1159,10 +1213,10 @@ 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, unsigned all)
int session_info_cmd(void *ctx, SecmListCookiesReplyMsg * args, FILE *out,
cmd_params_st *params, const char *lsid, unsigned all)
{
char *username = "";
char *groupname = "";
const char *username, *groupname;
char str_since[65];
char str_since2[65];
struct tm *tm;
@@ -1170,7 +1224,12 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
unsigned at_least_one = 0;
int ret = 1;
unsigned i;
const char *sid;
unsigned init_pager = 0;
unsigned int match_len = 0;
if (lsid)
match_len = strlen(lsid);
if (out == NULL) {
out = pager_start(params);
@@ -1180,8 +1239,16 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
if (HAVE_JSON(params))
fprintf(out, "[\n");
session_entries_clear();
for (i=0;i<args->n_cookies;i++) {
if (!all && args->cookies[i]->status != PS_AUTH_COMPLETED)
if (!all && args->cookies[i]->status != PS_AUTH_COMPLETED && lsid == NULL)
continue;
sid = shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 1);
session_entries_add(ctx, sid);
if (lsid && strncmp(sid, lsid, match_len) != 0)
continue;
if (at_least_one > 0)
@@ -1189,9 +1256,12 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
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", ps_status_to_str(args->cookies[i]->status, 1), 1);
print_single_value(out, params, "Session", sid, 1);
if (HAVE_JSON(params))
print_single_value(out, params, "Full session", shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 0), 1);
else
print_single_value(out, params, "Full session ID", shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 0), 1);
t = args->cookies[i]->created;
str_since[0] = 0;
@@ -1210,6 +1280,8 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
}
print_pair_value(out, params, "Created", str_since, "Expires", str_since2, 1);
print_single_value(out, params, "State", ps_status_to_str(args->cookies[i]->status, 1), 1);
username = args->cookies[i]->username;
if (username == NULL || username[0] == 0)
username = NO_USER;
@@ -1222,6 +1294,15 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
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);
if (HAVE_JSON(params)) {
/* old names for compatibility */
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);
} else {
/* old names for compatibility */
print_single_value(out, params, "Active", args->cookies[i]->session_is_open?"True":"False", 1);
print_single_value(out, params, "Certificate auth", args->cookies[i]->tls_auth_ok?"True":"False", 1);
}
#ifdef OCSERV_0_11_6_COMPAT
if (HAVE_JSON(params)) {
@@ -1231,8 +1312,6 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
print_single_value(out, params, "Cookie", shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 1), 1);
}
#endif
print_single_value(out, params, "Full session", shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 0), 1);
print_single_value(out, params, "Session", shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 1), 1);
print_end_block(out, params, i<(args->n_cookies-1)?1:0);
@@ -1248,7 +1327,7 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
cleanup:
if (at_least_one == 0) {
if (NO_JSON(params))
fprintf(out, "user or ID not found\n");
fprintf(out, "Session ID not found\n");
ret = 2;
}
if (init_pager)