- Fix RADIUS authentication on DAE responses.
- Don't send tunnel HELLO when there are pending control messages.
- Move plugin_radius_reset from *ctl to auto* plugins.
+- Add Cisco-AVPairs to RADIUS accounting records via plugin_radius_account.
* Mon Sep 19 2005 Brendan O'Dea <bod@optus.net> 2.1.8
- Move code from signal handlers into mainloop, avoiding a race
/* set up intercept based on RADIUS reply */
-char const *cvs_id = "$Id: autosnoop.c,v 1.11 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: autosnoop.c,v 1.12 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-struct pluginfuncs *p;
+static struct pluginfuncs *f = 0;
int plugin_radius_response(struct param_radius_response *data)
{
- if (!strcmp(data->key, "intercept"))
+ if (!strcmp(data->key, "intercept"))
+ {
+ char *p;
+ data->s->snoop_ip = 0;
+ data->s->snoop_port = 0;
+ if ((p = strchr(data->value, ':')))
{
- char *x;
+ *p++ = 0;
+ if (*data->value)
+ data->s->snoop_ip = inet_addr(data->value);
+
+ if (data->s->snoop_ip == INADDR_NONE)
data->s->snoop_ip = 0;
- data->s->snoop_port = 0;
- if ((x = strchr(data->value, ':')))
- {
- *x++ = 0;
- if (*data->value) data->s->snoop_ip = inet_addr(data->value);
- if (data->s->snoop_ip == INADDR_NONE) data->s->snoop_ip = 0;
- if (*x) data->s->snoop_port = atoi(x);
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Intercepting user to %s:%d\n",
- p->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
- }
- else
- {
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Not Intercepting user (reply string should be intercept=ip:port)\n");
- }
+
+ if (*p)
+ data->s->snoop_port = atoi(p);
+
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Intercepting user to %s:%d\n",
+ f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
+ }
+ else
+ {
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Not Intercepting user (reply string should"
+ " be intercept=ip:port)\n");
}
+ }
return PLUGIN_RET_OK;
}
int plugin_radius_reset(struct param_radius_reset *data)
{
- data->s->snoop_ip = 0;
- data->s->snoop_port = 0;
- return PLUGIN_RET_OK;
+ data->s->snoop_ip = 0;
+ data->s->snoop_port = 0;
+ return PLUGIN_RET_OK;
+}
+
+int plugin_radius_account(struct param_radius_account *data)
+{
+ if (data->s->snoop_ip && data->s->snoop_port)
+ {
+ uint8_t *p = *data->packet;
+
+ *p = 26; // vendor-specific
+ *(uint32_t *) (p + 2) = htonl(9); // Cisco
+ p[6] = 1; // Cisco-AVPair
+ p[7] = 2 + sprintf((char *) p + 8, "intercept=%s:%d",
+ f->fmtaddr(data->s->snoop_ip, 0), data->s->snoop_port);
+
+ p[1] = p[7] + 6;
+ *data->packet += p[1];
+ }
+
+ return PLUGIN_RET_OK;
}
int plugin_init(struct pluginfuncs *funcs)
{
- return ((p = funcs)) ? 1 : 0;
+ return ((f = funcs)) ? 1 : 0;
}
* throttle=no
*/
-char const *cvs_id = "$Id: autothrottle.c,v 1.15 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: autothrottle.c,v 1.16 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-struct pluginfuncs *p;
+static struct pluginfuncs *f = 0;
#define THROTTLE_KEY "lcp:interface-config"
int plugin_radius_response(struct param_radius_response *data)
{
- if (!strncmp(data->key, THROTTLE_KEY, sizeof(THROTTLE_KEY) - 1))
+ if (!strncmp(data->key, THROTTLE_KEY, sizeof(THROTTLE_KEY) - 1))
+ {
+ char *sp = strchr(data->value, ' ');
+ char type;
+ int rate;
+
+ if (!sp || sp - data->value < 4 ||
+ strncmp("service-policy", data->value, sp - data->value))
+ return PLUGIN_RET_OK;
+
+ while (*sp == ' ') sp++;
+ data->value = sp;
+
+ if (!(sp = strchr(data->value, ' ')) ||
+ (strncmp("input", data->value, sp - data->value) &&
+ strncmp("output", data->value, sp - data->value)))
{
- char *sp = strchr(data->value, ' ');
- char type;
- int rate;
-
- if (!sp || sp - data->value < 4 ||
- strncmp("service-policy", data->value, sp - data->value))
- return PLUGIN_RET_OK;
-
- while (*sp == ' ') sp++;
- data->value = sp;
-
- if (!(sp = strchr(data->value, ' ')) ||
- (strncmp("input", data->value, sp - data->value) &&
- strncmp("output", data->value, sp - data->value)))
- {
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Not throttling user (invalid type %.*s)\n",
- sp - data->value, data->value);
-
- return PLUGIN_RET_OK;
- }
-
- type = *data->value;
-
- while (*sp == ' ') sp++;
- data->value = sp;
-
- if ((rate = strtol(data->value, &sp, 10)) < 0 || *sp)
- {
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Not throttling user (invalid rate %s)\n",
- data->value);
-
- return PLUGIN_RET_OK;
- }
-
- if (type == 'i')
- {
- data->s->throttle_in = rate;
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Throttling user input to %dkb/s\n",
- rate);
- }
- else
- {
- data->s->throttle_out = rate;
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Throttling user output to %dkb/s\n",
- rate);
- }
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Not throttling user (invalid type %.*s)\n",
+ sp - data->value, data->value);
+
+ return PLUGIN_RET_OK;
+ }
+
+ type = *data->value;
+
+ while (*sp == ' ') sp++;
+ data->value = sp;
+
+ if ((rate = strtol(data->value, &sp, 10)) < 0 || *sp)
+ {
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Not throttling user (invalid rate %s)\n",
+ data->value);
+
+ return PLUGIN_RET_OK;
}
- if (!strcmp(data->key, "throttle"))
+ if (type == 'i')
{
- char *e;
- int rate;
-
- if ((rate = strtol(data->value, &e, 10)) < 0 || *e)
- {
- rate = -1;
- if (!strcmp(data->value, "yes"))
- {
- unsigned long *ts = p->getconfig("throttle_speed", UNSIGNED_LONG);
- if (ts)
- rate = *ts;
- }
- else if (!strcmp(data->value, "no"))
- rate = 0;
- }
-
- if (rate < 0)
- return PLUGIN_RET_OK;
-
- if (rate)
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Throttling user to %dkb/s\n", rate);
- else
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
- " Not throttling user\n");
-
- data->s->throttle_in = data->s->throttle_out = rate;
+ data->s->throttle_in = rate;
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Throttling user input to %dkb/s\n", rate);
}
+ else
+ {
+ data->s->throttle_out = rate;
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Throttling user output to %dkb/s\n", rate);
+ }
+ }
+ else if (!strcmp(data->key, "throttle"))
+ {
+ char *e;
+ int rate;
+
+ if ((rate = strtol(data->value, &e, 10)) < 0 || *e)
+ {
+ rate = -1;
+ if (!strcmp(data->value, "yes"))
+ {
+ unsigned long *ts = f->getconfig("throttle_speed", UNSIGNED_LONG);
+ if (ts)
+ rate = *ts;
+ }
+ else if (!strcmp(data->value, "no"))
+ rate = 0;
+ }
+
+ if (rate < 0)
+ return PLUGIN_RET_OK;
- return PLUGIN_RET_OK;
+ if (rate)
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Throttling user to %dkb/s\n", rate);
+ else
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ " Not throttling user\n");
+
+ data->s->throttle_in = data->s->throttle_out = rate;
+ }
+
+ return PLUGIN_RET_OK;
}
int plugin_radius_reset(struct param_radius_reset *data)
{
- p->throttle(p->get_id_by_session(data->s), 0, 0);
- return PLUGIN_RET_OK;
+ f->throttle(f->get_id_by_session(data->s), 0, 0);
+ return PLUGIN_RET_OK;
+}
+
+int plugin_radius_account(struct param_radius_account *data)
+{
+ if (data->s->throttle_in || data->s->throttle_out)
+ {
+ uint8_t *p = *data->packet;
+ int i = 1;
+
+ if (data->s->throttle_in)
+ {
+ *p = 26; // vendor-specific
+ *(uint32_t *) (p + 2) = htonl(9); // Cisco
+ p[6] = 1; // Cisco-AVPair
+ p[7] = 2 + sprintf((char *) p + 8,
+ "lcp:interface-config#%d=service-policy input %d", i++,
+ data->s->throttle_in);
+
+ p[1] = p[7] + 6;
+ p += p[1];
+ }
+
+ if (data->s->throttle_out)
+ {
+ *p = 26; // vendor-specific
+ *(uint32_t *) (p + 2) = htonl(9); // Cisco
+ p[6] = 1; // Cisco-AVPair
+ p[7] = 2 + sprintf((char *) p + 8,
+ "lcp:interface-config#%d=service-policy output %d", i++,
+ data->s->throttle_out);
+
+ p[1] = p[7] + 6;
+ p += p[1];
+ }
+
+ *data->packet = p;
+ }
+
+ return PLUGIN_RET_OK;
}
int plugin_init(struct pluginfuncs *funcs)
{
- return ((p = funcs)) ? 1 : 0;
+ return ((f = funcs)) ? 1 : 0;
}
/* walled garden */
-char const *cvs_id = "$Id: garden.c,v 1.23 2005-06-02 11:32:30 bodea Exp $";
+char const *cvs_id = "$Id: garden.c,v 1.24 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
static int iam_master = 0; // We're all slaves! Slaves I tell you!
char *up_commands[] = {
- "iptables -t nat -N garden >/dev/null 2>&1", // Create a chain that all gardened users will go through
- "iptables -t nat -F garden",
- ". " PLUGINCONF "/build-garden", // Populate with site-specific DNAT rules
- "iptables -t nat -N garden_users >/dev/null 2>&1", // Empty chain, users added/removed by garden_session
- "iptables -t nat -F garden_users",
- "iptables -t nat -A PREROUTING -j garden_users", // DNAT any users on the garden_users chain
- "sysctl -w net.ipv4.ip_conntrack_max=512000 >/dev/null", // lots of entries
- NULL,
+ "iptables -t nat -N garden >/dev/null 2>&1", // Create a chain that all gardened users will go through
+ "iptables -t nat -F garden",
+ ". " PLUGINCONF "/build-garden", // Populate with site-specific DNAT rules
+ "iptables -t nat -N garden_users >/dev/null 2>&1", // Empty chain, users added/removed by garden_session
+ "iptables -t nat -F garden_users",
+ "iptables -t nat -A PREROUTING -j garden_users", // DNAT any users on the garden_users chain
+ "sysctl -w net.ipv4.ip_conntrack_max=512000 >/dev/null", // lots of entries
+ NULL,
};
char *down_commands[] = {
- "iptables -t nat -F PREROUTING",
- "iptables -t nat -F garden_users",
- "iptables -t nat -X garden_users",
- "iptables -t nat -F garden",
- "iptables -t nat -X garden",
- "rmmod iptable_nat", // Should also remove ip_conntrack, but
+ "iptables -t nat -F PREROUTING",
+ "iptables -t nat -F garden_users",
+ "iptables -t nat -X garden_users",
+ "iptables -t nat -F garden",
+ "iptables -t nat -X garden",
+ "rmmod iptable_nat", // Should also remove ip_conntrack, but
// doing so can take hours... literally.
// If a master is re-started as a slave,
// either rmmod manually, or reboot.
- NULL,
+ NULL,
};
#define F_UNGARDEN 0
int plugin_post_auth(struct param_post_auth *data)
{
- // Ignore if user authentication was successful
- if (data->auth_allowed) return PLUGIN_RET_OK;
-
- p->log(3, p->get_id_by_session(data->s), data->s->tunnel, "Walled Garden allowing login\n");
- data->auth_allowed = 1;
- data->s->walled_garden = 1;
+ // Ignore if user authentication was successful
+ if (data->auth_allowed)
return PLUGIN_RET_OK;
+
+ f->log(3, f->get_id_by_session(data->s), data->s->tunnel,
+ "Walled Garden allowing login\n");
+
+ data->auth_allowed = 1;
+ data->s->walled_garden = 1;
+ return PLUGIN_RET_OK;
}
int plugin_new_session(struct param_new_session *data)
{
- if (!iam_master)
- return PLUGIN_RET_OK; // Slaves don't do walled garden processing.
+ if (!iam_master)
+ return PLUGIN_RET_OK; // Slaves don't do walled garden processing.
- if (data->s->walled_garden)
- garden_session(data->s, F_GARDEN, 0);
+ if (data->s->walled_garden)
+ garden_session(data->s, F_GARDEN, 0);
- return PLUGIN_RET_OK;
+ return PLUGIN_RET_OK;
}
int plugin_kill_session(struct param_new_session *data)
{
- if (!iam_master)
- return PLUGIN_RET_OK; // Slaves don't do walled garden processing.
+ if (!iam_master)
+ return PLUGIN_RET_OK; // Slaves don't do walled garden processing.
- if (data->s->walled_garden)
- garden_session(data->s, F_CLEANUP, 0);
+ if (data->s->walled_garden)
+ garden_session(data->s, F_CLEANUP, 0);
- return PLUGIN_RET_OK;
+ return PLUGIN_RET_OK;
}
char *plugin_control_help[] = {
- " garden USER|SID Put user into the walled garden",
- " ungarden SID [USER] Release session from garden",
- 0
+ " garden USER|SID Put user into the walled garden",
+ " ungarden SID [USER] Release session from garden",
+ 0
};
int plugin_control(struct param_control *data)
{
- sessionidt session;
- sessiont *s = 0;
- int flag;
- char *end;
+ sessionidt session;
+ sessiont *s = 0;
+ int flag;
+ char *end;
- if (data->argc < 1)
- return PLUGIN_RET_OK;
+ if (data->argc < 1)
+ return PLUGIN_RET_OK;
- if (strcmp(data->argv[0], "garden") && strcmp(data->argv[0], "ungarden"))
- return PLUGIN_RET_OK; // not for us
+ if (strcmp(data->argv[0], "garden") && strcmp(data->argv[0], "ungarden"))
+ return PLUGIN_RET_OK; // not for us
- if (!iam_master)
- return PLUGIN_RET_NOTMASTER;
+ if (!iam_master)
+ return PLUGIN_RET_NOTMASTER;
- flag = data->argv[0][0] == 'g' ? F_GARDEN : F_UNGARDEN;
+ flag = data->argv[0][0] == 'g' ? F_GARDEN : F_UNGARDEN;
- if (data->argc < 2 || data->argc > 3 || (data->argc > 2 && flag == F_GARDEN))
- {
- data->response = NSCTL_RES_ERR;
- data->additional = flag == F_GARDEN
- ? "requires username or session id"
- : "requires session id and optional username";
+ if (data->argc < 2 || data->argc > 3 || (data->argc > 2 && flag == F_GARDEN))
+ {
+ data->response = NSCTL_RES_ERR;
+ data->additional = flag == F_GARDEN
+ ? "requires username or session id"
+ : "requires session id and optional username";
- return PLUGIN_RET_STOP;
- }
+ return PLUGIN_RET_STOP;
+ }
- if (!(session = strtol(data->argv[1], &end, 10)) || *end)
- {
- if (flag)
- session = p->get_session_by_username(data->argv[1]);
- else
- session = 0; // can't ungarden by username
- }
+ if (!(session = strtol(data->argv[1], &end, 10)) || *end)
+ {
+ if (flag)
+ session = f->get_session_by_username(data->argv[1]);
+ else
+ session = 0; // can't ungarden by username
+ }
- if (session)
- s = p->get_session_by_id(session);
+ if (session)
+ s = f->get_session_by_id(session);
- if (!s || !s->ip)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "session not found";
- return PLUGIN_RET_STOP;
- }
+ if (!s || !s->ip)
+ {
+ data->response = NSCTL_RES_ERR;
+ data->additional = "session not found";
+ return PLUGIN_RET_STOP;
+ }
- if (s->walled_garden == flag)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = flag ? "already in walled garden" : "not in walled garden";
- return PLUGIN_RET_STOP;
- }
+ if (s->walled_garden == flag)
+ {
+ data->response = NSCTL_RES_ERR;
+ data->additional = flag ? "already in walled garden" : "not in walled garden";
+ return PLUGIN_RET_STOP;
+ }
- garden_session(s, flag, data->argc > 2 ? data->argv[2] : 0);
- p->session_changed(session);
+ garden_session(s, flag, data->argc > 2 ? data->argv[2] : 0);
+ f->session_changed(session);
- data->response = NSCTL_RES_OK;
- data->additional = 0;
+ data->response = NSCTL_RES_OK;
+ data->additional = 0;
- return PLUGIN_RET_STOP;
+ return PLUGIN_RET_STOP;
}
int plugin_become_master(void)
{
- int i;
- iam_master = 1; // We just became the master. Wow!
+ int i;
+ iam_master = 1; // We just became the master. Wow!
- for (i = 0; up_commands[i] && *up_commands[i]; i++)
- {
- p->log(3, 0, 0, "Running %s\n", up_commands[i]);
- system(up_commands[i]);
- }
+ for (i = 0; up_commands[i] && *up_commands[i]; i++)
+ {
+ f->log(3, 0, 0, "Running %s\n", up_commands[i]);
+ system(up_commands[i]);
+ }
- return PLUGIN_RET_OK;
+ return PLUGIN_RET_OK;
}
// Called for each active session after becoming master
int plugin_new_session_master(sessiont *s)
{
- if (s->walled_garden)
- garden_session(s, F_GARDEN, 0);
+ if (s->walled_garden)
+ garden_session(s, F_GARDEN, 0);
- return PLUGIN_RET_OK;
+ return PLUGIN_RET_OK;
}
int garden_session(sessiont *s, int flag, char *newuser)
{
- char cmd[2048];
- sessionidt sess;
+ char cmd[2048];
+ sessionidt sess;
+
+ if (!s) return 0;
+ if (!s->opened) return 0;
+
+ sess = f->get_id_by_session(s);
+ if (flag == F_GARDEN)
+ {
+ f->log(2, sess, s->tunnel, "Garden user %s (%s)\n", s->user,
+ f->fmtaddr(htonl(s->ip), 0));
+
+ snprintf(cmd, sizeof(cmd),
+ "iptables -t nat -A garden_users -s %s -j garden",
+ f->fmtaddr(htonl(s->ip), 0));
+
+ f->log(3, sess, s->tunnel, "%s\n", cmd);
+ system(cmd);
+ s->walled_garden = 1;
+ }
+ else
+ {
+ sessionidt other;
+ int count = 40;
+
+ // Normal User
+ f->log(2, sess, s->tunnel, "Un-Garden user %s (%s)\n", s->user, f->fmtaddr(htonl(s->ip), 0));
+ if (newuser)
+ {
+ snprintf(s->user, MAXUSER, "%s", newuser);
+ f->log(2, sess, s->tunnel, " Setting username to %s\n", s->user);
+ }
- if (!s) return 0;
- if (!s->opened) return 0;
+ // Kick off any duplicate usernames
+ // but make sure not to kick off ourself
+ if (s->ip && !s->die && (other = f->get_session_by_username(s->user)) &&
+ s != f->get_session_by_id(other))
+ {
+ f->sessionkill(other,
+ "Duplicate session when user released from walled garden");
+ }
+
+ /* Clean up counters */
+ s->pin = s->pout = 0;
+ s->cin = s->cout = 0;
+ s->cin_delta = s->cout_delta = 0;
+ s->cin_wrap = s->cout_wrap = 0;
- sess = p->get_id_by_session(s);
- if (flag == F_GARDEN)
+ snprintf(cmd, sizeof(cmd),
+ "iptables -t nat -D garden_users -s %s -j garden",
+ f->fmtaddr(htonl(s->ip), 0));
+
+ f->log(3, sess, s->tunnel, "%s\n", cmd);
+ while (--count)
{
- p->log(2, sess, s->tunnel, "Garden user %s (%s)\n", s->user, p->fmtaddr(htonl(s->ip), 0));
- snprintf(cmd, sizeof(cmd), "iptables -t nat -A garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
- p->log(3, sess, s->tunnel, "%s\n", cmd);
- system(cmd);
- s->walled_garden = 1;
+ int status = system(cmd);
+ if (WEXITSTATUS(status) != 0) break;
}
- else
+
+ s->walled_garden = 0;
+
+ if (flag != F_CLEANUP)
{
- sessionidt other;
- int count = 40;
-
- // Normal User
- p->log(2, sess, s->tunnel, "Un-Garden user %s (%s)\n", s->user, p->fmtaddr(htonl(s->ip), 0));
- if (newuser)
- {
- snprintf(s->user, MAXUSER, "%s", newuser);
- p->log(2, sess, s->tunnel, " Setting username to %s\n", s->user);
- }
-
- // Kick off any duplicate usernames
- // but make sure not to kick off ourself
- if (s->ip && !s->die && (other = p->get_session_by_username(s->user)) && s != p->get_session_by_id(other)) {
- p->sessionkill(other, "Duplicate session when user released from walled garden");
- }
- /* Clean up counters */
- s->pin = s->pout = 0;
- s->cin = s->cout = 0;
- s->cin_delta = s->cout_delta = 0;
- s->cin_wrap = s->cout_wrap = 0;
-
- snprintf(cmd, sizeof(cmd), "iptables -t nat -D garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
- p->log(3, sess, s->tunnel, "%s\n", cmd);
- while (--count)
- {
- int status = system(cmd);
- if (WEXITSTATUS(status) != 0) break;
- }
-
- s->walled_garden = 0;
-
- if (flag != F_CLEANUP)
- {
- /* OK, we're up! */
- uint16_t r = p->radiusnew(p->get_id_by_session(s));
- if (r) p->radiussend(r, RADIUSSTART);
- }
+ /* OK, we're up! */
+ uint16_t r = f->radiusnew(f->get_id_by_session(s));
+ if (r) f->radiussend(r, RADIUSSTART);
}
+ }
- return 1;
+ return 1;
}
int plugin_init(struct pluginfuncs *funcs)
{
- FILE *tables;
- int found_nat = 0;
+ FILE *tables;
+ int found_nat = 0;
- if (!funcs)
- return 0;
+ if (!funcs)
+ return 0;
- p = funcs;
+ f = funcs;
- if ((tables = fopen("/proc/net/ip_tables_names", "r")))
- {
- char buf[1024];
- while (fgets(buf, sizeof(buf), tables) && !found_nat)
- found_nat = !strcmp(buf, "nat\n");
+ if ((tables = fopen("/proc/net/ip_tables_names", "r")))
+ {
+ char buf[1024];
+ while (fgets(buf, sizeof(buf), tables) && !found_nat)
+ found_nat = !strcmp(buf, "nat\n");
- fclose(tables);
- }
+ fclose(tables);
+ }
- /* master killed/crashed? */
- if (found_nat)
+ /* master killed/crashed? */
+ if (found_nat)
+ {
+ int i;
+ for (i = 0; down_commands[i] && *down_commands[i]; i++)
{
- int i;
- for (i = 0; down_commands[i] && *down_commands[i]; i++)
- {
- p->log(3, 0, 0, "Running %s\n", down_commands[i]);
- system(down_commands[i]);
- }
+ f->log(3, 0, 0, "Running %s\n", down_commands[i]);
+ system(down_commands[i]);
}
+ }
- return 1;
+ return 1;
}
void plugin_done()
{
- int i;
+ int i;
- if (!iam_master) // Never became master. nothing to do.
- return;
+ if (!iam_master) // Never became master. nothing to do.
+ return;
- for (i = 0; down_commands[i] && *down_commands[i]; i++)
- {
- p->log(3, 0, 0, "Running %s\n", down_commands[i]);
- system(down_commands[i]);
- }
+ for (i = 0; down_commands[i] && *down_commands[i]; i++)
+ {
+ f->log(3, 0, 0, "Running %s\n", down_commands[i]);
+ system(down_commands[i]);
+ }
}
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
// vim: sw=8 ts=8
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.143 2005-10-11 07:06:56 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.144 2005-10-11 09:04:53 bodea Exp $";
#include <arpa/inet.h>
#include <assert.h>
"plugin_control",
"plugin_radius_response",
"plugin_radius_reset",
+ "plugin_radius_account",
"plugin_become_master",
"plugin_new_session_master",
};
enum
{
- PLUGIN_PRE_AUTH = 1,
- PLUGIN_POST_AUTH,
- PLUGIN_PACKET_RX,
- PLUGIN_PACKET_TX,
- PLUGIN_TIMER,
- PLUGIN_NEW_SESSION,
- PLUGIN_KILL_SESSION,
- PLUGIN_CONTROL,
- PLUGIN_RADIUS_RESPONSE,
- PLUGIN_RADIUS_RESET,
- PLUGIN_BECOME_MASTER,
- PLUGIN_NEW_SESSION_MASTER,
+ PLUGIN_PRE_AUTH = 1,
+ PLUGIN_POST_AUTH,
+ PLUGIN_PACKET_RX,
+ PLUGIN_PACKET_TX,
+ PLUGIN_TIMER,
+ PLUGIN_NEW_SESSION,
+ PLUGIN_KILL_SESSION,
+ PLUGIN_CONTROL,
+ PLUGIN_RADIUS_RESPONSE,
+ PLUGIN_RADIUS_RESET,
+ PLUGIN_RADIUS_ACCOUNT,
+ PLUGIN_BECOME_MASTER,
+ PLUGIN_NEW_SESSION_MASTER,
};
#define PLUGIN_RET_ERROR 0
struct pluginfuncs
{
- void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...);
- void (*log_hex)(int level, const char *title, const uint8_t *data, int maxsize);
- char *(*fmtaddr)(in_addr_t addr, int n);
- sessionidt (*get_session_by_username)(char *username);
- sessiont *(*get_session_by_id)(sessionidt s);
- sessionidt (*get_id_by_session)(sessiont *s);
- uint16_t (*radiusnew)(sessionidt s);
- void (*radiussend)(uint16_t r, uint8_t state);
- void *(*getconfig)(char *key, enum config_typet type);
- void (*sessionshutdown)(sessionidt s, char *reason, int result, int error);
- void (*sessionkill)(sessionidt s, char *reason);
- void (*throttle)(sessionidt s, int rate_in, int rate_out);
- int (*session_changed)(int sid);
+ void (*log)(int level, sessionidt s, tunnelidt t, const char *format, ...);
+ void (*log_hex)(int level, const char *title, const uint8_t *data, int maxsize);
+ char *(*fmtaddr)(in_addr_t addr, int n);
+ sessionidt (*get_session_by_username)(char *username);
+ sessiont *(*get_session_by_id)(sessionidt s);
+ sessionidt (*get_id_by_session)(sessiont *s);
+ uint16_t (*radiusnew)(sessionidt s);
+ void (*radiussend)(uint16_t r, uint8_t state);
+ void *(*getconfig)(char *key, enum config_typet type);
+ void (*sessionshutdown)(sessionidt s, char *reason, int result, int error);
+ void (*sessionkill)(sessionidt s, char *reason);
+ void (*throttle)(sessionidt s, int rate_in, int rate_out);
+ int (*session_changed)(int sid);
};
struct param_pre_auth
{
- tunnelt *t;
- sessiont *s;
- char *username;
- char *password;
- int protocol;
- int continue_auth;
+ tunnelt *t;
+ sessiont *s;
+ char *username;
+ char *password;
+ int protocol;
+ int continue_auth;
};
struct param_post_auth
{
- tunnelt *t;
- sessiont *s;
- char *username;
- short auth_allowed;
- int protocol;
+ tunnelt *t;
+ sessiont *s;
+ char *username;
+ short auth_allowed;
+ int protocol;
};
struct param_packet_rx
{
- tunnelt *t;
- sessiont *s;
- char *buf;
- int len;
+ tunnelt *t;
+ sessiont *s;
+ char *buf;
+ int len;
};
struct param_packet_tx
{
- tunnelt *t;
- sessiont *s;
- char *buf;
- int len;
+ tunnelt *t;
+ sessiont *s;
+ char *buf;
+ int len;
};
struct param_timer
{
- time_t time_now;
+ time_t time_now;
};
struct param_control
{
- int iam_master;
- int argc;
- char **argv;
- // output
- int response;
- char *additional;
+ int iam_master;
+ int argc;
+ char **argv;
+ // output
+ int response;
+ char *additional;
};
struct param_new_session
{
- tunnelt *t;
- sessiont *s;
+ tunnelt *t;
+ sessiont *s;
};
struct param_kill_session
{
- tunnelt *t;
- sessiont *s;
+ tunnelt *t;
+ sessiont *s;
};
struct param_radius_response
{
- tunnelt *t;
- sessiont *s;
- char *key;
- char *value;
+ tunnelt *t;
+ sessiont *s;
+ char *key;
+ char *value;
};
struct param_radius_reset
{
- tunnelt *t;
- sessiont *s;
+ tunnelt *t;
+ sessiont *s;
+};
+
+struct param_radius_account
+{
+ tunnelt *t;
+ sessiont *s;
+ uint8_t **packet;
};
#endif /* __PLUGIN_H__ */
// L2TPNS Radius Stuff
-char const *cvs_id_radius = "$Id: radius.c,v 1.43 2005-10-11 02:27:40 foonly Exp $";
+char const *cvs_id_radius = "$Id: radius.c,v 1.44 2005-10-11 09:04:53 bodea Exp $";
#include <time.h>
#include <stdio.h>
p[1] = 6;
*(uint32_t *) (p + 2) = htonl(session[s].cout_wrap);
p += p[1];
- }
-
- if (session[s].snoop_ip && session[s].snoop_port)
- {
- *p = 26; // vendor-specific
- *(uint32_t *) (p + 2) = htonl(9); // Cisco
- p[6] = 1; // Cisco-AVPair
- p[7] = 2 + sprintf((char *) p + 8, "intercept=%s:%d",
- fmtaddr(session[s].snoop_ip, 0), session[s].snoop_port);
- p[1] = p[7] + 6;
- p += p[1];
+ {
+ struct param_radius_account acct = { &tunnel[session[s].tunnel], &session[s], &p };
+ run_plugins(PLUGIN_RADIUS_ACCOUNT, &acct);
+ }
}
}
}
/* session control */
-char const *cvs_id = "$Id: sessionctl.c,v 1.3 2005-06-28 14:48:28 bodea Exp $";
+char const *cvs_id = "$Id: sessionctl.c,v 1.4 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
char *plugin_control_help[] = {
" drop USER|SID [REASON] Shutdown user session",
}
if (!(session = strtol(data->argv[1], &end, 10)) || *end)
- session = p->get_session_by_username(data->argv[1]);
+ session = f->get_session_by_username(data->argv[1]);
if (session)
- s = p->get_session_by_id(session);
+ s = f->get_session_by_id(session);
if (!s || !s->ip)
{
reason = "Requested by administrator.";
if (data->argv[0][0] == 'd')
- p->sessionshutdown(session, reason, 3, 0);
+ f->sessionshutdown(session, reason, 3, 0);
else
- p->sessionkill(session, reason);
+ f->sessionkill(session, reason);
data->response = NSCTL_RES_OK;
data->additional = 0;
int plugin_init(struct pluginfuncs *funcs)
{
- return ((p = funcs)) ? 1 : 0;
+ return ((f = funcs)) ? 1 : 0;
}
/* fudge up session rx speed if not set */
-char const *cvs_id = "$Id: setrxspeed.c,v 1.3 2004-11-17 08:23:35 bodea Exp $";
+char const *cvs_id = "$Id: setrxspeed.c,v 1.4 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
int plugin_post_auth(struct param_post_auth *data)
{
- if (!data->auth_allowed) return PLUGIN_RET_OK;
-
- if (!data->s->rx_connect_speed)
- {
- switch (data->s->tx_connect_speed)
- {
- case 256 :
- data->s->rx_connect_speed = 64;
- break;
- case 512 :
- data->s->rx_connect_speed = 128;
- break;
- case 1500 :
- data->s->rx_connect_speed = 256;
- break;
- }
- }
- return PLUGIN_RET_OK;
+ if (!data->auth_allowed)
+ return PLUGIN_RET_OK;
+
+ if (data->s->rx_connect_speed)
+ return PLUGIN_RET_OK;
+
+ switch (data->s->tx_connect_speed)
+ {
+ case 256:
+ data->s->rx_connect_speed = 64;
+ break;
+
+ case 512:
+ data->s->rx_connect_speed = 128;
+ break;
+
+ case 1500:
+ data->s->rx_connect_speed = 256;
+ break;
+ }
+
+ return PLUGIN_RET_OK;
}
int plugin_init(struct pluginfuncs *funcs)
{
- return ((p = funcs)) ? 1 : 0;
+ return ((f = funcs)) ? 1 : 0;
}
/* snoop control */
-char const *cvs_id = "$Id: snoopctl.c,v 1.6 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: snoopctl.c,v 1.7 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
char *plugin_control_help[] = {
- " snoop USER|SID IP PORT Intercept user traffic",
- " unsnoop USER|SID Stop intercepting user",
- 0
+ " snoop USER|SID IP PORT Intercept user traffic",
+ " unsnoop USER|SID Stop intercepting user",
+ 0
};
int plugin_control(struct param_control *data)
{
- sessionidt session;
- sessiont *s = 0;
- int flag;
- char *end;
+ sessionidt session;
+ sessiont *s = 0;
+ int flag;
+ char *end;
- if (data->argc < 1)
- return PLUGIN_RET_OK;
+ if (data->argc < 1)
+ return PLUGIN_RET_OK;
- if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop"))
- return PLUGIN_RET_OK; // not for us
+ if (strcmp(data->argv[0], "snoop") && strcmp(data->argv[0], "unsnoop"))
+ return PLUGIN_RET_OK; // not for us
- if (!data->iam_master)
- return PLUGIN_RET_NOTMASTER;
+ if (!data->iam_master)
+ return PLUGIN_RET_NOTMASTER;
- flag = data->argv[0][0] != 'u';
+ flag = data->argv[0][0] != 'u';
- if (flag)
+ if (flag)
+ {
+ if (data->argc != 4)
{
- if (data->argc != 4)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "requires username or session id and host, port";
- return PLUGIN_RET_STOP;
- }
+ data->response = NSCTL_RES_ERR;
+ data->additional = "requires username or session id and host, port";
+ return PLUGIN_RET_STOP;
}
- else
+ }
+ else
+ {
+ if (data->argc != 2)
{
- if (data->argc != 2)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "requires username or session id";
- return PLUGIN_RET_STOP;
- }
+ data->response = NSCTL_RES_ERR;
+ data->additional = "requires username or session id";
+ return PLUGIN_RET_STOP;
}
+ }
- if (!(session = strtol(data->argv[1], &end, 10)) || *end)
- session = p->get_session_by_username(data->argv[1]);
+ if (!(session = strtol(data->argv[1], &end, 10)) || *end)
+ session = f->get_session_by_username(data->argv[1]);
- if (session)
- s = p->get_session_by_id(session);
+ if (session)
+ s = f->get_session_by_id(session);
- if (!s || !s->ip)
+ if (!s || !s->ip)
+ {
+ data->response = NSCTL_RES_ERR;
+ data->additional = "session not found";
+ return PLUGIN_RET_STOP;
+ }
+
+ if (flag)
+ {
+ in_addr_t ip = inet_addr(data->argv[2]);
+ uint16_t port = atoi(data->argv[3]);
+
+ if (!ip || ip == INADDR_NONE)
{
- data->response = NSCTL_RES_ERR;
- data->additional = "session not found";
- return PLUGIN_RET_STOP;
+ data->response = NSCTL_RES_ERR;
+ data->additional = "invalid ip address";
+ return PLUGIN_RET_STOP;
}
- if (flag)
+ if (!port)
{
- in_addr_t ip = inet_addr(data->argv[2]);
- uint16_t port = atoi(data->argv[3]);
-
- if (!ip || ip == INADDR_NONE)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "invalid ip address";
- return PLUGIN_RET_STOP;
- }
-
- if (!port)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "invalid port";
- return PLUGIN_RET_STOP;
- }
-
- if (ip == s->snoop_ip && port == s->snoop_port)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "already intercepted";
- return PLUGIN_RET_STOP;
- }
-
- s->snoop_ip = ip;
- s->snoop_port = port;
+ data->response = NSCTL_RES_ERR;
+ data->additional = "invalid port";
+ return PLUGIN_RET_STOP;
}
- else
+
+ if (ip == s->snoop_ip && port == s->snoop_port)
{
- if (!s->snoop_ip)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "not intercepted";
- return PLUGIN_RET_STOP;
- }
-
- s->snoop_ip = 0;
- s->snoop_port = 0;
+ data->response = NSCTL_RES_ERR;
+ data->additional = "already intercepted";
+ return PLUGIN_RET_STOP;
}
- p->session_changed(session);
+ s->snoop_ip = ip;
+ s->snoop_port = port;
+ }
+ else
+ {
+ if (!s->snoop_ip)
+ {
+ data->response = NSCTL_RES_ERR;
+ data->additional = "not intercepted";
+ return PLUGIN_RET_STOP;
+ }
- data->response = NSCTL_RES_OK;
- data->additional = 0;
+ s->snoop_ip = 0;
+ s->snoop_port = 0;
+ }
- return PLUGIN_RET_STOP;
+ f->session_changed(session);
+
+ data->response = NSCTL_RES_OK;
+ data->additional = 0;
+
+ return PLUGIN_RET_STOP;
}
int plugin_init(struct pluginfuncs *funcs)
{
- return ((p = funcs)) ? 1 : 0;
+ return ((f = funcs)) ? 1 : 0;
}
/* strip domain part of username before sending RADIUS requests */
-char const *cvs_id = "$Id: stripdomain.c,v 1.7 2004-11-29 02:17:18 bodea Exp $";
+char const *cvs_id = "$Id: stripdomain.c,v 1.8 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
int plugin_pre_auth(struct param_pre_auth *data)
{
- char *x;
+ char *p;
- if (!data->continue_auth) return PLUGIN_RET_STOP;
+ if (!data->continue_auth) return PLUGIN_RET_STOP;
- // Strip off @domain
- if ((x = strchr(data->username, '@')))
- {
- p->log(3, 0, 0, "Stripping off trailing domain name \"%s\"\n", x);
- *x = 0;
- }
+ // Strip off @domain
+ if ((p = strchr(data->username, '@')))
+ {
+ f->log(3, 0, 0, "Stripping off trailing domain name \"%s\"\n", p);
+ *p = 0;
+ }
- return PLUGIN_RET_OK;
+ return PLUGIN_RET_OK;
}
int plugin_init(struct pluginfuncs *funcs)
{
- return ((p = funcs)) ? 1 : 0;
+ return ((f = funcs)) ? 1 : 0;
}
/* throttle control */
-char const *cvs_id = "$Id: throttlectl.c,v 1.8 2005-10-11 07:59:09 bodea Exp $";
+char const *cvs_id = "$Id: throttlectl.c,v 1.9 2005-10-11 09:04:53 bodea Exp $";
int plugin_api_version = PLUGIN_API_VERSION;
-static struct pluginfuncs *p = 0;
+static struct pluginfuncs *f = 0;
char *plugin_control_help[] = {
- " throttle USER|SID [RATE|[in|out] RATE ...] Throttle user traffic",
- " unthrottle USER|SID Stop throttling user",
- 0
+ " throttle USER|SID [RATE|[in|out] RATE ...] Throttle user traffic",
+ " unthrottle USER|SID Stop throttling user",
+ 0
};
int plugin_control(struct param_control *data)
{
- sessionidt session;
- sessiont *s = 0;
- int flag;
- char *end;
- int rate_in = 0;
- int rate_out = 0;
+ sessionidt session;
+ sessiont *s = 0;
+ int flag;
+ char *end;
+ int rate_in = 0;
+ int rate_out = 0;
- if (data->argc < 1)
- return PLUGIN_RET_OK;
+ if (data->argc < 1)
+ return PLUGIN_RET_OK;
- if (strcmp(data->argv[0], "throttle")
- && strcmp(data->argv[0], "unthrottle"))
- return PLUGIN_RET_OK; // not for us
+ if (strcmp(data->argv[0], "throttle") &&
+ strcmp(data->argv[0], "unthrottle"))
+ return PLUGIN_RET_OK; // not for us
- if (!data->iam_master)
- return PLUGIN_RET_NOTMASTER;
+ if (!data->iam_master)
+ return PLUGIN_RET_NOTMASTER;
- flag = data->argv[0][0] == 't';
+ flag = data->argv[0][0] == 't';
- if (flag)
+ if (flag)
+ {
+ if (data->argc < 2 || data->argc > 6)
{
- if (data->argc < 2 || data->argc > 6)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "requires username or session id and optional rate(s)";
- return PLUGIN_RET_STOP;
- }
+ data->response = NSCTL_RES_ERR;
+ data->additional = "requires username or session id and optional rate(s)";
+ return PLUGIN_RET_STOP;
}
- else
+ }
+ else
+ {
+ if (data->argc != 2)
{
- if (data->argc != 2)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "requires username or session id";
- return PLUGIN_RET_STOP;
- }
+ data->response = NSCTL_RES_ERR;
+ data->additional = "requires username or session id";
+ return PLUGIN_RET_STOP;
}
+ }
- if (!(session = strtol(data->argv[1], &end, 10)) || *end)
- session = p->get_session_by_username(data->argv[1]);
+ if (!(session = strtol(data->argv[1], &end, 10)) || *end)
+ session = f->get_session_by_username(data->argv[1]);
- if (session)
- s = p->get_session_by_id(session);
+ if (session)
+ s = f->get_session_by_id(session);
- if (!s || !s->ip)
+ if (!s || !s->ip)
+ {
+ data->response = NSCTL_RES_ERR;
+ data->additional = "session not found";
+ return PLUGIN_RET_STOP;
+ }
+
+ if (flag)
+ {
+ rate_in = rate_out = -1;
+ if (data->argc == 2)
{
- data->response = NSCTL_RES_ERR;
- data->additional = "session not found";
- return PLUGIN_RET_STOP;
+ unsigned long *rate = f->getconfig("throttle_speed", UNSIGNED_LONG);
+ rate_in = rate_out = *rate;
}
-
- if (flag)
+ else if (data->argc == 3)
{
- rate_in = rate_out = -1;
- if (data->argc == 2)
+ rate_in = rate_out = atoi(data->argv[2]);
+ }
+ else
+ {
+ int i;
+ for (i = 2; i < data->argc - 1; i += 2)
+ {
+ int len = strlen(data->argv[i]);
+ if (!strncmp(data->argv[i], "in", len))
{
- unsigned long *rate = p->getconfig("throttle_speed", UNSIGNED_LONG);
- rate_in = rate_out = *rate;
+ rate_in = atoi(data->argv[i+1]);
}
- else if (data->argc == 3)
+ else if (!strncmp(data->argv[i], "out", len))
{
- rate_in = rate_out = atoi(data->argv[2]);
+ rate_out = atoi(data->argv[i+1]);
}
else
{
- int i;
- for (i = 2; i < data->argc - 1; i += 2)
- {
- int len = strlen(data->argv[i]);
- if (!strncmp(data->argv[i], "in", len))
- {
- rate_in = atoi(data->argv[i+1]);
- }
- else if (!strncmp(data->argv[i], "out", len))
- {
- rate_out = atoi(data->argv[i+1]);
- }
- else
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "invalid rate";
- return PLUGIN_RET_STOP;
- }
- }
- }
-
- if (!rate_in || !rate_out)
- {
- data->response = NSCTL_RES_ERR;
- data->additional = "invalid rate";
- return PLUGIN_RET_STOP;
+ data->response = NSCTL_RES_ERR;
+ data->additional = "invalid rate";
+ return PLUGIN_RET_STOP;
}
+ }
}
- if (rate_in != -1 && rate_in == s->throttle_in &&
- rate_out != -1 && rate_out == s->throttle_out)
+ if (!rate_in || !rate_out)
{
- data->response = NSCTL_RES_ERR;
- data->additional = flag ? "already throttled" : "not throttled";
- return PLUGIN_RET_STOP;
+ data->response = NSCTL_RES_ERR;
+ data->additional = "invalid rate";
+ return PLUGIN_RET_STOP;
}
+ }
+
+ if (rate_in != -1 && rate_in == s->throttle_in &&
+ rate_out != -1 && rate_out == s->throttle_out)
+ {
+ data->response = NSCTL_RES_ERR;
+ data->additional = flag ? "already throttled" : "not throttled";
+ return PLUGIN_RET_STOP;
+ }
- p->throttle(session, rate_in, rate_out);
- p->session_changed(session);
+ f->throttle(session, rate_in, rate_out);
+ f->session_changed(session);
- data->response = NSCTL_RES_OK;
- data->additional = 0;
+ data->response = NSCTL_RES_OK;
+ data->additional = 0;
- return PLUGIN_RET_STOP;
+ return PLUGIN_RET_STOP;
}
int plugin_init(struct pluginfuncs *funcs)
{
- return ((p = funcs)) ? 1 : 0;
+ return ((f = funcs)) ? 1 : 0;
}