mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 08:46:58 +08:00
Added support for no-routes (X-Split-Exclude)
This commit is contained in:
@@ -342,10 +342,15 @@ ping-leases = false
|
||||
# comment out all routes from the server, or use the special keyword
|
||||
# 'default'.
|
||||
|
||||
route = 192.168.1.0/255.255.255.0
|
||||
route = 192.168.5.0/255.255.255.0
|
||||
route = 10.10.10.0/255.255.255.0
|
||||
route = 192.168.0.0/255.255.0.0
|
||||
#route = fef4:db8:1000:1001::/64
|
||||
|
||||
# Subsets of the routes above that will not be routed by
|
||||
# the server.
|
||||
|
||||
no-route = 192.168.5.0/255.255.255.0
|
||||
|
||||
# Groups that a client is allowed to select from.
|
||||
# A client may belong in multiple groups, and in certain use-cases
|
||||
# it is needed to switch between them. For these cases the client can
|
||||
|
||||
@@ -59,6 +59,7 @@ struct cfg_options {
|
||||
static struct cfg_options available_options[] = {
|
||||
{ .name = "auth", .type = OPTION_MULTI_LINE, .mandatory = 1 },
|
||||
{ .name = "route", .type = OPTION_MULTI_LINE, .mandatory = 0 },
|
||||
{ .name = "no-route", .type = OPTION_MULTI_LINE, .mandatory = 0 },
|
||||
{ .name = "select-group", .type = OPTION_MULTI_LINE, .mandatory = 0 },
|
||||
{ .name = "custom-header", .type = OPTION_MULTI_LINE, .mandatory = 0 },
|
||||
{ .name = "split-dns", .type = OPTION_MULTI_LINE, .mandatory = 0 },
|
||||
@@ -723,6 +724,8 @@ unsigned force_cert_auth;
|
||||
}
|
||||
}
|
||||
|
||||
READ_MULTI_LINE("no-route", config->network.no_routes, config->network.no_routes_size);
|
||||
|
||||
READ_STRING("default-select-group", config->default_select_group);
|
||||
READ_TF("auto-select-group", auto_select_group, 0);
|
||||
if (auto_select_group != 0 && amod != NULL && amod->group_list != NULL) {
|
||||
|
||||
@@ -43,6 +43,7 @@ message user_info_rep
|
||||
|
||||
optional string cstp_compr = 23;
|
||||
optional string dtls_compr = 24;
|
||||
repeated string no_routes = 25;
|
||||
}
|
||||
|
||||
message user_list_rep
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
/* === Authentication ===
|
||||
|
||||
main sec-mod worker
|
||||
| | |
|
||||
| | <--AUTH_INIT--- |
|
||||
| | ---AUTH_REP---> |
|
||||
| | <--AUTH_CONT--- |
|
||||
| | . |
|
||||
| | . |
|
||||
| | . |
|
||||
| | ----AUTH_REP--> |
|
||||
| | |
|
||||
| <----------AUTH_COOKIE_REQ------------- |
|
||||
| | |
|
||||
| ---SESSION_OPEN----> | |
|
||||
| <--SESSION_REPLY---- | |
|
||||
| | |
|
||||
| -----------------AUTH_REP-------------> |
|
||||
| | |
|
||||
| |
|
||||
| | (disconnect)
|
||||
| ---SESSION_CLOSE---> |
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* == Auth in main process (cookie auth only) ==
|
||||
*
|
||||
@@ -50,6 +76,7 @@ message auth_reply_msg
|
||||
optional string xml_config_file = 26;
|
||||
optional string ipv4_network = 27;
|
||||
optional string ipv6_network = 28;
|
||||
repeated string no_routes = 29;
|
||||
}
|
||||
|
||||
/* RESUME_FETCH_REQ + RESUME_DELETE_REQ */
|
||||
@@ -185,7 +212,7 @@ message cookie
|
||||
*
|
||||
* main sec-mod
|
||||
* SESSION_OPEN/CLOSE ------>
|
||||
*
|
||||
* <------ SESSION_REPLY
|
||||
*/
|
||||
|
||||
/* SEC_SESSION_CLOSE */
|
||||
@@ -221,4 +248,5 @@ message sec_auth_session_reply_msg
|
||||
optional uint32 net_priority = 25;
|
||||
optional string explicit_ipv4 = 26;
|
||||
optional string explicit_ipv6 = 27;
|
||||
repeated string no_routes = 28;
|
||||
}
|
||||
|
||||
@@ -131,6 +131,12 @@ int send_cookie_auth_reply(main_server_st* s, struct proc_st* proc,
|
||||
msg.routes = proc->config.routes;
|
||||
}
|
||||
|
||||
msg.n_no_routes = proc->config.no_routes_size;
|
||||
for (i=0;i<proc->config.no_routes_size;i++) {
|
||||
mslog(s, proc, LOG_DEBUG, "sending no-route '%s'", proc->config.no_routes[i]);
|
||||
msg.no_routes = proc->config.no_routes;
|
||||
}
|
||||
|
||||
ret = send_socket_msg_to_worker(s, proc, AUTH_COOKIE_REP, proc->tun_lease.fd,
|
||||
&msg,
|
||||
(pack_size_func)auth_reply_msg__get_packed_size,
|
||||
|
||||
@@ -376,6 +376,14 @@ static int append_user_info(method_ctx *ctx,
|
||||
rep->n_routes = ctx->s->config->network.routes_size;
|
||||
}
|
||||
|
||||
if (ctmp->config.no_routes_size > 0) {
|
||||
rep->no_routes = ctmp->config.no_routes;
|
||||
rep->n_no_routes = ctmp->config.no_routes_size;
|
||||
} else {
|
||||
rep->no_routes = ctx->s->config->network.no_routes;
|
||||
rep->n_no_routes = ctx->s->config->network.no_routes_size;
|
||||
}
|
||||
|
||||
if (ctmp->config.iroutes_size > 0) {
|
||||
rep->iroutes = ctmp->config.iroutes;
|
||||
rep->n_iroutes = ctmp->config.iroutes_size;
|
||||
|
||||
@@ -287,6 +287,14 @@ int session_cmd(main_server_st * s, struct proc_st *proc, unsigned open)
|
||||
proc->config.routes_size = msg->n_routes;
|
||||
}
|
||||
|
||||
if (msg->n_no_routes > 0) {
|
||||
proc->config.no_routes = talloc_size(proc, sizeof(char*)*msg->n_no_routes);
|
||||
for (i=0;i<msg->n_no_routes;i++) {
|
||||
proc->config.no_routes[i] = talloc_strdup(proc, msg->no_routes[i]);
|
||||
}
|
||||
proc->config.no_routes_size = msg->n_no_routes;
|
||||
}
|
||||
|
||||
if (msg->n_iroutes > 0) {
|
||||
proc->config.iroutes = talloc_size(proc, sizeof(char*)*msg->n_iroutes);
|
||||
for (i=0;i<msg->n_iroutes;i++) {
|
||||
|
||||
@@ -658,6 +658,9 @@ int common_info_cmd(UserListRep * args)
|
||||
fprintf(out, "Routes: defaultroute\n");
|
||||
}
|
||||
|
||||
if ((r = print_list_entries(out, "\tNo-routes:", args->user[i]->no_routes, args->user[i]->n_no_routes)) < 0)
|
||||
goto error_parse;
|
||||
|
||||
if (print_list_entries(out, "\tiRoutes:", args->user[i]->iroutes, args->user[i]->n_iroutes) < 0)
|
||||
goto error_parse;
|
||||
|
||||
|
||||
@@ -417,10 +417,15 @@ ping-leases = false
|
||||
# comment out all routes from the server, or use the special keyword
|
||||
# 'default'.
|
||||
|
||||
route = 192.168.1.0/255.255.255.0
|
||||
route = 192.168.5.0/255.255.255.0
|
||||
route = 10.10.10.0/255.255.255.0
|
||||
route = 192.168.0.0/255.255.0.0
|
||||
#route = fef4:db8:1000:1001::/64
|
||||
|
||||
# Subsets of the routes above that will not be routed by
|
||||
# the server.
|
||||
|
||||
no-route = 192.168.5.0/255.255.255.0
|
||||
|
||||
# Groups that a client is allowed to select from.
|
||||
# A client may belong in multiple groups, and in certain use-cases
|
||||
# it is needed to switch between them. For these cases the client can
|
||||
@@ -441,7 +446,7 @@ route = 192.168.5.0/255.255.255.0
|
||||
# per group. Each file name on these directories must match the username
|
||||
# or the groupname.
|
||||
# The options allowed in the configuration files are dns, nbns,
|
||||
# ipv?-network, ipv4-netmask, rx/tx-per-sec, iroute, route,
|
||||
# ipv?-network, ipv4-netmask, rx/tx-per-sec, iroute, route, no-route,
|
||||
# net-priority, deny-roaming, no-udp, user-profile, require-cert, and cgroup.
|
||||
#
|
||||
# Note that the 'iroute' option allows to add routes on the server
|
||||
|
||||
@@ -46,6 +46,7 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "deny-roaming", .type = OPTION_BOOLEAN },
|
||||
{ .name = "require-cert", .type = OPTION_BOOLEAN },
|
||||
{ .name = "route", .type = OPTION_MULTI_LINE },
|
||||
{ .name = "no-route", .type = OPTION_MULTI_LINE },
|
||||
{ .name = "iroute", .type = OPTION_MULTI_LINE },
|
||||
{ .name = "dns", .type = OPTION_MULTI_LINE },
|
||||
{ .name = "ipv4-dns", .type = OPTION_MULTI_LINE }, /* alias of dns */
|
||||
@@ -183,6 +184,7 @@ unsigned prefix = 0;
|
||||
READ_TF("require-cert", msg->require_cert, msg->has_require_cert);
|
||||
|
||||
READ_RAW_MULTI_LINE("route", msg->routes, msg->n_routes);
|
||||
READ_RAW_MULTI_LINE("no-route", msg->no_routes, msg->n_no_routes);
|
||||
READ_RAW_MULTI_LINE("iroute", msg->iroutes, msg->n_iroutes);
|
||||
|
||||
READ_RAW_MULTI_LINE("dns", msg->dns, msg->n_dns);
|
||||
|
||||
@@ -147,6 +147,10 @@ struct group_cfg_st {
|
||||
char **routes;
|
||||
unsigned int routes_size;
|
||||
|
||||
/* routes that are excluded */
|
||||
char **no_routes;
|
||||
unsigned int no_routes_size;
|
||||
|
||||
/* routes to be applied to the server */
|
||||
char **iroutes;
|
||||
unsigned int iroutes_size;
|
||||
@@ -194,6 +198,10 @@ struct vpn_st {
|
||||
char **routes;
|
||||
unsigned int routes_size;
|
||||
|
||||
/* excluded routes */
|
||||
char **no_routes;
|
||||
unsigned int no_routes_size;
|
||||
|
||||
char **dns;
|
||||
unsigned int dns_size;
|
||||
|
||||
|
||||
@@ -602,6 +602,15 @@ static int recv_cookie_auth_reply(worker_st * ws)
|
||||
if (check_if_default_route(ws->routes, ws->routes_size))
|
||||
ws->default_route = 1;
|
||||
|
||||
ws->no_routes = talloc_size(ws, msg->n_no_routes*sizeof(char*));
|
||||
if (ws->no_routes != NULL) {
|
||||
ws->no_routes_size = msg->n_no_routes;
|
||||
for (i = 0; i < ws->no_routes_size; i++) {
|
||||
ws->no_routes[i] =
|
||||
talloc_strdup(ws, msg->no_routes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ws->dns = talloc_size(ws, msg->n_dns*sizeof(char*));
|
||||
if (ws->dns != NULL) {
|
||||
ws->dns_size = msg->n_dns;
|
||||
|
||||
@@ -227,6 +227,10 @@ int complete_vpn_info(worker_st * ws, struct vpn_st *vinfo)
|
||||
if (check_if_default_route(vinfo->routes, vinfo->routes_size))
|
||||
ws->default_route = 1;
|
||||
|
||||
vinfo->no_routes_size = ws->config->network.no_routes_size;
|
||||
if (ws->config->network.no_routes_size > 0)
|
||||
vinfo->no_routes = ws->config->network.no_routes;
|
||||
|
||||
vinfo->ipv4_network = ws->config->network.ipv4_network;
|
||||
vinfo->ipv6_network = ws->config->network.ipv6_network;
|
||||
|
||||
|
||||
@@ -1092,6 +1092,47 @@ char *replace_vals(worker_st *ws, const char *txt)
|
||||
return (char*)str.data;
|
||||
}
|
||||
|
||||
static int send_routes(worker_st *ws, struct http_req_st *req,
|
||||
char **routes, unsigned routes_size,
|
||||
bool include)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned ip6;
|
||||
const char *txt;
|
||||
int ret;
|
||||
|
||||
if (include)
|
||||
txt = "Include";
|
||||
else
|
||||
txt = "Exclude";
|
||||
|
||||
for (i = 0; i < routes_size; i++) {
|
||||
if (strchr(routes[i], ':') != 0)
|
||||
ip6 = 1;
|
||||
else
|
||||
ip6 = 0;
|
||||
|
||||
if (req->no_ipv6 != 0 && ip6 != 0)
|
||||
continue;
|
||||
if (req->no_ipv4 != 0 && ip6 == 0)
|
||||
continue;
|
||||
oclog(ws, LOG_DEBUG, "%s route %s", txt, routes[i]);
|
||||
|
||||
if (ip6 != 0 && ws->full_ipv6) {
|
||||
ret = cstp_printf(ws,
|
||||
"X-CSTP-Split-%s-IP6: %s\r\n",
|
||||
txt, routes[i]);
|
||||
} else {
|
||||
ret = cstp_printf(ws,
|
||||
"X-CSTP-Split-%s: %s\r\n",
|
||||
txt, routes[i]);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* connect_handler:
|
||||
* @ws: an initialized worker structure
|
||||
*
|
||||
@@ -1377,54 +1418,18 @@ static int connect_handler(worker_st * ws)
|
||||
}
|
||||
|
||||
if (ws->default_route == 0) {
|
||||
for (i = 0; i < ws->vinfo.routes_size; i++) {
|
||||
if (strchr(ws->vinfo.routes[i], ':') != 0)
|
||||
ip6 = 1;
|
||||
else
|
||||
ip6 = 0;
|
||||
ret = send_routes(ws, req, ws->vinfo.routes, ws->vinfo.routes_size, 1);
|
||||
SEND_ERR(ret);
|
||||
|
||||
if (req->no_ipv6 != 0 && ip6 != 0)
|
||||
continue;
|
||||
if (req->no_ipv4 != 0 && ip6 == 0)
|
||||
continue;
|
||||
oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]);
|
||||
|
||||
if (ip6 != 0 && ws->full_ipv6) {
|
||||
ret = cstp_printf(ws,
|
||||
"X-CSTP-Split-Include-IP6: %s\r\n",
|
||||
ws->vinfo.routes[i]);
|
||||
} else {
|
||||
ret = cstp_printf(ws,
|
||||
"X-CSTP-Split-Include: %s\r\n",
|
||||
ws->vinfo.routes[i]);
|
||||
}
|
||||
ret = send_routes(ws, req, ws->routes, ws->routes_size, 1);
|
||||
SEND_ERR(ret);
|
||||
}
|
||||
|
||||
for (i = 0; i < ws->routes_size; i++) {
|
||||
if (strchr(ws->routes[i], ':') != 0)
|
||||
ip6 = 1;
|
||||
else
|
||||
ip6 = 0;
|
||||
|
||||
if (req->no_ipv6 != 0 && ip6 != 0)
|
||||
continue;
|
||||
if (req->no_ipv4 != 0 && ip6 == 0)
|
||||
continue;
|
||||
oclog(ws, LOG_DEBUG, "adding private route %s", ws->routes[i]);
|
||||
|
||||
if (ip6 != 0 && ws->full_ipv6) {
|
||||
ret = cstp_printf(ws,
|
||||
"X-CSTP-Split-Include-IP6: %s\r\n",
|
||||
ws->routes[i]);
|
||||
} else {
|
||||
ret = cstp_printf(ws,
|
||||
"X-CSTP-Split-Include: %s\r\n",
|
||||
ws->routes[i]);
|
||||
}
|
||||
ret = send_routes(ws, req, ws->vinfo.no_routes, ws->vinfo.no_routes_size, 0);
|
||||
SEND_ERR(ret);
|
||||
|
||||
ret = send_routes(ws, req, ws->no_routes, ws->no_routes_size, 0);
|
||||
SEND_ERR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
ret =
|
||||
cstp_printf(ws, "X-CSTP-Keepalive: %u\r\n",
|
||||
|
||||
@@ -245,6 +245,9 @@ typedef struct worker_st {
|
||||
/* additional data - received per user or per group */
|
||||
unsigned routes_size;
|
||||
char** routes;
|
||||
unsigned no_routes_size;
|
||||
char** no_routes;
|
||||
|
||||
unsigned dns_size;
|
||||
char** dns;
|
||||
unsigned nbns_size;
|
||||
|
||||
Reference in New Issue
Block a user