]> git.decadent.org.uk Git - ap-utils.git/blob - src/ap-auth.c
Update config.{sub,guess} in the right place at build time - closes: #534825
[ap-utils.git] / src / ap-auth.c
1 /*
2  *      ap-auth.c from Access Point SNMP Utils for Linux
3  *
4  * Copyright (c) 2004 Teemu Kiviniemi <teemuki at fotokone.fi>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License Version 2 from
8  * June 1991 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20 #include <stdio.h>
21 #include <fcntl.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
27 #if defined (__GLIBC__)
28 #include <libgen.h>
29 #endif
30 #include "ap-utils.h"
31
32 #define ERROR_PACKET _("AuthorizedMacTableString packet error")
33 #define ERROR_DATA _("Invalid data in source file")
34 #define ERROR_FILE_OPEN _("Can't open file")
35 #define ERROR_FILE_WRITE _("Can't write to file")
36 #define ERROR_FILE_CLOSE _("Error closing file")
37
38 short ap_type;
39 char *community = NULL;
40 struct in_addr ap_ip;
41
42 void usage()
43 {
44     printf(_("\nUsage:\n"));
45     printf(_("\tap-auth -i ip -c community -d filename [-h]\n"));
46     printf(_("\tap-auth -i ip -c community -u filename [-h]\n\n"));
47     printf(_("Change accesspoint's list of authorised MAC addresses\n\n"));
48     printf(_("-i ip        - AP ip address\n"));
49     printf(_("-c community - SNMP community string\n"));
50     printf(_("-d filename  - download list of authorised MAC addresses from AP"
51         " to a file\n"));
52     printf(_("-u filename  - upload list of authorised MAC addresses from"
53         " a file to AP\n"));
54     printf(_("-h           - print this help screen\n\n"));
55     printf(_("ap-auth %s Copyright (c) 2004 Teemu Kiviniemi\n\n"),
56            VERSION);
57 }
58
59 int write_addr (FILE *f, const struct MacListStat *n)
60 {
61     if (fprintf (f, "%02x%02x%02x%02x%02x%02x\n", n->addr[0], n->addr[1],
62                                                   n->addr[2], n->addr[3],
63                                                   n->addr[4], n->addr[5])
64                                                 != 13)
65         return 1;
66
67     return 0;
68 }
69
70 int get_addr (struct MacListStat *ml, char *addr)
71 {
72     int i;
73     char tmp[3];
74
75     if (strlen (addr) != 12)
76         return 1;
77
78     tmp[2] = '\0';
79
80     for (i = 0; i < 6 ; i++) {
81         tmp[0] = addr[2 * i];
82         tmp[1] = addr[2 * i + 1];
83         ml->addr[i] = strtol (tmp, NULL, 16);
84     }
85
86     return 0;
87 }
88
89 int main(int argc, char **argv)
90 {
91     extern char *optarg;
92     extern int optind;
93     extern int opterr;
94     extern int optopt;
95     int opt = 0;
96     int mode = 0; /* 1 = download, 2 = upload */
97     FILE *f;
98     char *filename = NULL;
99
100     struct AuthorizedMacTableString {
101         unsigned int short Action;
102         unsigned int short NumOfAllTableAddresses;
103         unsigned int short NumOfCurrentAddress;
104         unsigned char MacAddress[6];
105     } *AuthMac = NULL, get;
106
107     struct MacListStat *first = NULL, *curr = NULL;
108
109     char sysDescr_NWN[] = {
110         0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00
111     };
112     char sysDescr_ATMEL[] = {
113         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
114     };
115     char AutorizedMac_ATMEL[] = {
116         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x02, 0x00
117     };
118
119     int total_mac, mac_num = 0;
120     varbind varbinds[1];
121     char mac_tmp[13];
122     char *cp;
123     struct MacListStat ml_tmp;
124     int i, tmp;
125
126 #ifdef HAVE_GETTEXT
127     setlocale(LC_ALL, "");
128     bindtextdomain("ap-utils", LOCALEDIR);
129     textdomain("ap-utils");
130 #endif
131
132     do {
133         opterr = 0;
134         switch (opt = getopt(argc, argv, "i:c:d:u:")) {
135         case 'i':
136             for (cp = optarg, i = 0; *cp && (cp = index(cp, '.')); cp++, i++);
137             if (i < 3 || inet_aton(optarg, &ap_ip) == 0) {
138                 printf(_("Error: invalid IP-address.\n"));
139                 return 1;
140             }
141             break;
142         case 'c':
143             community = malloc(strlen(optarg) + 1);
144             strncpy(community, optarg, strlen(optarg) + 1);
145             break;
146         case 'd':
147             filename = malloc(strlen(optarg) + 1);
148             strncpy(filename, optarg, strlen(optarg) + 1);
149             mode = 1;
150             break;
151         case 'u':
152             filename = malloc(strlen(optarg) + 1);
153             strncpy(filename, optarg, strlen(optarg) + 1);
154             mode = 2;
155             break;
156         case -1:
157             break;
158         default:
159             usage();
160             return 1;
161         }
162     } while (opt != -1);
163
164     if (!community) {
165         usage();
166         return 1;
167     }
168
169     /*
170      * Part detecting ap_type (ATMEL AP MIB type) follows.
171      * We could use get_mib_details() here with advantage, but it would
172      * have to involve 1. putting it to separate file in lib/ and
173      * 2. patch it so it would not contain curses-related commands (TODO)
174      */
175
176     /* determine private MIB type according to enterprises ID */
177     varbinds[0].oid = sysDescr_NWN;
178     varbinds[0].len_oid = sizeof(sysDescr_NWN);
179     varbinds[0].value = NULL;
180     varbinds[0].len_val = 0;
181     varbinds[0].type = NULL_VALUE;
182     if (snmp(varbinds, 1, GET) > 0) {
183         ap_type = NWN;
184     } else {
185         varbinds[0].oid = sysDescr_ATMEL;
186         varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
187         varbinds[0].value = NULL;
188         varbinds[0].len_val = 0;
189         varbinds[0].type = NULL_VALUE;
190         if (snmp(varbinds, 1, GET) > 0) {
191             ap_type = ATMEL410;
192         } else {
193             sysDescr_ATMEL[5] = 0xE0;
194             sysDescr_ATMEL[6] = 0x3E;
195             varbinds[0].oid = sysDescr_ATMEL;
196             varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
197             varbinds[0].value = NULL;
198             varbinds[0].len_val = 0;
199             varbinds[0].type = NULL_VALUE;
200             if (snmp(varbinds, 1, GET) > 0) {
201                 ap_type = ATMEL12350;
202             } else {
203                 printf(_("Unable to determine AP MIB type "
204                     "(no response from AP)."));
205                 return 1;
206             }
207         }
208     }
209
210     if (ap_type == NWN) {
211         printf(_("NWN devices are not yet supported."));
212         return 1;
213     }
214
215     if (ap_type == ATMEL12350) {
216         AutorizedMac_ATMEL[5] = 0xE0;
217         AutorizedMac_ATMEL[6] = 0x3E;
218     }
219
220     switch (mode) {
221
222     case 1: /* download */
223
224         total_mac = 0;
225         mac_num = 0;
226
227         while (mac_num <= total_mac) {
228             get.Action = 0x02; rshort(get.Action);
229             get.NumOfAllTableAddresses = total_mac; rshort(get.NumOfAllTableAddresses);
230             get.NumOfCurrentAddress = mac_num; rshort(get.NumOfCurrentAddress);
231             
232             varbinds[0].oid = AutorizedMac_ATMEL;
233             varbinds[0].len_oid = sizeof(AutorizedMac_ATMEL);
234             varbinds[0].value = (char *) &get;
235             varbinds[0].len_val = 12;
236             varbinds[0].type = STRING_VALUE;
237             
238             if (snmp(varbinds, 1, SET) <= 0) {
239                 printf(ERR_RET);
240                 printf("\n");
241                 return 1;
242             }
243
244             if (varbinds[0].len_val == 12) {
245                 if (AuthMac)
246                     free(AuthMac);
247                 AuthMac = 
248                     (struct AuthorizedMacTableString *) malloc(varbinds[0].
249                                                                len_val);
250                 memcpy(AuthMac, varbinds[0].value, varbinds[0].len_val);
251             } else {
252                 printf(ERROR_PACKET);
253                 printf("\n");
254                 return 1;
255             }
256
257             rshort(AuthMac->NumOfAllTableAddresses);
258             total_mac =
259                 (AuthMac->NumOfAllTableAddresses ==
260                  65535) ? 0 : AuthMac->NumOfAllTableAddresses;
261
262             if (mac_num) {
263                 if (first == NULL) {
264                     first = (struct MacListStat *)
265                         malloc(sizeof(struct MacListStat));
266                     curr = first;
267                 } else {
268                     curr->next = (struct MacListStat *)
269                         malloc(sizeof(struct MacListStat));
270                     curr = curr->next;
271                 }
272                 memcpy(curr->addr, AuthMac->MacAddress, 6);
273                 curr->next = NULL;
274             }
275             mac_num++;
276         }
277         f = fopen(filename, "w");
278         if(f == NULL) {
279             perror(ERROR_FILE_OPEN);
280             return 1;
281         }
282         if (first == NULL) {
283             /* no authorised addresses */
284         } else {
285             curr = first;
286             while (curr != NULL) {
287                 if(write_addr (f, curr) != 0) {
288                     perror(ERROR_FILE_WRITE);
289                     return 1;
290                 }
291                 curr = curr->next;
292             }
293         }
294         if(fclose(f) != 0) {
295             perror(ERROR_FILE_CLOSE);
296             return 1;
297         }
298         break;
299     case 2: /* upload */
300         f = fopen(filename, "r");
301         if (f == NULL) {
302             perror(ERROR_FILE_OPEN);
303             return 1;
304         }
305         mac_num  = 0;
306         while (!feof (f)) {
307             tmp = fread (mac_tmp, 1, sizeof (mac_tmp), f);
308
309             if (tmp == sizeof (mac_tmp)) {
310                 if (mac_tmp[12] != '\n') {
311                     printf(ERROR_DATA);
312                     printf("\n");
313                     return 1;
314                 }
315                 mac_tmp[12] = '\0';
316
317                 if (get_addr (&ml_tmp, mac_tmp) != 0) {
318                     printf(ERROR_DATA);
319                     printf("\n");
320                     return 1;
321                 }
322                 if (first == NULL) {
323                     first = (struct MacListStat *)
324                         malloc (sizeof (struct MacListStat));
325                     curr = first;
326                 } else {
327                     curr->next = (struct MacListStat *)
328                         malloc (sizeof (struct MacListStat));
329                     curr = curr->next;
330                 }
331                 memcpy (curr, &ml_tmp, sizeof (struct MacListStat));
332                 curr->next = NULL;
333                 mac_num++;
334             }
335         }
336         fclose(f);
337
338         curr = first;
339         i = 1;
340         while (curr != NULL) {
341             get.Action = 0x01;
342             rshort(get.Action);
343             get.NumOfAllTableAddresses = mac_num;
344             rshort(get.NumOfAllTableAddresses);
345             get.NumOfCurrentAddress = i;
346             rshort(get.NumOfCurrentAddress);
347             memcpy(get.MacAddress, curr->addr, 6);
348             varbinds[0].oid = AutorizedMac_ATMEL;
349             varbinds[0].len_oid = sizeof(AutorizedMac_ATMEL);
350             varbinds[0].value = (char *) &get;
351             varbinds[0].len_val = 12;
352             varbinds[0].type = STRING_VALUE;
353             if (snmp(varbinds, 1, SET) <= 0) {
354                 printf(ERR_RET);
355                 printf("\n");
356                 return 1;
357             }
358             if (varbinds[0].len_val != 12) {
359                 printf(ERROR_PACKET);
360                 printf("\n");
361                 return 1;
362             }
363             curr = curr->next;
364             i++;
365         }
366         break;
367     default:
368         usage();
369         return 1;
370     }
371
372     curr = first;
373     while (curr != NULL) {
374         curr = curr->next;
375         free (first);
376         first = curr;
377     }
378
379     if (community)
380         free(community);
381     if (filename)
382         free(filename);
383     return 0;
384 }