]> git.decadent.org.uk Git - ap-utils.git/blobdiff - src/auth.c
Merge commit 'upstream/1.5'
[ap-utils.git] / src / auth.c
diff --git a/src/auth.c b/src/auth.c
new file mode 100644 (file)
index 0000000..b4cf968
--- /dev/null
@@ -0,0 +1,1098 @@
+/*
+ *      auth.c from Access Point SNMP Utils for Linux
+ *
+ * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
+ * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 from
+ * June 1991 as published by the Free Software Foundation.
+ *
+ * This program 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, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "ap-utils.h"
+
+#define MAX_LINES LINES-12
+#define PACKET_ERROR _("AuthorizedMacTableString packet error")
+
+#define AUTH_TITLE _("APClient authorization credentials")
+
+#define MAC_AUTH _("[A] MAC authorization: ")
+#define MAC_ADD  _("Enter MAC: ")
+#define MAC_DEL  _("Delete Num: ")
+#define MAC_HEADER _(" NUM     MAC address     ")
+#define MAC_HELP _("A: auth; N: new; D: del; arrows: scroll; W: write conf; Q: quit")
+
+#define RADIUS_IP _("[I] Radius server IP: ")
+#define RADIUS_DEST_PORT _("[P] Radius server port: ")
+#define RADIUS_SECRET _("[S] Radius server secret: ")
+#define RADIUS_TIME _("[T] Reauthorization time (minutes): ")
+#define RADIUS_PORT _("[F] Radius source port: ")
+#define RADIUS_HELP _("A: auth; N: new; D: del; IPSTF: set; arrows: scroll; W: write conf; Q: quit")
+
+#define DOT1X_MODE _("[M] 802.1x authorization: ")
+#define DOT1X_TIME _("[T] key broadcasting time period (seconds): ")
+#define DOT1X_IP _("[I] 802.1x auth. server IP: ")
+#define DOT1X_SECRET _("[S] 802.1x auth. server secret: ")
+#define DOT1X_HELP _("A: auth; N: new; D: del; MTIS: set; arrows: scroll; W: write conf; Q: quit")
+
+extern WINDOW *main_sub;
+extern int LINES;
+extern short ap_type, ap_vendorext;
+
+void atmel_auth()
+{
+    char AuthorizationMacEnable[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x01, 0x00
+    };
+    char AutorizedMac[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x02, 0x00
+    };
+
+    /* These 6 are ATMEL410 MIB with SBRIDGES extensions -specific */
+    char AuthRadiusIP[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x03, 0x00
+    };
+    char AuthRadiusSecret[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x04, 0x00
+    };
+    char AuthRadiusSecretLength[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x05, 0x00
+    };
+    char AuthRadiusPort[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x06, 0x00
+    };
+    char AuthRadiusReauthorizationTime[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x07, 0x00
+    };
+    char AuthRadiusDestinPort[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x08, 0x00
+    };
+
+    /* These 4 are ATMEL12350 MIB with EZYNET extensions -specific */
+    /* Note: GEMTEK MIB falsely claims it has these, but it is not true. :( */
+    char Dot1xEnable[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x08, 0x01, 0x00
+    };
+    char BroadcastKeyPeriod[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x08, 0x02, 0x00
+    };
+    char ServerIP[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x08, 0x03, 0x00
+    };
+    char ServerSecret[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x08, 0x04, 0x00
+    };
+
+    struct AuthorizedMacTableString {
+       unsigned int short Action;
+       unsigned int short NumOfAllTableAddresses;
+       unsigned int short NumOfCurrentAddress;
+       unsigned char MacAddress[6];
+    } *AuthMac = NULL, get;
+
+    /* for ATMEL* MIBs with NONE extensions */
+    char *AuthModes_OO[] = {
+       ON,
+       OFF
+    };
+       
+    /* for ATMEL410 MIB with SBRIDGES extensions */
+    char *AuthModes_IOR[] = {
+       _("Internal"),
+       OFF,
+       _("Radius")
+    };
+
+    /* for ATMEL12350 MIBs with GEMTEK or EZYNET extensions */
+    char *AuthModes_AOD[] = {
+       _("Allow listed MACs only"),
+       OFF,
+       _("Deny listed MACs only")
+    };
+
+    char *Dot1xModes[] = {
+       ON,
+       OFF,
+       _("Mixed environment")
+    };
+
+    /* These will be used for both Radius-related and 802.1x-related stuff. */
+    struct in_addr ea_ip;
+    char ea_secret[33];
+    int ea_mode, ea_port, ea_time, ea_dest_port,
+       m_ea_mode = 0, m_ea_port = 0, m_ea_ip = 0, m_ea_secret = 0,
+       m_ea_time = 0, m_ea_dest_port = 0;
+
+    struct MacListStat *pmac, *first = NULL, *curr = NULL;
+    char message[1024], m_authmac = 0;
+    int i = 0, total_mac, auth_mode = 0, mac_num = 0, begin, end;
+    varbind varbinds[7];
+
+
+    if (ap_type == ATMEL12350) {
+       AuthorizationMacEnable[5] = 0xE0;
+       AuthorizationMacEnable[6] = 0x3E;
+       AutorizedMac[5] = 0xE0;
+       AutorizedMac[6] = 0x3E;
+    }
+
+    varbinds[i].oid = AuthorizationMacEnable;
+    varbinds[i].len_oid = sizeof(AuthorizationMacEnable);
+    varbinds[i].type = NULL_VALUE;
+    varbinds[i].len_val = 0;
+    i++;
+
+    if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES) {
+       varbinds[i].oid = AuthRadiusIP;
+       varbinds[i].len_oid = sizeof(AuthRadiusIP);
+       varbinds[i].type = NULL_VALUE;
+       varbinds[i].len_val = 0;
+       i++;
+
+       varbinds[i].oid = AuthRadiusPort;
+       varbinds[i].len_oid = sizeof(AuthRadiusPort);
+       varbinds[i].type = NULL_VALUE;
+       varbinds[i].len_val = 0;
+       i++;
+
+       varbinds[i].oid = AuthRadiusReauthorizationTime;
+       varbinds[i].len_oid = sizeof(AuthRadiusReauthorizationTime);
+       varbinds[i].type = NULL_VALUE;
+       varbinds[i].len_val = 0;
+       i++;
+
+       varbinds[i].oid = AuthRadiusDestinPort;
+       varbinds[i].len_oid = sizeof(AuthRadiusDestinPort);
+       varbinds[i].type = NULL_VALUE;
+       varbinds[i].len_val = 0;
+       i++;
+    }
+
+    if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+       varbinds[i].oid = Dot1xEnable;
+       varbinds[i].len_oid = sizeof(Dot1xEnable);
+       varbinds[i].type = NULL_VALUE;
+       varbinds[i].len_val = 0;
+       i++;
+
+       varbinds[i].oid = BroadcastKeyPeriod;
+       varbinds[i].len_oid = sizeof(BroadcastKeyPeriod);
+       varbinds[i].type = NULL_VALUE;
+       varbinds[i].len_val = 0;
+       i++;
+
+       varbinds[i].oid = ServerIP;
+       varbinds[i].len_oid = sizeof(ServerIP);
+       varbinds[i].type = NULL_VALUE;
+       varbinds[i].len_val = 0;
+       i++;
+    }
+
+    print_help(WAIT_RET);
+    if (snmp(varbinds, i, GET) < i) {
+       print_helperr(ERR_RET);
+       goto exit;
+    }
+    print_top(NULL, AUTH_TITLE);
+
+    auth_mode = *(varbinds[0].value);
+
+    strcpy(ea_secret, _("(not shown)"));
+
+    if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES) {
+       sprintf(message, "%s%s", MAC_AUTH, AuthModes_IOR[auth_mode - 1]);
+       mvwaddstr(main_sub, 0, 0, message);
+
+       if (auth_mode == 3) { /* Radius */
+           memcpy(&ea_ip.s_addr, varbinds[1].value, 4);
+           sprintf(message, "%s%s", RADIUS_IP, inet_ntoa(ea_ip));
+           mvwaddstr(main_sub, 1, 0, message);
+
+           ea_dest_port = varbinds[4].len_val == 2 ?
+               (varbinds[4].value[0] << 8) | varbinds[4].value[1] :
+               varbinds[4].value[0] < 0x80 ?
+               varbinds[4].value[0] : 0xff00 | varbinds[4].value[0];
+           sprintf(message, "%s%d", RADIUS_DEST_PORT, ea_dest_port);
+           mvwaddstr(main_sub, 2, 0, message);
+
+           sprintf(message, "%s%s", RADIUS_SECRET, ea_secret);
+           mvwaddstr(main_sub, 3, 0, message);
+
+           ea_time = varbinds[3].len_val == 2 ?
+               (varbinds[3].value[0] << 8) | varbinds[3].value[1] :
+               varbinds[3].value[0] < 0x80 ?
+               varbinds[3].value[0] : 0xff00 | varbinds[3].value[0];
+           sprintf(message, "%s%d", RADIUS_TIME, ea_time);
+           mvwaddstr(main_sub, 4, 0, message);
+
+           ea_port = varbinds[2].len_val == 2 ?
+               (varbinds[2].value[0] << 8) | varbinds[2].value[1] :
+               varbinds[2].value[0] < 0x80 ?
+               varbinds[2].value[0] : 0xff00 | varbinds[2].value[0];
+           sprintf(message, "%s%d", RADIUS_PORT, ea_port);
+           mvwaddstr(main_sub, 5, 0, message);
+       }
+    } else if (ap_type == ATMEL12350 &&
+       (ap_vendorext == GEMTEK || ap_vendorext == EZYNET)) {
+       sprintf(message, "%s%s", MAC_AUTH, AuthModes_AOD[auth_mode - 1]);
+       mvwaddstr(main_sub, 0, 0, message);
+
+       if (ap_vendorext == EZYNET) {
+           ea_mode = *(varbinds[1].value);
+           sprintf(message, "%s%s", DOT1X_MODE, Dot1xModes[ea_mode - 1]);
+           mvwaddstr(main_sub, 1, 0, message);
+
+           ea_time = varbinds[2].len_val == 2 ?
+               (varbinds[2].value[0] << 8) | varbinds[2].value[1] :
+               varbinds[2].value[0] < 0x80 ?
+               varbinds[2].value[0] : 0xff00 | varbinds[2].value[0];
+           sprintf(message, "%s%d", DOT1X_TIME, ea_time);
+           mvwaddstr(main_sub, 2, 0, message);
+
+           memcpy(&ea_ip.s_addr, varbinds[3].value, 4);
+           sprintf(message, "%s%s", DOT1X_IP, inet_ntoa(ea_ip));
+           mvwaddstr(main_sub, 3, 0, message);
+
+           sprintf(message, "%s%s", DOT1X_SECRET, ea_secret);
+           mvwaddstr(main_sub, 4, 0, message);
+       }
+    } else {
+       sprintf(message, "%s%s", MAC_AUTH, AuthModes_OO[auth_mode - 1]);
+       mvwaddstr(main_sub, 0, 0, message);
+    }
+    mvwaddstr(main_sub, 7, 0, _("Authorized MAC addresses:"));
+    wattrset(main_sub, COLOR_PAIR(13));
+    mvwaddstr(main_sub, 8, 0, MAC_HEADER);
+    wattrset(main_sub, A_NORMAL);
+    wrefresh(main_sub);
+
+    print_help("Trying to retrieve auth. MAC address list from AP. Please wait.");
+
+    total_mac = 0;
+    mac_num = 0;
+
+    while (mac_num <= total_mac) {
+       get.Action = 0x02; rshort(get.Action);
+       get.NumOfAllTableAddresses = total_mac; rshort(get.NumOfAllTableAddresses);
+       get.NumOfCurrentAddress = mac_num; rshort(get.NumOfCurrentAddress);
+
+       varbinds[0].oid = AutorizedMac;
+       varbinds[0].len_oid = sizeof(AutorizedMac);
+       varbinds[0].value = (char *) &get;
+       varbinds[0].len_val = 12;
+       varbinds[0].type = STRING_VALUE;
+
+       i = snmp(varbinds, 1, SET);
+       if (i == 0) {
+           print_helperr(ERR_SET);
+           goto exit;
+       }
+       if (i < 0)
+           break;
+
+       if (varbinds[0].len_val == 12) {
+           if (AuthMac)
+               free(AuthMac);
+           AuthMac =
+               (struct AuthorizedMacTableString *) malloc(varbinds[0].
+                                                          len_val);
+           memcpy(AuthMac, varbinds[0].value, varbinds[0].len_val);
+/*         AuthMac =
+               (struct AuthorizedMacTableString *) varbinds[0].value;*/
+       } else {
+           print_helperr(PACKET_ERROR);
+           goto exit;
+       }
+
+       rshort(AuthMac->NumOfAllTableAddresses);
+       total_mac =
+           (AuthMac->NumOfAllTableAddresses ==
+            65535) ? 0 : AuthMac->NumOfAllTableAddresses;
+
+       if (mac_num) {
+           if (first == NULL) {
+               first = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = first;
+           } else {
+               curr->next = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = curr->next;
+           }
+           memcpy(curr->addr, AuthMac->MacAddress, 6);
+           curr->next = NULL;
+       }
+       mac_num++;
+    }
+
+    begin = (mac_num > MAX_LINES) ? mac_num + 1 - (MAX_LINES) : 1;
+    end = mac_num;
+
+    if (i < 0) {
+       mvwaddstr(main_sub, 9, 0, _("(insufficient community used)"));
+       wrefresh(main_sub);
+    } else {
+       scroll_rows(first, begin, end, 9, 0);
+    }
+
+    noecho();
+
+    if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES)
+       print_help(RADIUS_HELP);
+    else if (ap_type == ATMEL12350 && ap_vendorext == EZYNET)
+       print_help(DOT1X_HELP);
+    else
+       print_help(MAC_HELP);
+
+    while (1) {
+       switch (getch()) {
+       case 'q':
+       case 'Q':
+           goto quit;
+       case 'a':
+       case 'A':
+           auth_mode = menu_choose(0, strlen(MAC_AUTH),
+               ap_type == ATMEL410 && ap_vendorext == SBRIDGES ?
+                   AuthModes_IOR :
+               ap_type == ATMEL12350 &&
+                   (ap_vendorext == GEMTEK || ap_vendorext == EZYNET) ?
+                   AuthModes_AOD :
+                   AuthModes_OO,
+               ap_vendorext == NONE ?
+                   2 : 3
+           );
+           clear_main_new(0, 1);
+           print_menusel(0, 0, MAC_AUTH,
+               ap_type == ATMEL410 && ap_vendorext == SBRIDGES ?
+                   AuthModes_IOR[auth_mode] :
+               ap_type == ATMEL12350 &&
+                   (ap_vendorext == GEMTEK || ap_vendorext == EZYNET) ?
+                   AuthModes_AOD[auth_mode] :
+                   AuthModes_OO[auth_mode]
+           );
+           auth_mode++;
+/*
+           auth_mode = on_off(0, strlen(MAC_AUTH));
+           clear_main_new(0, 1);
+           print_menusel(0, 0, MAC_AUTH, (auth_mode == 1) ? ON : OFF);
+*/
+           m_authmac = 1;
+           continue;
+       case 'd':
+       case 'D':
+           /* no MACs available for deletion */
+           if (mac_num == 1)
+               continue;
+
+           mvwaddstr(main_sub, 6, 0, MAC_DEL);
+           get_value(message, 6, strlen(MAC_DEL), 5, INT_STRING,
+               0, mac_num - 1, NULL);
+           i = atoi(message);
+           if (i == 0) {
+               clear_main_new(6, 7);
+               continue;
+           }
+           curr = first;
+           if (i == 1) {
+               if (curr->next) {
+                   pmac = curr->next;
+                   free(first);
+                   first = pmac;
+               }
+           } else {
+               int j = i;
+
+               while (--j > 1)
+                   curr = curr->next;
+               pmac = curr->next;
+               curr->next = pmac->next;
+               free(pmac);
+           }
+
+           mac_num--;
+
+           /* Rather do not ask how this works. */
+           if (i < begin) {
+               begin--;
+               end--;
+           } else if (i > (end - 1)) {
+               /* Nothing to do! */
+           } else { /* begin <= i <= (end - 1) */
+               if ((begin == 1) && ((end - 1) == mac_num)) {
+                   end--;
+               } else if ((begin > 1) && ((end - 1) < mac_num)) {
+                   /* Uncomment for top side scrolling first. */
+/*
+                   begin--;
+                   end--;
+*/
+               } else if (begin > 1) {
+                   begin--;
+                   end--;
+               }
+           }
+#if 0 /* DEBUG */
+           sprintf(message, "MAX_LINES: %i mac_num: %i begin: %i end: %i",
+               MAX_LINES, mac_num, begin, end);
+           clear_main(0);
+           mvwaddstr(main_sub, 0, 0, message);
+           wrefresh(main_sub);
+           exit(0);
+#endif /* DEBUG */
+           scroll_rows(first, begin, end, 9, 0);
+           clear_main_new(6, 7);
+           continue;
+       case 'n':
+       case 'N':
+           if (mac_num == 1) {
+               free(first);
+               first = NULL;
+           }
+again:
+           mvwaddstr(main_sub, 6, 0, MAC_ADD);
+           get_mac(message, 6, strlen(MAC_ADD));
+
+           curr = first;
+           i = 1;
+           while (curr) {
+               if (memcmp(curr->addr, message, 6) == 0) {
+                   sprintf(message, _("Given MAC already exists in MAC list "
+                       "at position %d. Press any key."), i);
+                   print_helperr(message);
+                   getch();
+                   if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES)
+                       print_help(RADIUS_HELP);
+                   else if (ap_type == ATMEL12350 && ap_vendorext == EZYNET)
+                       print_help(DOT1X_HELP);
+                   else
+                       print_help(MAC_HELP);
+                   goto again;
+               }
+               curr = curr->next;
+               i++;
+           }
+
+           curr = first;
+           while (curr && curr->next)
+               curr = curr->next;
+           if (first == NULL) {
+               first = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = first;
+           } else {
+               curr->next = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = curr->next;
+           }
+           curr->next = NULL;
+           memcpy(curr->addr, message, 6);
+           mac_num++;
+/*         get_value(message, 1, strlen(MAC_ADD), 13, ANY_STRING, 0, 0,
+               NULL);
+
+           for (i = 0; i < 6; i++) {
+               mess[0] = message[2 * i];
+               mess[1] = message[2 * i + 1];
+               mess[2] = '\0';
+               curr->addr[i] = strtol(mess, NULL, 16);
+           }
+           clear_main_new(1, 2);
+*/
+           begin = (mac_num > MAX_LINES) ? mac_num + 1 - (MAX_LINES) : 1;
+           end = mac_num;
+           scroll_rows(first, begin, end, 9, 0);
+           clear_main_new(6, 7);
+           continue;
+       case 'f':
+       case 'F':
+           if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES && auth_mode == 3) {
+               get_value(message, 5, strlen(RADIUS_PORT), 6,
+                   INT_STRING, 0, 65535, RADIUS_HELP);
+               ea_port = atoi(message);
+               m_ea_port = 1;
+           };
+           continue;
+       case 'i':
+       case 'I':
+           if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES && auth_mode == 3) {
+               get_ip(&ea_ip, 1, strlen(RADIUS_IP), RADIUS_HELP);
+               m_ea_ip = 1;
+           }
+           if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+               get_ip(&ea_ip, 3, strlen(DOT1X_IP), DOT1X_HELP);
+               m_ea_ip = 1;
+           }
+           continue;
+       case 'm':
+       case 'M':
+           if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+               ea_mode = menu_choose(1, strlen(DOT1X_MODE), Dot1xModes, 3);
+               clear_main_new(1, 2);
+               print_menusel(1, 0, DOT1X_MODE, Dot1xModes[ea_mode]);
+               ea_mode++;
+               m_ea_mode = 1;
+           }
+           continue;
+       case 'p':
+       case 'P':
+           if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES && auth_mode == 3) {
+               get_value(message, 2, strlen(RADIUS_DEST_PORT), 6,
+                   INT_STRING, 0, 65535, RADIUS_HELP);
+               ea_dest_port = atoi(message);
+               m_ea_dest_port = 1;
+           }
+           continue;
+       case 's':
+       case 'S':
+           if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES && auth_mode == 3) {
+               get_value(ea_secret, 3, strlen(RADIUS_SECRET), -33,
+                   ANY_STRING, 0, 0, NULL);
+               m_ea_secret = 1;
+           }
+           if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+               get_value(ea_secret, 4, strlen(DOT1X_SECRET), -17,
+                   ANY_STRING, 0, 0, NULL);
+               m_ea_secret = 1;
+           }
+           continue;
+       case 't':
+       case 'T':
+           if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES && auth_mode == 3) {
+               get_value(message, 4, strlen(RADIUS_TIME), 6,
+                   INT_STRING, 0, 65535, RADIUS_HELP);
+               ea_time = atoi(message);
+               m_ea_time = 1;
+           }
+           if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+               get_value(message, 2, strlen(DOT1X_TIME), 6,
+                   INT_STRING, 0, 65535, RADIUS_HELP);
+               ea_time = atoi(message);
+               m_ea_time = 1;
+           }
+           continue;
+       case 'w':
+       case 'W':
+           curr = first;
+           i = (mac_num == 1 ? 0 : 1);
+           while (curr != NULL) {
+               get.Action = 0x01; rshort(get.Action);
+               get.NumOfAllTableAddresses = mac_num - 1; rshort(get.NumOfAllTableAddresses);
+               get.NumOfCurrentAddress = i; rshort(get.NumOfCurrentAddress);
+               memcpy(get.MacAddress, curr->addr, 6);
+               varbinds[0].oid = AutorizedMac;
+               varbinds[0].len_oid = sizeof(AutorizedMac);
+               varbinds[0].value = (char *) &get;
+               varbinds[0].len_val = 12;
+               varbinds[0].type = STRING_VALUE;
+               print_help(WAIT_SET);
+               if (snmp(varbinds, 1, SET) <= 0) {
+                   print_helperr(ERR_SET);
+                   goto exit;
+               }
+               if (varbinds[0].len_val != 12) {
+                   print_helperr(PACKET_ERROR);
+                   goto exit;
+               }
+               curr = curr->next;
+               i++;
+           }
+
+           i = 0;
+
+           if (m_authmac) {
+               int c = swap4(auth_mode);
+
+               varbinds[i].oid = AuthorizationMacEnable;
+               varbinds[i].len_oid = sizeof(AuthorizationMacEnable);
+               varbinds[i].value = (char *) &c;
+               varbinds[i].len_val = 1;
+               varbinds[i].type = INT_VALUE;
+               i++;
+           }
+
+           if (m_ea_port) {
+               varbinds[i].oid = AuthRadiusPort;
+               varbinds[i].len_oid = sizeof(AuthRadiusPort);
+               ea_port = htons(ea_port);
+               varbinds[i].value = (char *) &ea_port;
+               varbinds[i].len_val = 2;
+               varbinds[i].type = INT_VALUE;
+               i++;
+           }
+
+           if (m_ea_ip) {
+               if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES) {
+                   varbinds[i].oid = AuthRadiusIP;
+                   varbinds[i].len_oid = sizeof(AuthRadiusIP);
+               }
+
+               if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+                   varbinds[i].oid = ServerIP;
+                   varbinds[i].len_oid = sizeof(ServerIP);
+               }
+
+               ea_ip.s_addr = htonl(ea_ip.s_addr);
+               ea_ip.s_addr = swap4(ea_ip.s_addr);
+               varbinds[i].value = (char *) &ea_ip.s_addr;
+               varbinds[i].len_val = 4;
+               varbinds[i].type = INT_VALUE;
+               i++;
+           }
+
+           if (m_ea_mode) {
+               varbinds[i].oid = Dot1xEnable;
+               varbinds[i].len_oid = sizeof(Dot1xEnable);
+               ea_mode = swap4(ea_mode);
+               varbinds[i].value = (char *) &ea_mode;
+               varbinds[i].len_val = 1;
+               varbinds[i].type = INT_VALUE;
+               i++;
+           }
+
+           if (m_ea_dest_port) {
+               varbinds[i].oid = AuthRadiusDestinPort;
+               varbinds[i].len_oid = sizeof(AuthRadiusDestinPort);
+               ea_dest_port = htons(ea_dest_port);
+               varbinds[i].value = (char *) &ea_dest_port;
+               varbinds[i].len_val = 2;
+               varbinds[i].type = INT_VALUE;
+               i++;
+           }
+
+           if (m_ea_secret) {
+               int c = strlen(ea_secret);
+
+               if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES) {
+                   varbinds[i].oid = AuthRadiusSecretLength;
+                   varbinds[i].len_oid = sizeof(AuthRadiusSecretLength);
+                   varbinds[i].value = (char *) &c;
+                   varbinds[i].len_val = 1;
+                   varbinds[i].type = INT_VALUE;
+                   i++;
+
+                   varbinds[i].oid = AuthRadiusSecret;
+                   varbinds[i].len_oid = sizeof(AuthRadiusSecret);
+               }
+
+               if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+                   varbinds[i].oid = ServerSecret;
+                   varbinds[i].len_oid = sizeof(ServerSecret);
+               }
+
+               varbinds[i].value = ea_secret;
+               varbinds[i].len_val = c;
+               varbinds[i].type = STRING_VALUE;
+               i++;
+           }
+
+           if (m_ea_time) {
+               if (ap_type == ATMEL410 && ap_vendorext == SBRIDGES) {
+                   varbinds[i].oid = AuthRadiusReauthorizationTime;
+                   varbinds[i].len_oid = sizeof(AuthRadiusReauthorizationTime);
+               }
+
+               if (ap_type == ATMEL12350 && ap_vendorext == EZYNET) {
+                   varbinds[i].oid = BroadcastKeyPeriod;
+                   varbinds[i].len_oid = sizeof(BroadcastKeyPeriod);
+               }
+
+               ea_time = htons(ea_time);
+               varbinds[i].value = (char *) &ea_time;
+               varbinds[i].len_val = 2;
+               varbinds[i].type = INT_VALUE;
+               i++;
+           }
+
+           print_help(WAIT_SET);
+           if (snmp(varbinds, i, SET) <= 0) {
+               print_helperr(ERR_SET);
+               goto exit;
+           }
+           wbkgd(main_sub, A_NORMAL);
+           wattrset(main_sub, COLOR_PAIR(13));
+           mvwaddstr(main_sub, 8, 0, MAC_HEADER);
+           wattrset(main_sub, A_NORMAL);
+           wrefresh(main_sub);
+           print_help(DONE_SET);
+           goto exit;
+       case KEY_DOWN:
+       case KEY_RIGHT:
+           if (end < mac_num) {
+               begin++;
+               end++;
+               scroll_rows(first, begin, end, 9, 0);
+           }
+           continue;
+       case KEY_UP:
+       case KEY_LEFT:
+           if (begin > 1) {
+               begin--;
+               end--;
+               scroll_rows(first, begin, end, 9, 0);
+           }
+           continue;
+       case KEY_NPAGE:
+           if (end < mac_num) {
+               end = (end + (MAX_LINES) - 1 < mac_num) ?
+                   end + (MAX_LINES) - 1 : mac_num;
+               begin = (end - (MAX_LINES) + 1 > 0) ?
+                   end - (MAX_LINES) + 1 : 1;
+               scroll_rows(first, begin, end, 9, 0);
+           }
+           continue;
+       case KEY_PPAGE:
+           if (begin > 1) {
+               begin = (begin - (MAX_LINES) + 1 > 0) ?
+                   begin - (MAX_LINES) + 1 : 1;
+               end = (begin + (MAX_LINES) - 1 < mac_num) ?
+                   begin + (MAX_LINES) - 1 : mac_num;
+               scroll_rows(first, begin, end, 9, 0);
+           }
+           continue;
+       case KEY_END:
+           if (end < mac_num) {
+               begin = (mac_num > MAX_LINES) ? mac_num + 1 - (MAX_LINES) : 1;
+               end = mac_num;
+               scroll_rows(first, begin, end, 9, 0);
+           }
+           continue;
+       case KEY_HOME:
+           if (begin > 1) {
+               begin = 1;
+               end = (mac_num > MAX_LINES) ? MAX_LINES : mac_num;
+               scroll_rows(first, begin, end, 9, 0);
+           }
+           continue;
+       }
+       continue;
+    }
+
+    print_help(ANY_KEY);
+  exit:
+    getch();
+  quit:
+    while ((curr = first)) {
+       first = curr->next;
+       free(curr);
+    }
+    if (AuthMac)
+       free(AuthMac);
+    print_top(NULL, NULL);
+    clear_main(0);
+}
+
+void nwn_auth_mac()
+{
+    struct MacListStat *pmac, *first = NULL, *curr = NULL;
+    char Mac[] =
+       { 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x02,
+       0x02, 0x01, 0x02, 0x00
+    };
+    char MacAllow[] =
+       { 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x02,
+       0x02, 0x01, 0x03, 0x00
+    };
+    char MacRowStatus[] =
+       { 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x02,
+       0x02, 0x01, 0x04, 0x00
+    };
+    char message[1024], auth_enable[] =
+       { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+    char destroy = 6, create = 4, allow = 1;
+    int i, auth_mac = 0, mac_num = 0, begin, end;
+    varbind varbinds[3];
+    print_top(NULL, AUTH_TITLE);
+
+    mvwaddstr(main_sub, 2, 0, MAC_HEADER);
+    wrefresh(main_sub);
+    print_help(WAIT_RET);
+
+    mac_num = 1;
+    varbinds[0].oid = Mac;
+    varbinds[0].len_oid = sizeof(Mac);
+    varbinds[0].value = Mac;
+    varbinds[0].len_val = 0;
+    varbinds[0].type = NULL_VALUE;
+    if (snmp(varbinds, 1, GET_NEXT) <= 0) {
+       print_helperr(ERR_RET);
+       goto exit;
+    }
+
+    while (memcmp(varbinds[0].oid, Mac, sizeof(Mac) - 1) == 0) {
+
+       Mac[sizeof(Mac) - 1] = varbinds[0].oid[sizeof(Mac) - 1];
+       MacAllow[sizeof(MacAllow) - 1] = varbinds[0].oid[sizeof(Mac) - 1];
+       MacRowStatus[sizeof(MacRowStatus) - 1] =
+           varbinds[0].oid[sizeof(Mac) - 1];
+
+       varbinds[0].oid = Mac;
+       varbinds[0].len_oid = sizeof(Mac);
+       varbinds[0].value = Mac;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+       varbinds[1].oid = MacAllow;
+       varbinds[1].len_oid = sizeof(MacAllow);
+       varbinds[1].value = Mac;
+       varbinds[1].len_val = 0;
+       varbinds[1].type = NULL_VALUE;
+       varbinds[2].oid = MacRowStatus;
+       varbinds[2].len_oid = sizeof(MacRowStatus);
+       varbinds[2].value = Mac;
+       varbinds[2].len_val = 0;
+       varbinds[2].type = NULL_VALUE;
+       if (snmp(varbinds, 3, GET) < 3) {
+           print_helperr(ERR_RET);
+           goto exit;
+       }
+       if (memcmp(auth_enable, varbinds[0].value, 6)) {
+           if (first == NULL) {
+               first = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = first;
+           } else {
+               curr->next = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = curr->next;
+           }
+           memcpy(curr->addr, varbinds[0].value, 6);
+           curr->next = NULL;
+           mac_num++;
+       } else
+           auth_mac = 1;
+
+
+       varbinds[0].oid = Mac;
+       varbinds[0].len_oid = sizeof(Mac);
+       varbinds[0].value = Mac;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+       if (snmp(varbinds, 1, GET_NEXT) <= 0) {
+           print_helperr(ERR_RET);
+           goto exit;
+       }
+    }
+
+    begin = 1;
+    end = (mac_num > MAX_LINES) ? MAX_LINES : mac_num;
+
+    sprintf(message, "%s%s", MAC_AUTH, (auth_mac) ? OFF : ON);
+    mvwaddstr(main_sub, 0, 0, message);
+
+    scroll_rows(first, begin, end, 3, 0);
+
+    noecho();
+
+    print_help(MAC_HELP);
+    while (1) {
+       switch (getch()) {
+       case 'Q':
+       case 'q':
+           goto quit;
+       case 'a':
+           auth_mac = on_off(0, strlen(MAC_AUTH)) - 1;
+           clear_main_new(0, 1);
+           print_menusel(0, 0, MAC_AUTH, (auth_mac) ? OFF : ON);
+           continue;
+       case 'd':
+           mvwaddstr(main_sub, 1, 0, MAC_DEL);
+           get_value(message, 1, strlen(MAC_DEL), 5, INT_STRING,
+               1, mac_num - 1, NULL);
+           i = atoi(message);
+           if (i == 1) {
+               pmac = first;
+               first = first->next;
+               free(pmac);
+           } else {
+               curr = first;
+               while (--i > 1)
+                   curr = curr->next;
+               pmac = curr->next;
+               curr->next = pmac->next;
+               free(pmac);
+           }
+           mac_num--;
+           begin = 1;
+           end = (mac_num > MAX_LINES) ? MAX_LINES : mac_num;
+           scroll_rows(first, begin, end, 3, 0);
+           clear_main_new(1, 2);
+           continue;
+       case 'n':
+       case 'N':
+           mvwaddstr(main_sub, 1, 0, MAC_ADD);
+           curr = first;
+           while (curr && curr->next)
+               curr = curr->next;
+           if (first == NULL) {
+               first = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = first;
+           } else {
+               curr->next = (struct MacListStat *)
+                   malloc(sizeof(struct MacListStat));
+               curr = curr->next;
+           }
+           curr->next = NULL;
+           mac_num++;
+           get_mac(curr->addr, 1, strlen(MAC_ADD));
+/*
+           for (i = 0; i < 6; i++) {
+               get_value(message, 1, 20 + i * 3, 3, ANY_STRING, 0, 0, NULL);
+               curr->addr[i] = strtol(message, NULL, 16);
+           }
+           clear_main_new(1, 2);
+*/
+           begin = 1;
+           end = (mac_num > MAX_LINES) ? MAX_LINES : mac_num;
+           scroll_rows(first, begin, end, 3, 0);
+           continue;
+       case 'w':
+       case 'W':
+           print_help(WAIT_SET);
+
+           Mac[sizeof(Mac) - 1] = 0;
+
+           varbinds[0].oid = Mac;
+           varbinds[0].len_oid = sizeof(Mac);
+           varbinds[0].value = Mac;
+           varbinds[0].len_val = 0;
+           varbinds[0].type = NULL_VALUE;
+           if (snmp(varbinds, 1, GET_NEXT) <= 0) {
+               print_helperr(ERR_RET);
+               goto exit;
+           }
+           while (memcmp(varbinds[0].oid, Mac, sizeof(Mac) - 1) == 0) {
+
+               MacRowStatus[sizeof(MacRowStatus) - 1] =
+                   varbinds[0].oid[sizeof(Mac) - 1];
+               varbinds[0].oid = MacRowStatus;
+               varbinds[0].len_oid = sizeof(MacRowStatus);
+               varbinds[0].value = &destroy;
+               varbinds[0].len_val = 1;
+               varbinds[0].type = INT_VALUE;
+               if (snmp(varbinds, 1, SET) <= 0) {
+                   print_helperr(ERR_SET);
+                   goto exit;
+               }
+               varbinds[0].oid = Mac;
+               varbinds[0].len_oid = sizeof(Mac);
+               varbinds[0].value = Mac;
+               varbinds[0].len_val = 0;
+               varbinds[0].type = NULL_VALUE;
+               if (snmp(varbinds, 1, GET_NEXT) <= 0) {
+                   print_helperr(ERR_RET);
+                   goto exit;
+               }
+           }
+
+
+           curr = first;
+           i = 1;
+
+           if (auth_mac) {
+               Mac[sizeof(Mac) - 1] = i;
+               MacAllow[sizeof(MacAllow) - 1] = i;
+               MacRowStatus[sizeof(MacRowStatus) - 1] = i;
+
+               varbinds[0].oid = MacRowStatus;
+               varbinds[0].len_oid = sizeof(MacRowStatus);
+               varbinds[0].value = &create;
+               varbinds[0].len_val = 1;
+               varbinds[0].type = INT_VALUE;
+               varbinds[1].oid = Mac;
+               varbinds[1].len_oid = sizeof(Mac);
+               varbinds[1].value = auth_enable;
+               varbinds[1].len_val = 6;
+               varbinds[1].type = STRING_VALUE;
+               varbinds[2].oid = MacAllow;
+               varbinds[2].len_oid = sizeof(MacAllow);
+               varbinds[2].value = &allow;
+               varbinds[2].len_val = 1;
+               varbinds[2].type = INT_VALUE;
+               print_help(WAIT_SET);
+               if (snmp(varbinds, 3, SET) <= 0) {
+                   print_helperr(ERR_SET);
+                   goto exit;
+               }
+               i++;
+           }
+
+
+
+
+           while (curr != NULL) {
+               Mac[sizeof(Mac) - 1] = i;
+               MacAllow[sizeof(MacAllow) - 1] = i;
+               MacRowStatus[sizeof(MacRowStatus) - 1] = i;
+
+               varbinds[0].oid = MacRowStatus;
+               varbinds[0].len_oid = sizeof(MacRowStatus);
+               varbinds[0].value = &create;
+               varbinds[0].len_val = 1;
+               varbinds[0].type = INT_VALUE;
+               varbinds[1].oid = Mac;
+               varbinds[1].len_oid = sizeof(Mac);
+               varbinds[1].value = curr->addr;
+               varbinds[1].len_val = 6;
+               varbinds[1].type = STRING_VALUE;
+               varbinds[2].oid = MacAllow;
+               varbinds[2].len_oid = sizeof(MacAllow);
+               varbinds[2].value = &allow;
+               varbinds[2].len_val = 1;
+               varbinds[2].type = INT_VALUE;
+               print_help(WAIT_SET);
+               if (snmp(varbinds, 3, SET) <= 0) {
+                   print_helperr(ERR_SET);
+                   goto exit;
+               }
+               curr = curr->next;
+               i++;
+           }
+           wbkgd(main_sub, A_NORMAL);
+           wrefresh(main_sub);
+           print_help(DONE_SET);
+           goto exit;
+       case KEY_DOWN:
+       case KEY_RIGHT:
+           if (end < mac_num) {
+               begin++;
+               end++;
+               scroll_rows(first, begin, end, 3, 0);
+           }
+
+           continue;
+       case KEY_UP:
+       case KEY_LEFT:
+           if (begin > 1) {
+               begin--;
+               end--;
+               scroll_rows(first, begin, end, 3, 0);
+           }
+           continue;
+       }
+       continue;
+    }
+
+    print_help(ANY_KEY);
+  exit:
+    getch();
+  quit:
+    while ((curr = first)) {
+       first = curr->next;
+       free(curr);
+    }
+    print_top(NULL, NULL);
+    clear_main(0);
+}