passwd
This commit is contained in:
62
login.c
62
login.c
@@ -15,56 +15,54 @@ static int do_change_object_passwd(char *name,
|
||||
{
|
||||
uint8 key[8];
|
||||
|
||||
fprintf(stderr, "PASSWD debug: user='%s' oldlen=%u newlen=%u\n",
|
||||
name, (uint)strlen(oldpassword), (uint)strlen(newpassword));
|
||||
|
||||
if (!ncp_17_17(key)) {
|
||||
uint32 objid;
|
||||
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_17 OK\n");
|
||||
|
||||
objid = ncp_17_35(name, objtyp);
|
||||
uint32 objid = ncp_17_35(name, objtyp);
|
||||
if (objid) {
|
||||
uint8 buff[128];
|
||||
uint8 encrypted[8];
|
||||
uint8 newcryptpasswd[16];
|
||||
int passwdx = (int)strlen(newpassword);
|
||||
uint8 oldpwd[16]; /* old passwd as stored by server */
|
||||
uint8 newpwd[16]; /* new passwd as stored by server */
|
||||
uint8 cryptkey[8];
|
||||
uint8 tmpid[4];
|
||||
uint8 passwdx;
|
||||
int newlen;
|
||||
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_35 OK objid=%08lx name='%s'\n",
|
||||
objid, name);
|
||||
|
||||
memcpy(cryptkey, key, 8);
|
||||
U32_TO_BE32(objid, tmpid);
|
||||
|
||||
shuffle(tmpid, oldpassword, strlen(oldpassword), buff);
|
||||
nw_encrypt(key, buff, encrypted);
|
||||
shuffle(tmpid, oldpassword, strlen(oldpassword), oldpwd);
|
||||
shuffle(tmpid, newpassword, strlen(newpassword), newpwd);
|
||||
|
||||
shuffle(tmpid, newpassword, strlen(newpassword), buff);
|
||||
memcpy(newcryptpasswd, buff, sizeof(newcryptpasswd));
|
||||
nw_encrypt(cryptkey, oldpwd, cryptkey);
|
||||
|
||||
fprintf(stderr, "PASSWD debug: trying encrypted ncp_17_4b passwdx=%d\n",
|
||||
passwdx);
|
||||
/*
|
||||
* Same keyed change password transformation as ncpfs
|
||||
* ncp_change_login_passwd(): encrypt both 8-byte halves of the
|
||||
* stored new password using the stored old password as key material.
|
||||
* newpassencrypt() intentionally mutates oldpwd; the passwd length
|
||||
* byte must be calculated afterwards, just like ncpfs does it.
|
||||
*/
|
||||
newpassencrypt(oldpwd, newpwd);
|
||||
newpassencrypt(oldpwd + 8, newpwd + 8);
|
||||
|
||||
if (!ncp_17_4b(encrypted, name, objtyp, passwdx, newcryptpasswd)) {
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_4b OK\n");
|
||||
newlen = strlen(newpassword);
|
||||
if (newlen > 63) newlen = 63;
|
||||
passwdx = (uint8)(((newlen ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40);
|
||||
|
||||
if (!ncp_17_4b(cryptkey, name, objtyp, passwdx, newpwd)) {
|
||||
;;
|
||||
return(0);
|
||||
}
|
||||
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_4b failed neterrno=%d\n", neterrno);
|
||||
} else {
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_35 failed neterrno=%d\n", neterrno);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_17 failed neterrno=%d\n", neterrno);
|
||||
}
|
||||
|
||||
fprintf(stderr, "PASSWD debug: trying fallback unencrypted ncp_17_40\n");
|
||||
/*
|
||||
* Fallback for old servers/requesters where Get Encryption Key is not
|
||||
* available. Keep the original unencrypted behavior as fallback only.
|
||||
*/
|
||||
if (!ncp_17_40(name, objtyp, oldpassword, newpassword)) {
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_40 OK\n");
|
||||
;;
|
||||
return(0);
|
||||
}
|
||||
|
||||
fprintf(stderr, "PASSWD debug: ncp_17_40 failed neterrno=%d\n", neterrno);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
112
nwcrypt.c
112
nwcrypt.c
@@ -210,4 +210,116 @@ nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til)
|
||||
til[s] = k[s] ^ k[15 - s];
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
newshuffle[256] =
|
||||
{
|
||||
0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
|
||||
0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
|
||||
0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
|
||||
0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
|
||||
|
||||
0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
|
||||
0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
|
||||
0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
|
||||
0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
|
||||
|
||||
0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
|
||||
0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
|
||||
0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
|
||||
0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
|
||||
|
||||
0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
|
||||
0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
|
||||
0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
|
||||
0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
|
||||
|
||||
0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
|
||||
0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
|
||||
0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
|
||||
0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
|
||||
|
||||
0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
|
||||
0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
|
||||
0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
|
||||
0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
|
||||
|
||||
0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
|
||||
0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
|
||||
0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
|
||||
0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
|
||||
|
||||
0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
|
||||
0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
|
||||
0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
|
||||
0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
|
||||
};
|
||||
|
||||
static const unsigned char final_shuffle[16] = {
|
||||
0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
|
||||
0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08,
|
||||
};
|
||||
|
||||
/*
|
||||
* verschluesseln des neuen Passworts fuer keyed change password
|
||||
* Verwendung:
|
||||
* - Shuffle (aus nwcrypt.c) altes passwort nach old (16 bytes)
|
||||
* - shuffle neues passwort nach new (16 bytes)
|
||||
* - nwpassencrypt (diese Funktion) zweimal aufrufen fuer je 8 bytes:
|
||||
* nwpassencrypt(old+0, new+0, out+0)
|
||||
* nwpassencrypt(old+8, new+8, out+8)
|
||||
* - NCP-Buffer aufbauen:
|
||||
* 2 byte Laenge im Hi-Lo-Format
|
||||
* 1 byte Funktion (0x4b)
|
||||
* 8 byte (nwcrypt Ergebnis analog login/verify password)
|
||||
* 2 byte Objecttype
|
||||
* 1 byte Objectname-Laenge
|
||||
* n byte Objectname
|
||||
* 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40
|
||||
* 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Encrypt the new password for keyed change password
|
||||
* For info on how to use this function, look at ncp_change_login_passwd
|
||||
* in ncplib.c.
|
||||
*/
|
||||
|
||||
void
|
||||
newpassencrypt(unsigned char *old, unsigned char *npwd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
int di, ax;
|
||||
unsigned char *p, *bx;
|
||||
unsigned char cl, dl, ch;
|
||||
unsigned char copy[8];
|
||||
|
||||
memcpy(copy, npwd, 8);
|
||||
for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++)
|
||||
{
|
||||
cl = newshuffle[(((copy[di] ^ *p) >> 4) & 0x0f) + ax + 0x10] << 4;
|
||||
dl = newshuffle[((copy[di] ^ *p) & 0xf) + ax];
|
||||
copy[di] = cl | dl;
|
||||
}
|
||||
|
||||
ch = old[7];
|
||||
for (bx = old + 7; bx > old; bx--)
|
||||
{
|
||||
*bx = ((bx[-1] >> 4) & 0x0f) | ((*bx) << 4);
|
||||
}
|
||||
*old = ((ch >> 4) & 0x0f) | (*old) << 4;
|
||||
|
||||
memset(npwd, 0, 8);
|
||||
|
||||
for (di = 0; di < 16; di++)
|
||||
{
|
||||
if (final_shuffle[di] & 1)
|
||||
ch = ((copy[final_shuffle[di] / 2] >> 4) & 0x0f);
|
||||
else
|
||||
ch = copy[final_shuffle[di] / 2] & 0x0f;
|
||||
npwd[di / 2] |= ((di & 1) ? ch << 4 : ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user