Add GPL-2-or-later license headers to the DOS utility source files and document the purpose and local dependencies of each C, header and assembler file. Preserve the original Martin Stover copyright attribution for the historic MARS-NWE utility sources, including files that did not previously carry an explicit header but are part of the original tool set. Add Mario Fetka as the 2026 copyright holder for the current maintenance work, and use Mario-only headers for files without original Martin Stover ownership. Also add a root-level COPYING file containing the GPL-2 license text.
353 lines
10 KiB
C
353 lines
10 KiB
C
/*
|
|
* mars-nwe-dosutils - NetWare/DOS utility tools.
|
|
*
|
|
* Copyright (C) 2026 Mario Fetka
|
|
* Copyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* Purpose: NetWare password obfuscation/encryption helper routines used by LOGIN/PASSWD.
|
|
* Depends on: nwcrypt.h public declarations and login.c caller.
|
|
*/
|
|
|
|
|
|
/*$*********************************************************
|
|
$*
|
|
$* This code has been taken from DDJ 11/93, from an
|
|
$* article by Pawel Szczerbina.
|
|
$*
|
|
$* Password encryption routines follow.
|
|
$* Converted to C from Barry Nance's Pascal
|
|
$* prog published in the March -93 issue of Byte.
|
|
$*
|
|
$* Adapted to be useable for ncpfs by
|
|
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
|
|
$* October 1995.
|
|
$*
|
|
$* Stolen to be useable for mars_nwe by
|
|
$* Martin Stover <mstover@freeway.de> in
|
|
$* Dezember 1995.
|
|
$**********************************************************/
|
|
|
|
/****************************************************************************
|
|
|
|
I read that Novell is not very open when it comes to technical details
|
|
of the Netware Core Protocol. This might be especially true for the
|
|
encryption stuff. I took the necessary code from Dr. Dobb's Journal
|
|
11/93, Undocumented Corner. I asked Jon Erickson <jon@ddj.com> about
|
|
the legal status of this piece of code:
|
|
|
|
|
|
---
|
|
Date: Thu, 12 Oct 1995 13:44:18 +0100
|
|
From: Volker Lendecke <lendecke>
|
|
To: jon@ddj.com
|
|
Subject: legal status of your source code?
|
|
|
|
|
|
Hello!
|
|
|
|
I hope that you're the right one to write to, you are the first on your WWW
|
|
server. If you are not, could you please forward this message to the right
|
|
person? Thanks.
|
|
|
|
I'm currently exploring the possibility to write a free (in the GNU GPL
|
|
sense) NCP filesystem, which would allow me to access a novell server
|
|
transparently. For that I would like to use the encryption functions you
|
|
published in DDJ 11/93, Undocumented Corner. I would make some cosmetic
|
|
changes, such as other indentations, minor code changes and so on. But I do
|
|
not know if that allows me to publish this code under GPL. One alternative
|
|
would be to publish a diff against your listing, but that would probably
|
|
contain much of your code as well, and it would be very inconvenient for
|
|
the average user.
|
|
|
|
I think that you have some kind of standard procedure for such a
|
|
case. Please tell me what I should do.
|
|
|
|
Many thanks in advance,
|
|
|
|
Volker
|
|
|
|
+=================================================================+
|
|
! Volker Lendecke Internet: lendecke@namu01.gwdg.de !
|
|
! D-37081 Goettingen, Germany !
|
|
+=================================================================+
|
|
|
|
--
|
|
|
|
|
|
I got the following answer:
|
|
|
|
---
|
|
From: Jon Erickson <jon@ddj.com>
|
|
X-Mailer: SCO System V Mail (version 3.2)
|
|
To: lendecke@namu01.gwdg.de
|
|
Subject: Re: legal status of your source code?
|
|
Date: Thu, 12 Oct 95 5:42:56 PDT
|
|
|
|
Volker,
|
|
Code from Dr. Dobb's Journal related articles is provided for
|
|
anyone to use. Clearly, the author of the article should be
|
|
given credit.
|
|
Jon Erickson
|
|
|
|
---
|
|
|
|
With this answer in mind, I took the code and made it a bit more
|
|
C-like. The original seemed to be translated by a mechanical pascal->c
|
|
translator. Jon's answer encouraged me to publish nwcrypt.c under the
|
|
GPL. If anybody who knows more about copyright and sees any problems
|
|
with this, please tell me.
|
|
****************************************************************************/
|
|
|
|
/******************* Data types ***************************/
|
|
typedef unsigned char buf32[32];
|
|
typedef unsigned char buf16[16];
|
|
typedef unsigned char buf8[8];
|
|
typedef unsigned char buf4[4];
|
|
typedef unsigned char u8;
|
|
|
|
static u8 encrypttable[256] =
|
|
{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
|
|
0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
|
|
0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
|
|
0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
|
|
0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
|
|
0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
|
|
0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
|
|
0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
|
|
0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
|
|
0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
|
|
0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
|
|
0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
|
|
0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
|
|
0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
|
|
0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
|
|
0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD};
|
|
|
|
static buf32 encryptkeys =
|
|
{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,
|
|
0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
|
|
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
|
|
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
|
|
|
|
#include <string.h>
|
|
#include "nwcrypt.h"
|
|
static void
|
|
shuffle1(buf32 temp, unsigned char *target)
|
|
{
|
|
short b4;
|
|
unsigned char b3;
|
|
int s, b2, i;
|
|
|
|
b4 = 0;
|
|
|
|
for (b2 = 0; b2 <= 1; ++b2)
|
|
{
|
|
for (s = 0; s <= 31; ++s)
|
|
{
|
|
b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]);
|
|
b4 = b4 + b3;
|
|
temp[s] = b3;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i <= 15; ++i) {
|
|
target[i] = encrypttable[temp[ 2*i ]]
|
|
| (encrypttable[temp[ 2*i + 1]] << 4);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
shuffle(unsigned char *lon, const unsigned char *buf, int buflen,
|
|
unsigned char *target)
|
|
{
|
|
int b2, d, s;
|
|
buf32 temp;
|
|
|
|
while ( (buflen > 0)
|
|
&& (buf[buflen - 1] == 0)) {
|
|
buflen = buflen - 1;
|
|
}
|
|
|
|
for (s = 0; s < 32; s++) {
|
|
temp[s] = 0;
|
|
}
|
|
|
|
d = 0;
|
|
while (buflen >= 32)
|
|
{
|
|
for (s = 0; s <= 31; ++s)
|
|
{
|
|
temp[s] = temp[s] ^ buf[d];
|
|
d = d + 1;
|
|
}
|
|
buflen = buflen - 32;
|
|
}
|
|
b2 = d;
|
|
if (buflen > 0)
|
|
{
|
|
for (s = 0; s <= 31; ++s)
|
|
{
|
|
if (d + buflen == b2)
|
|
{
|
|
b2 = d;
|
|
temp[s] = temp[s] ^ encryptkeys[s];
|
|
} else {
|
|
temp[s] = temp[s] ^ buf[b2];
|
|
b2 = b2 + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (s = 0; s <= 31; ++s)
|
|
temp[s] = temp[s] ^ lon[s & 3];
|
|
|
|
shuffle1(temp,target);
|
|
}
|
|
|
|
|
|
void
|
|
nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til)
|
|
{
|
|
buf32 k;
|
|
int s;
|
|
|
|
shuffle(&(fra[0]), buf, 16, &(k[ 0]));
|
|
shuffle(&(fra[4]), buf, 16, &(k[16]));
|
|
|
|
for (s = 0; s <= 15; ++s)
|
|
k[s] = k[s] ^ k[31 - s];
|
|
|
|
for (s = 0; s <= 7; ++s)
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|