From 8af9e22649c04b6fbd8d30ccbb86c7150623a102 Mon Sep 17 00:00:00 2001 From: darkcoven Date: Tue, 17 Sep 2013 00:04:58 +0200 Subject: [PATCH 1/1] Add support for password encryption --- lib/src/lib.h | 1 + lib/src/network.c | 6 +++++- lib/src/ngadmin.c | 23 ++++++++++++++++++++++- raw/include/attr.h | 1 + raw/include/protocol.h | 5 +++++ raw/src/attr.c | 1 + raw/src/protocol.c | 19 +++++++++++++++++++ 7 files changed, 54 insertions(+), 2 deletions(-) diff --git a/lib/src/lib.h b/lib/src/lib.h index b1552ec..5cea87f 100644 --- a/lib/src/lib.h +++ b/lib/src/lib.h @@ -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 */ diff --git a/lib/src/network.c b/lib/src/network.c index 3b144ba..0306d0a 100644 --- a/lib/src/network.c +++ b/lib/src/network.c @@ -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)); diff --git a/lib/src/ngadmin.c b/lib/src/ngadmin.c index d599be0..3156d02 100644 --- a/lib/src/ngadmin.c +++ b/lib/src/ngadmin.c @@ -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; diff --git a/raw/include/attr.h b/raw/include/attr.h index e297b49..7f0c6e9 100644 --- a/raw/include/attr.h +++ b/raw/include/attr.h @@ -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 diff --git a/raw/include/protocol.h b/raw/include/protocol.h index d2064f6..b6d9da6 100644 --- a/raw/include/protocol.h +++ b/raw/include/protocol.h @@ -64,6 +64,11 @@ struct attr { }; +extern const char passwordKey[]; + + +void passwordEndecode (char *buf, unsigned int len); + int trim (char *txt, int start); diff --git a/raw/src/attr.c b/raw/src/attr.c index 39f8f25..e6ce0ca 100644 --- a/raw/src/attr.c +++ b/raw/src/attr.c @@ -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), diff --git a/raw/src/protocol.c b/raw/src/protocol.c index c41a649..afb5aa2 100644 --- a/raw/src/protocol.c +++ b/raw/src/protocol.c @@ -10,6 +10,25 @@ +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; -- 2.39.2