]> git.sur5r.net Git - ngadmin/commitdiff
Add support for password encryption
authordarkcoven <admin@darkcoven.tk>
Mon, 16 Sep 2013 22:04:58 +0000 (00:04 +0200)
committerdarkcoven <admin@darkcoven.tk>
Wed, 18 Sep 2013 20:14:05 +0000 (22:14 +0200)
lib/src/lib.h
lib/src/network.c
lib/src/ngadmin.c
raw/include/attr.h
raw/include/protocol.h
raw/src/attr.c
raw/src/protocol.c

index b1552ec1f098a9ede961dede83acc7d115590ec8..5cea87f48350078ecaae900d04da07924cdfb755 100644 (file)
@@ -26,6 +26,7 @@ struct ngadmin {
        bool keepbroad;                 /* keep broadcasting */
        bool globalbroad;               /* use global broadcast address (255.255.255.255) */
        /* switch properties */
+       bool encrypt_pass;              /* switch uses password "encryption" */
        char password[PASSWORD_MAX];    /* password to use to login on switches */
        struct swi_attr *swi_tab;       /* array of detected switches */
        int swi_count;                  /* number of detected switches */
index 3b144ba5be96e33422405f01ec5aa9d37087819e..0306d0aa5462601489b8770b71298069a6b87973 100644 (file)
@@ -289,6 +289,7 @@ int writeRequest (struct ngadmin *nga, List *attr)
        int i, ret = ERR_OK;
        unsigned char err;
        unsigned short attr_error;
+       struct attr *at;
        
        
        if (nga == NULL) {
@@ -304,7 +305,10 @@ int writeRequest (struct ngadmin *nga, List *attr)
                attr = createEmptyList();
        
        /* add password attribute to start */
-       pushFrontList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
+       at = newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password));
+       if (nga->encrypt_pass)
+               passwordEndecode(at->data, at->size);
+       pushFrontList(attr, at);
        
        /* add end attribute to end */
        pushBackList(attr, newEmptyAttr(ATTR_END));
index d599be00417ee09765978f38dd02d17641765c31..3156d02df1ee0e29e5bb900c12d6d83dd36b1dbb 100644 (file)
@@ -219,6 +219,7 @@ const struct swi_attr* ngadmin_getCurrentSwitch (struct ngadmin *nga)
 int ngadmin_login (struct ngadmin *nga, int id)
 {
        List *attr;
+       struct attr *at;
        int ret = ERR_OK;
        struct swi_attr *sa;
        
@@ -230,8 +231,23 @@ int ngadmin_login (struct ngadmin *nga, int id)
        
        sa = &nga->swi_tab[id];
        nga->current = sa;
+       nga->encrypt_pass = false;
        
        attr = createEmptyList();
+       pushBackList(attr, newEmptyAttr(ATTR_ENCPASS));
+       ret = readRequest(nga, attr);
+       if (ret != ERR_OK)
+               goto end;
+       
+       filterAttributes(attr, ATTR_ENCPASS, ATTR_END);
+       if (attr->first != NULL) {
+               at = attr->first->data;
+               nga->encrypt_pass = (at->size == 4 && ntohl(*(unsigned int*)at->data) == 1);
+       }
+       clearList(attr, (void(*)(void*))freeAttr);
+       
+       /* Strangely, passwords must never be encrypted inside a read request,
+        * or it will be rejected. Seems more to be a firmware bug. */
        pushBackList(attr, newAttr(ATTR_PASSWORD, strlen(nga->password), strdup(nga->password)));
        ret = readRequest(nga, attr);
        if (ret == ERR_OK ) {
@@ -244,6 +260,7 @@ int ngadmin_login (struct ngadmin *nga, int id)
                nga->current = NULL;
        }
        
+end:
        destroyList(attr, (void(*)(void*))freeAttr);
        
        
@@ -393,6 +410,7 @@ int ngadmin_resetPortsStatistics (struct ngadmin *nga)
 int ngadmin_changePassword (struct ngadmin *nga, const char* pass)
 {
        List *attr;
+       struct attr *at;
        int ret = ERR_OK;
        
        
@@ -403,7 +421,10 @@ int ngadmin_changePassword (struct ngadmin *nga, const char* pass)
        
        
        attr = createEmptyList();
-       pushBackList(attr, newAttr(ATTR_NEW_PASSWORD, strlen(pass), strdup(pass)));
+       at = newAttr(ATTR_NEW_PASSWORD, strlen(pass), strdup(pass));
+       if (nga->encrypt_pass)
+               passwordEndecode(at->data, at->size);
+       pushBackList(attr, at);
        ret = writeRequest(nga, attr);
        if (ret != ERR_OK)
                goto end;
index e297b4943caa6b53a91c5ceb4adc3002b280349f..7f0c6e94790bfa3373c8b9d73f5fa0012326068b 100644 (file)
@@ -25,6 +25,7 @@
 #define ATTR_UNK_000F          0x000F
 #define ATTR_FIRM_UPGRADE      0x0010
 #define ATTR_RESTART           0x0013
+#define ATTR_ENCPASS           0x0014
 #define ATTR_DEFAULTS          0x0400
 #define ATTR_PORT_STATUS       0x0C00
 #define ATTR_PORT_STATISTICS   0x1000
index d2064f68c43c0dc90478a6487738ae9f5d7a36a0..b6d9da6bf7b04b02f3234a09eaa3ce86796679ae 100644 (file)
@@ -64,6 +64,11 @@ struct attr {
 };
 
 
+extern const char passwordKey[];
+
+
+void passwordEndecode (char *buf, unsigned int len);
+
 
 int trim (char *txt, int start);
 
index 39f8f25cef937c33b24ae52a07f5ecc70e68e26c..e6ce0ca679dc3320c57762a5b4d9c89e33c60f98 100644 (file)
@@ -408,6 +408,7 @@ static const struct attr_handler attrtab[] = {
        ATTR_HANDLER_ENTRY(ATTR_GATEWAY, 4, NULL, NULL),
        ATTR_HANDLER_ENTRY(ATTR_DHCP, 2, NULL, NULL),
        ATTR_HANDLER_ENTRY(ATTR_RESTART, 1, NULL, NULL),
+       ATTR_HANDLER_ENTRY(ATTR_ENCPASS, 4, NULL, NULL),
        ATTR_HANDLER_ENTRY(ATTR_DEFAULTS, 1, NULL, NULL),
        ATTR_HANDLER_ENTRY(ATTR_PORT_STATUS, sizeof(struct attr_port_status), NULL, ports_status_decode),
        ATTR_HANDLER_ENTRY(ATTR_PORT_STATISTICS, sizeof(struct attr_port_stat), NULL, port_stat_decode),
index c41a6493bb6ad138d36fe48250bba44edff1bca4..afb5aa2662eb138c0631f1ef961c46266026fe73 100644 (file)
 
 
 
+const char passwordKey[] = "NtgrSmartSwitchRock";
+
+
+void passwordEndecode (char *buf, unsigned int len)
+{
+       const char *k = passwordKey;
+       unsigned int i;
+       
+       if (buf == NULL || len <= 0)
+               return;
+       
+       for (i = 0; i < len; i++) {
+               if (*k == '\0')
+                       k = passwordKey;
+               buf[i] ^= *k++;
+       }
+}
+
+
 int trim (char *txt, int start)
 {
        char *p;