From e5067d7cd967cb17067de24a162306b79f432b20 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 24 Jun 2015 04:23:46 +0200 Subject: Import newax25-2.4.3.patch.1.bz2 And cleanup the *.orig and *.rej files and whitespace errors that are part of the original patch. Signed-off-by: Ralf Baechle --- net/ax25/ax25_uid.c | 197 +++++++++++++++++++++++++++------------------------- 1 file changed, 101 insertions(+), 96 deletions(-) (limited to 'net/ax25/ax25_uid.c') diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c index 603d8b8cc..4a41313de 100644 --- a/net/ax25/ax25_uid.c +++ b/net/ax25/ax25_uid.c @@ -1,124 +1,146 @@ /* - * AX.25 release 037 + * ax25_uid.c: Callsign/UID mapper. This is in kernel space for security on mul * - * This code REQUIRES 2.1.15 or higher/ NET3.038 + * Authors: Matthias Welwarsky (DG2FEF) + * Joerg Reuter (DL1BKE) * - * This module: - * This module 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. + * Comment: * - * History - * AX.25 036 Jonathan(G4KLX) Split from af_ax25.c. + * Changelog: + * 2001-02-06 Joerg Reuter DL1BKE + * extended policy scheme implemented + * + * License: This module 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. */ -#include #include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include -/* - * Callsign/UID mapper. This is in kernel space for security on multi-amateur machines. - */ +#include + +#include "af_ax25.h" +t_ax25_uid_policy ax25_uid_policy = AX25_UID_POLICY_ARBITRARY_CALLSIGN; static ax25_uid_assoc *ax25_uid_list; -int ax25_uid_policy = 0; +ax25_address *ax25_find_by_uid(uid_t uid) +{ + ax25_uid_assoc *a; -ax25_address *ax25_findbyuid(uid_t uid) + for (a = ax25_uid_list; a != NULL; a = a->next) { + if (a->uid == uid) + return &a->call; + } + + return NULL; +} + +ax25_address *ax25_find_match_for_uid(uid_t uid, ax25_address *provided, char *device) { - ax25_uid_assoc *ax25_uid; + int res; + ax25_uid_assoc *a; + + /* no callsign given? find one! */ + if (ax25cmp(provided, &null_ax25_address) == 0) + { + for (a = ax25_uid_list; a != NULL; a = a->next) { + if (a->uid == uid) + { + if (device != NULL && strcmp(device, a->device)) + continue; + return &a->call; + } + } + } + + /* any user can choose an arbitrary callsign? */ + if (ax25_uid_policy == 0) + return provided; + + /* walk the list... */ + for (a = ax25_uid_list; a != NULL ; a = a->next) { + if (a->uid == uid) + { + /* limited to a device? */ + if (device != NULL && strcmp(device, a->device)) + continue; - for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { - if (ax25_uid->uid == uid) - return &ax25_uid->call; + /* user can choose any callsign? */ + if (ax25cmp(&a->call, &null_ax25_address) == 0) + return provided; + + res = ax25cmp(provided, &a->call); + + /* exact match, or only SSID differ (when allowed): okay */ + if ( res == 0 || + (res == 2 && ax25_uid_policy == AX25_UID_POLICY_ANY_SSID) ) + return provided; + } } return NULL; } +/* + * TODO: move this stuff to procfs + * general idea: echo "add 503 dl1bke scc0" >/proc/net/ax25_calls + * echo "del 502 dk0tux *" >/proc/net/ax25_calls + */ + int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) { - ax25_uid_assoc *s, *ax25_uid; - unsigned long flags; + ax25_uid_assoc *a; switch (cmd) { case SIOCAX25GETUID: - for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { - if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) - return ax25_uid->uid; + for (a = ax25_uid_list; a != NULL; a = a->next) { + if (ax25cmp(&sax->sax25_call, &a->call) == 0) + return a->uid; } return -ENOENT; case SIOCAX25ADDUID: if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (ax25_findbyuid(sax->sax25_uid)) + if (ax25_find_by_uid(sax->sax25_uid)) return -EEXIST; if (sax->sax25_uid == 0) return -EINVAL; - if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL) + a = (ax25_uid_assoc *)kmalloc(sizeof(*a), GFP_KERNEL); + if (a == NULL) return -ENOMEM; - ax25_uid->uid = sax->sax25_uid; - ax25_uid->call = sax->sax25_call; - save_flags(flags); cli(); - ax25_uid->next = ax25_uid_list; - ax25_uid_list = ax25_uid; - restore_flags(flags); + a->uid = sax->sax25_uid; + a->call = sax->sax25_call; + a->device[0] = '\0'; + a->next = ax25_uid_list; + ax25_uid_list = a; return 0; - case SIOCAX25DELUID: + case SIOCAX25DELUID: { + ax25_uid_assoc **l; + if (!capable(CAP_NET_ADMIN)) return -EPERM; - for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { - if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) - break; - } - if (ax25_uid == NULL) - return -ENOENT; - save_flags(flags); cli(); - if ((s = ax25_uid_list) == ax25_uid) { - ax25_uid_list = s->next; - restore_flags(flags); - kfree(ax25_uid); - return 0; - } - while (s != NULL && s->next != NULL) { - if (s->next == ax25_uid) { - s->next = ax25_uid->next; - restore_flags(flags); - kfree(ax25_uid); + l = &ax25_uid_list; + while ((*l) != NULL) { + if (ax25cmp(&((*l)->call), &(sax->sax25_call)) == 0) { + a = *l; + *l = (*l)->next; + kfree(a); return 0; } - s = s->next; + + l = &((*l)->next); } - restore_flags(flags); return -ENOENT; + } default: return -EINVAL; @@ -127,19 +149,17 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) return -EINVAL; /*NOTREACHED */ } -int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length) +int ax25_cs_get_info(char *buffer, char **start, off_t offset, int length) { ax25_uid_assoc *pt; int len = 0; off_t pos = 0; off_t begin = 0; - cli(); - len += sprintf(buffer, "Policy: %d\n", ax25_uid_policy); for (pt = ax25_uid_list; pt != NULL; pt = pt->next) { - len += sprintf(buffer + len, "%6d %s\n", pt->uid, ax2asc(&pt->call)); + len += sprintf(buffer + len, "%6d %-9s %s\n", pt->uid, ax2asc(&pt->call), pt->device); pos = begin + len; @@ -152,7 +172,6 @@ int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length) break; } - sti(); *start = buffer + (offset - begin); len -= offset - begin; @@ -162,17 +181,3 @@ int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length) return len; } -/* - * Free all memory associated with UID/Callsign structures. - */ -void __exit ax25_uid_free(void) -{ - ax25_uid_assoc *s, *ax25_uid = ax25_uid_list; - - while (ax25_uid != NULL) { - s = ax25_uid; - ax25_uid = ax25_uid->next; - - kfree(s); - } -} -- cgit v1.2.3