Import ncpfs 2.0.12

This commit is contained in:
ncpfs archive import
2026-04-28 20:39:59 +02:00
parent 915f560f85
commit f813517d69
81 changed files with 8104 additions and 4783 deletions

View File

@@ -19,6 +19,15 @@ endif
CFLAGS += $(PIC_FLAG)
ifdef NDS_SUPPORT
CFLAGS += -DNDS_SUPPORT
NDS_OBJ = ndslib.o mpilib.o ndscrypt.o
endif
ifdef SIGNATURES
CFLAGS += -DSIGNATURES
SIGN_OBJ = ncpsign.o
endif
default:
make -C ..
@@ -27,8 +36,17 @@ all: libcom_err.a ncplib_err.o $(NCP_LIB)
install:
$(INSTALL_LIB)
mpilib.o: mpilib.c
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c mpilib.c
ndscrypt.o: ndscrypt.c
$(CC) $(CFLAGS) -c ndscrypt.c
ndslib.o: ndslib.c
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c ndslib.c
ncpsign.o: ncpsign.c
$(CC) $(CFLAGS) -c ncpsign.c
ncplib.o: ncplib.c ncplib_err.h
$(CC) $(CFLAGS) -c ncplib.c
$(CC) $(CFLAGS) -c ncplib.c
COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \
com_err/init_et.c
@@ -38,8 +56,9 @@ COM_ERR_OFILES = com_err/com_err.o com_err/error_message.o com_err/et_name.o \
libcom_err.a: $(COM_ERR_CFILES)
make -C com_err
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(COM_ERR_OFILES)
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a $(SIGN_OBJ) $(NDS_OBJ)
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(SIGN_OBJ) \
$(COM_ERR_OFILES) $(NDS_OBJ)
ln -sf libncp.so.1.0 libncp.so.1
ln -sf libncp.so.1 libncp.so
export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH

1881
lib/mpilib.c Normal file

File diff suppressed because it is too large Load Diff

468
lib/mpilib.h Normal file
View File

@@ -0,0 +1,468 @@
/* C include file for MPI multiprecision integer math routines.
Boulder Software Engineering
3021 Eleventh Street
Boulder, CO 80304
(303) 541-0140
(c) Copyright 1986-92 by Philip Zimmermann. All rights reserved.
The author assumes no liability for damages resulting from the use
of this software, even if the damage results from defects in this
software. No warranty is expressed or implied.
These routines implement all of the multiprecision arithmetic necessary
for Rivest-Shamir-Adleman (RSA) public key cryptography, as well as
other number-theoretic algorithms such as ElGamal, Diffie-Hellman,
or Rabin.
Although originally developed in Microsoft C for the IBM PC, this code
contains few machine dependencies. It assumes 2's complement
arithmetic. It can be adapted to 8-bit, 16-bit, or 32-bit machines,
lowbyte-highbyte order or highbyte-lowbyte order. This version
has been converted to ANSI C.
Modified 8 Apr 92 - HAJK - Implement new VAX/VMS primitive support.
Modified 29 Nov 92 - Thad Smith
*/
#include <string.h>
#include "usuals.h" /* typedefs for byte, word16, boolean, etc. */
#include "platform.h" /* customization for different environments */
/* Platform customization:
* A version which runs on almost any computer can be implemented by
* defining PORTABLE and MPORTABLE, preferably as a command line
* parameter. Faster versions can be generated by specifying specific
* parameters, such as size of unit and MULTUNIT, and by supplying some
* of the critical in assembly. See the file platform.h for more
* details on customization.
*
* The symbol HIGHFIRST, designating that integers and longs are stored
* with the most significant bit in the lowest address, should be defined
* on the command line for compiling all files, since it is used by files
* other than the mpilib routines.
*/
#ifndef ALIGN
#define ALIGN
#endif
#ifndef PEASANT /* if not Russian peasant modulo multiply algorithm */
#ifndef MERRITT /* if not Merritt's modmult */
#ifndef UPTON /* if not Upton's modmult */
#ifndef SMITH
#define SMITH /* default: use Smith's modmult algorithm */
#endif
#endif
#endif
#endif
#ifdef SMITH
#define UPTON_OR_SMITH /* enable common code */
#endif
#ifdef UPTON
#define UPTON_OR_SMITH /* enable common code */
#endif
#ifndef UNIT32
#ifndef UNIT8
#define UNIT16 /* default--use 16-bit units */
#endif
#endif
/*** CAUTION: If your machine has an unusual word size that is not a
power of 2 (8, 16, 32, or 64) bits wide, then the macros here that
use the symbol "LOG_UNITSIZE" must be changed.
***/
#ifdef UNIT8
typedef unsigned char unit;
typedef signed char signedunit;
#define UNITSIZE 8 /* number of bits in a unit */
#define LOG_UNITSIZE 3
#define uppermostbit ((unit) 0x80)
#define BYTES_PER_UNIT 1 /* number of bytes in a unit */
#define units2bits(n) ((n) << 3) /* fast multiply by UNITSIZE */
#define units2bytes(n) (n)
#define bits2units(n) (((n)+7) >> 3)
#define bytes2units(n) (n)
#endif
#ifdef UNIT16
typedef word16 unit;
typedef short signedunit;
#define UNITSIZE 16 /* number of bits in a unit */
#define LOG_UNITSIZE 4
#define uppermostbit ((unit) 0x8000)
#define BYTES_PER_UNIT 2 /* number of bytes in a unit */
#define units2bits(n) ((n) << 4) /* fast multiply by UNITSIZE */
#define units2bytes(n) ((n) << 1)
#define bits2units(n) (((n)+15) >> 4)
#define bytes2units(n) (((n)+1) >> 1)
#endif
#ifdef UNIT32
typedef word32 unit;
typedef long signedunit;
#define UNITSIZE 32 /* number of bits in a unit */
#define LOG_UNITSIZE 5
#define uppermostbit ((unit) 0x80000000L)
#define BYTES_PER_UNIT 4 /* number of bytes in a unit */
#define units2bits(n) ((n) << 5) /* fast multiply by UNITSIZE */
#define units2bytes(n) ((n) << 2)
#define bits2units(n) (((n)+31) >> 5)
#define bytes2units(n) (((n)+3) >> 2)
#endif
#define power_of_2(b) ((unit) 1 << (b)) /* computes power-of-2 bit masks */
#define bits2bytes(n) (((n)+7) >> 3)
/* Some C compilers (like the ADSP2101) will not always collapse constant
expressions at compile time if the expressions contain shift operators. */
/* #define uppermostbit power_of_2(UNITSIZE-1) */
/* #define UNITSIZE units2bits(1) */ /* number of bits in a unit */
/* #define bytes2units(n) bits2units((n)<<3) */
/* #define BYTES_PER_UNIT (UNITSIZE >> 3) */
/* LOG_UNITSIZE is the log base 2 of UNITSIZE, ie: 4 for 16-bit units */
/* #define units2bits(n) ((n) << LOG_UNITSIZE) */ /* fast multiply by UNITSIZE */
/* #define units2bytes(n) ((n) << (LOG_UNITSIZE-3)) */
/* #define bits2units(n) (((n)+(UNITSIZE-1)) >> LOG_UNITSIZE) */
/* #define bytes2units(n) (((n)+(BYTES_PER_UNIT-1)) >> (LOG_UNITSIZE-3)) */
typedef unit *unitptr;
/*--------------------- Byte ordering stuff -------------------*/
#ifdef HIGHFIRST
/* these definitions assume MSB comes first */
#define tohigher(n) (-(n)) /* offset towards higher unit */
#define pre_higherunit(r) (--(r))
#define pre_lowerunit(r) (++(r))
#define post_higherunit(r) ((r)--)
#define post_lowerunit(r) ((r)++)
#define bit_index(n) (global_precision-bits2units((n)+1))
#define lsbptr(r,prec) ((r)+(prec)-1)
#define make_lsbptr(r,prec) (r) = lsbptr(r,prec)
#define unmake_lsbptr(r,prec) (r) = ((r)-(prec)+1)
#define msbptr(r,prec) (r)
#define make_msbptr(r,prec) /* (r) = msbptr(r,prec) */
/* The macro rescale(r,current_precision,new_precision) rescales
a multiprecision integer by adjusting r and its precision to new values.
It can be used to reverse the effects of the normalize
routine given above. See the comments in normalize concerning
Intel vs. Motorola LSB/MSB conventions.
WARNING: You can only safely call rescale on registers that
you have previously normalized with the above normalize routine,
or are known to be big enough for the new precision. You may
specify a new precision that is smaller than the current precision.
You must be careful not to specify a new_precision value that is
too big, or which adjusts the r pointer out of range.
*/
#define rescale(r,currentp,newp) r -= ((newp) - (currentp))
/* The macro normalize(r,precision) "normalizes" a multiprecision integer
by adjusting r and precision to new values. For Motorola-style processors
(MSB-first), r is a pointer to the MSB of the register, and must
be adjusted to point to the first nonzero unit. For Intel/VAX-style
(LSB-first) processors, r is a pointer to the LSB of the register,
and must be left unchanged. The precision counter is always adjusted,
regardless of processor type. In the case of precision = 0,
r becomes undefined.
*/
#define normalize(r,prec) \
{ prec = significance(r); r += (global_precision-(prec)); }
#else /* LOWFIRST byte order */
/* these definitions assume LSB comes first */
#define tohigher(n) (n) /* offset towards higher unit */
#define pre_higherunit(r) (++(r))
#define pre_lowerunit(r) (--(r))
#define post_higherunit(r) ((r)++)
#define post_lowerunit(r) ((r)--)
#define bit_index(n) (bits2units((n)+1)-1)
#define lsbptr(r,prec) (r)
#define make_lsbptr(r,prec) /* (r) = lsbptr(r,prec) */
#define unmake_lsbptr(r,prec) /* (r) = (r) */
#define msbptr(r,prec) ((r)+(prec)-1)
#define make_msbptr(r,prec) (r) = msbptr(r,prec)
#define rescale(r,currentp,newp) /* nil statement */
#define normalize(r,prec) prec = significance(r)
#endif /* LOWFIRST byte order */
/*------------------ End byte ordering stuff -------------------*/
/* Note that the address calculations require that lsbptr, msbptr,
make_lsbptr, make_msbptr, mp_tstbit, mp_setbit, mp_clrbit,
and bitptr all have unitptr arguments, not byte pointer arguments. */
#define bitptr(r,n) &((r)[bit_index(n)])
#define bitmsk(n) power_of_2((n) & (UNITSIZE-1))
/* bitmsk() assumes UNITSIZE is a power of 2 */
#define mp_tstbit(r,n) (*bitptr(r,n) & bitmsk(n))
#define mp_setbit(r,n) (*bitptr(r,n) |= bitmsk(n))
#define mp_clrbit(r,n) (*bitptr(r,n) &= ~bitmsk(n))
#define msunit(r) (*msbptr(r,global_precision))
#define lsunit(r) (*lsbptr(r,global_precision))
/* #define mp_tstminus(r) ((msunit(r) & uppermostbit)!=0) */
#define mp_tstminus(r) ((signedunit) msunit(r) < 0)
/* set working precision to specified number of bits. */
#ifdef mp_setp
void mp_setp(short nbits);
#define set_precision(prec) mp_setp(units2bits(global_precision=(prec)))
#else
#define set_precision(prec) (global_precision = (prec))
#endif
#ifdef PEASANT
/* Define C names for Russian peasant modmult primitives. */
#define stage_modulus stage_peasant_modulus
#define mp_modmult peasant_modmult
#define modmult_burn peasant_burn
#define SLOP_BITS PEASANT_SLOP_BITS
#else /* not PEASANT */
#ifdef MERRITT
/* Define C names for Merritt's modmult primitives. */
#define stage_modulus stage_merritt_modulus
#define mp_modmult merritt_modmult
#define modmult_burn merritt_burn
#define SLOP_BITS MERRITT_SLOP_BITS
#else /* not PEASANT, MERRITT */
#ifdef UPTON
/* Define C names for Upton's modmult primitives. */
#define stage_modulus stage_upton_modulus
#define mp_modmult upton_modmult
#define modmult_burn upton_burn
#define SLOP_BITS UPTON_SLOP_BITS
#else /* not PEASANT, MERRITT, UPTON */
#ifdef SMITH
/* Define C names for Smith's modmult primitives. */
#define stage_modulus stage_smith_modulus
#define mp_modmult smith_modmult
#define modmult_burn smith_burn
#define SLOP_BITS SMITH_SLOP_BITS
#endif /* SMITH */
#endif /* UPTON */
#endif /* MERRITT */
#endif /* PEASANT */
#define mp_shift_left(r1) mp_rotate_left(r1,(boolean)0)
/* multiprecision shift left 1 bit */
#define mp_add(r1,r2) mp_addc(r1,r2,(boolean)0)
/* multiprecision add with no carry */
#define mp_sub(r1,r2) mp_subb(r1,r2,(boolean)0)
/* multiprecision subtract with no borrow */
#define mp_abs(r) (mp_tstminus(r) ? (mp_neg(r),TRUE) : FALSE)
#define msub(r,m) if (mp_compare(r,m) >= 0) mp_sub(r,m)
/* Prevents r from getting bigger than modulus m */
#define testeq(r,i) \
( (lsunit(r)==(i)) && (significance(r)<=1) )
#define testne(r,i) \
( (lsunit(r)!=(i)) || (significance(r)>1) )
#define testge(r,i) \
( (lsunit(r)>=(i)) || (significance(r)>1) )
#define testle(r,i) \
( (lsunit(r)<=(i)) && (significance(r)<=1) )
#define mp_square(r1,r2) mp_mult(r1,r2,r2)
/* Square r2, returning product in r1 */
#define mp_modsquare(r1,r2) mp_modmult(r1,r2,r2)
/* Square r2, returning modulo'ed product in r1 */
#define countbytes(r) ((countbits(r)+7)>>3)
/* SLOP_BITS is how many "carry bits" to allow for intermediate
calculation results to exceed the size of the modulus.
It is used by modexp to give some overflow elbow room for
modmult to use to perform modulo operations with the modulus.
The number of slop bits required is determined by the modmult
algorithm. The Russian peasant modmult algorithm only requires
1 slop bit, for example. Note that if we use an external assembly
modmult routine, SLOP_BITS may be meaningless or may be defined in a
non-constant manner.
*/
#define PEASANT_SLOP_BITS 1
#define MERRITT_SLOP_BITS UNITSIZE
#define UPTON_SLOP_BITS (UNITSIZE/2)
#ifdef mp_smul /* old version requires MS word = 0 */
#define SMITH_SLOP_BITS UNITSIZE
#else /* mp_smula or C version of mp_smul */
#define SMITH_SLOP_BITS 0
#endif /* mp_smul */
/* MAX_BIT_PRECISION is upper limit that assembly primitives can handle.
It must be less than 32704 bits, or 4088 bytes. It should be an
integer multiple of UNITSIZE*2.
*/
#if (SLOP_BITS > 0)
#define MAX_BIT_PRECISION (1280+(2*UNITSIZE))
#else
#define MAX_BIT_PRECISION 1280
#endif
#define MAX_BYTE_PRECISION (MAX_BIT_PRECISION/8)
#define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/UNITSIZE)
/* global_precision is the unit precision last set by set_precision */
extern short global_precision;
/* The "bit sniffer" macros all begin sniffing at the MSB.
They are used internally by all the various multiply, divide,
modulo, exponentiation, and square root functions.
*/
#define sniff_bit(bptr,bitmask) (*(bptr) & bitmask)
#define init_bitsniffer(bptr,bitmask,prec,bits) \
{ normalize(bptr,prec); \
if (!prec) \
return(0); \
bits = units2bits(prec); \
make_msbptr(bptr,prec); bitmask = uppermostbit; \
while (!sniff_bit(bptr,bitmask)) \
{ bitmask >>= 1; bits--; \
} \
}
#define bump_bitsniffer(bptr,bitmask) \
{ if (!(bitmask >>= 1)) \
{ bitmask = uppermostbit; \
post_lowerunit(bptr); \
} \
}
/* bump_2bitsniffers is used internally by mp_udiv. */
#define bump_2bitsniffers(bptr,bptr2,bitmask) \
{ if (!(bitmask >>= 1)) \
{ bitmask = uppermostbit; \
post_lowerunit(bptr); \
post_lowerunit(bptr2); \
} \
}
/* stuff_bit is used internally by mp_udiv and mp_sqrt. */
#define stuff_bit(bptr,bitmask) *(bptr) |= bitmask
boolean mp_addc
(register unitptr r1,register unitptr r2,register boolean carry);
/* multiprecision add with carry r2 to r1, result in r1 */
boolean mp_subb
(register unitptr r1,register unitptr r2,register boolean borrow);
/* multiprecision subtract with borrow, r2 from r1, result in r1 */
boolean mp_rotate_left(register unitptr r1,register boolean carry);
/* multiprecision rotate left 1 bit with carry, result in r1. */
void mp_shift_right_bits(register unitptr r1,register short bits);
/* multiprecision shift right bits, result in r1. */
short mp_compare(register unitptr r1,register unitptr r2);
/* Compares registers *r1, *r2, and returns -1, 0, or 1 */
boolean mp_inc(register unitptr r);
/* Increment multiprecision integer r. */
boolean mp_dec(register unitptr r);
/* Decrement multiprecision integer r. */
void mp_neg(register unitptr r);
/* Compute 2's complement, the arithmetic negative, of r */
#ifndef mp_move
#define mp_move(d,s) memcpy((void*)(d), (void*)(s), \
units2bytes(global_precision))
#endif
#ifndef unitfill0
#define unitfill0(r,ct) memset((void*)(r), 0, units2bytes(ct))
#endif
#ifndef mp_burn
#define mp_burn(r) mp_init(r,0) /* for burning the evidence */
#define mp_init0(r) mp_init(r,0)
#endif
#define empty_array(r) unitfill0(r, sizeof(r)/sizeof(r[0])/sizeof(unit))
void mp_init(register unitptr r, word16 value);
/* Init multiprecision register r with short value. */
short significance(register unitptr r);
/* Returns number of significant units in r */
int mp_udiv(register unitptr remainder,register unitptr quotient,
register unitptr dividend,register unitptr divisor);
/* Unsigned divide, treats both operands as positive. */
int mp_recip(register unitptr quotient,register unitptr divisor);
/* Compute reciprocal as 1/divisor. Used by faster modmult. */
int mp_div(register unitptr remainder,register unitptr quotient,
register unitptr dividend,register unitptr divisor);
/* Signed divide, either or both operands may be negative. */
word16 mp_shortdiv(register unitptr quotient,
register unitptr dividend,register word16 divisor);
/* Returns short remainder of unsigned divide. */
int mp_mod(register unitptr remainder,
register unitptr dividend,register unitptr divisor);
/* Unsigned divide, treats both operands as positive. */
word16 mp_shortmod(register unitptr dividend,register word16 divisor);
/* Just returns short remainder of unsigned divide. */
int mp_mult(register unitptr prod,
register unitptr multiplicand,register unitptr multiplier);
/* Computes multiprecision prod = multiplicand * multiplier */
int countbits(unitptr r);
/* Returns number of significant bits in r. */
int stage_peasant_modulus(unitptr n);
int stage_merritt_modulus(unitptr n);
int stage_upton_modulus(unitptr n);
int stage_smith_modulus(unitptr n);
/* Must pass modulus to stage_modulus before calling modmult. */
int peasant_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
int merritt_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
int upton_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
int smith_modmult(register unitptr prod,
unitptr multiplicand,register unitptr multiplier);
/* Performs combined multiply/modulo operation, with global modulus */
int mp_modexp(register unitptr expout,register unitptr expin,
register unitptr exponent,register unitptr modulus);
/* Combined exponentiation/modulo algorithm. */
int mp_modexp_crt(unitptr expout, unitptr expin,
unitptr p, unitptr q, unitptr ep, unitptr eq, unitptr u);
/* exponentiation and modulo using Chinese Remainder Theorem */
/****************** end of MPI library ****************************/

View File

@@ -7,6 +7,12 @@
#include "ncplib.h"
#include "ncplib_err.h"
#ifdef SIGNATURES
#include "ncpsign.h"
#endif
#ifdef NDS_SUPPORT
#include "ndslib.h"
#endif
#include <sys/ioctl.h>
extern pid_t wait(int *);
@@ -20,7 +26,7 @@ extern pid_t wait(int *);
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <linux/route.h>
#include "kernel/route.h"
#include <sys/param.h>
#include <stdlib.h>
#include <mntent.h>
@@ -28,9 +34,21 @@ extern pid_t wait(int *);
#include <sys/stat.h>
#include <stdarg.h>
#define NCP_DEFAULT_BUFSIZE 1024
#ifdef SIGNATURES
#define NCP_DEFAULT_OPTIONS 2
int in_options=NCP_DEFAULT_OPTIONS;
#endif
static long
ncp_negotiate_buffersize(struct ncp_conn *conn,
int size, int *target);
#ifdef SIGNATURES
static long
ncp_negotiate_size_and_options(struct ncp_conn *conn,
int size, int options,
int *ret_size, int *ret_options);
#endif
static long
ncp_login_object(struct ncp_conn *conn,
const unsigned char *username,
@@ -93,7 +111,7 @@ ipx_fprint_node(FILE * file, IPXNode node)
void
ipx_fprint_network(FILE * file, IPXNet net)
{
fprintf(file, "%08lX", ntohl(net));
fprintf(file, "%08X", (u_int32_t)ntohl(net));
}
void
@@ -160,15 +178,16 @@ ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target)
{
char *p;
struct sockaddr_ipx addr;
unsigned long sipx_network;
addr.sipx_family = AF_IPX;
addr.sipx_type = NCP_PTYPE;
if (sscanf(buf, "%lx", &addr.sipx_network) != 1)
if (sscanf(buf, "%lx", &sipx_network) != 1)
{
return 1;
}
addr.sipx_network = htonl(addr.sipx_network);
addr.sipx_network = htonl(sipx_network);
if ((p = strchr(buf, ':')) == NULL)
{
return 1;
@@ -341,6 +360,12 @@ do_ncp_call(struct ncp_conn *conn, int request_size)
long err;
memcpy(&request, conn->packet, sizeof(request));
#ifdef SIGNATURES
if (conn->sign_active)
{
sign_packet(conn, &request_size);
}
#endif
while (retries > 0)
{
@@ -394,7 +419,7 @@ do_ncp_call(struct ncp_conn *conn, int request_size)
0, 1, &err);
goto re_select;
}
ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE,
len = ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE,
0, 1, &err);
conn->reply_size = len;
return 0;
@@ -513,6 +538,9 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target,
int ncp_sock, wdog_sock;
long err;
#ifdef SIGNATURES
int options;
#endif
conn->is_connected = NOT_CONNECTED;
conn->verbose = 0;
@@ -582,10 +610,31 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target,
BVAL(conn->packet, 3) + (BVAL(conn->packet, 5) << 8);
conn->is_connected = CONN_TEMPORARY;
if ((ncp_negotiate_buffersize(conn, 1024,
&(conn->i.buffer_size)) != 0)
#ifdef SIGNATURES
conn->sign_wanted = 0;
conn->sign_active = 0;
if ((err = ncp_negotiate_size_and_options(conn,
NCP_DEFAULT_BUFSIZE, in_options,
&(conn->i.buffer_size), &options)) == 0)
{
if ((options & 2) != (in_options & 2))
{
if ((err = ncp_negotiate_size_and_options(conn,
NCP_DEFAULT_BUFSIZE, options & 2, &(conn->i.buffer_size),
&options)) != 0)
options = 0;
}
if (options & 2)
conn->sign_wanted = 1;
}
else
#endif
err = ncp_negotiate_buffersize(conn, NCP_DEFAULT_BUFSIZE,
&(conn->i.buffer_size));
if ((err != 0)
|| (conn->i.buffer_size < 512)
|| (conn->i.buffer_size > 1024))
|| (conn->i.buffer_size > NCP_DEFAULT_BUFSIZE))
{
ncp_do_close(conn);
return -1;
@@ -693,12 +742,33 @@ ncp_open_temporary(struct ncp_conn *conn,
if (strlen(spec->user) != 0)
{
#ifdef NDS_SUPPORT
if (!nds_get_tree_name(conn, NULL, 0))
{
if ((err = nds_login_auth(conn, spec->user,
spec->password)))
{
if ((err != NCPL_ET_REQUEST_ERROR) ||
(conn->completion != NDS_GRACE_PERIOD))
{
ncp_do_close(conn);
return EACCES;
}
fprintf(stderr, "Your password has expired\n");
}
}
else
{
#endif
if (ncp_login_object(conn, spec->user, spec->login_type,
spec->password) != 0)
{
ncp_do_close(conn);
return EACCES;
}
#ifdef NDS_SUPPORT
}
#endif
strcpy(conn->user, spec->user);
}
return 0;
@@ -755,6 +825,16 @@ ncp_find_permanent(const struct ncp_conn_spec *spec)
errno = (result == NULL) ? ENOENT : 0;
return result;
}
#ifdef SIGNATURES
static void
ncp_sign_init_perm(struct ncp_conn *conn)
{
if (ioctl(conn->mount_fid, NCP_IOC_SIGN_WANTED,
&conn->sign_wanted) != 0)
conn->sign_wanted = 0;
conn->sign_active = 0;
}
#endif
static int
ncp_open_permanent(struct ncp_conn *conn,
@@ -792,6 +872,9 @@ ncp_open_permanent(struct ncp_conn *conn,
}
strcpy(conn->mount_point, mount_point);
conn->is_connected = CONN_PERMANENT;
#ifdef SIGNATURES
ncp_sign_init_perm(conn);
#endif
return 0;
}
@@ -865,6 +948,9 @@ ncp_open_mount(const char *mount_point, long *err)
*err = NCPL_ET_NO_NCPFS_FILE;
return NULL;
}
#ifdef SIGNATURES
ncp_sign_init_perm(result);
#endif
return result;
}
@@ -937,6 +1023,17 @@ ncp_close(struct ncp_conn *conn)
return 0;
}
int
ncp_get_mount_uid(int fid, uid_t* uid) {
__kernel_uid_t k_uid;
int err;
err = ioctl(fid, NCP_IOC_GETMOUNTUID, &k_uid);
if (err) return err;
*uid = k_uid;
return 0;
}
struct ncp_conn_ent *
ncp_get_conn_ent(FILE * filep)
{
@@ -985,7 +1082,7 @@ ncp_get_conn_ent(FILE * filep)
{
continue;
}
if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0)
if (ncp_get_mount_uid(fid, &entry.uid) != 0)
{
close(fid);
continue;
@@ -1568,6 +1665,30 @@ ncp_negotiate_buffersize(struct ncp_conn *conn,
return 0;
}
#ifdef SIGNATURES
static long
ncp_negotiate_size_and_options(struct ncp_conn *conn,
int size, int options,
int *ret_size, int *ret_options)
{
long result;
ncp_init_request(conn);
ncp_add_word_hl(conn, size);
ncp_add_byte(conn, options);
if ((result = ncp_request(conn, 0x61)) != 0)
{
ncp_unlock_conn(conn);
return result;
}
*ret_size = min(ncp_reply_word_hl(conn, 0), size);
*ret_options = ncp_reply_byte(conn, 4);
ncp_unlock_conn(conn);
return 0;
}
#endif
long
ncp_get_file_server_description_strings(struct ncp_conn *conn,
@@ -1746,6 +1867,34 @@ ncp_send_broadcast(struct ncp_conn *conn,
return result;
}
long
ncp_send_broadcast2(struct ncp_conn *conn,
unsigned int conns, const unsigned int* connlist,
const char* message)
{
int i;
long result;
i = strlen(message);
if (i > 255)
{
return NCPL_ET_MSG_TOO_LONG;
}
if (conns > 350) /* max pkt len ~ 1KB */
/* maybe do it by handshaked length ? */
return NCPL_ET_MSG_TOO_LONG;
ncp_init_request_s(conn, 0x0A);
ncp_add_word_lh(conn, conns);
for (;conns; --conns)
ncp_add_dword_lh(conn, *connlist++);
ncp_add_byte(conn, i);
ncp_add_mem(conn, message, i);
result = ncp_request(conn, 0x15);
ncp_unlock_conn(conn);
return result;
}
/*
* target is a 8-byte buffer
*/
@@ -2102,6 +2251,15 @@ ncp_login_encrypted(struct ncp_conn *conn,
result = ncp_request(conn, 23);
ncp_unlock_conn(conn);
#ifdef SIGNATURES
if ((result == 0) || ((result == NCPL_ET_REQUEST_ERROR) &&
(conn->completion == NCP_GRACE_PERIOD)))
{
memcpy(buf + 16, key, 8);
sign_init(buf, buf);
result = ncp_sign_start(conn, buf);
}
#endif
return result;
}
@@ -3096,6 +3254,143 @@ ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
return result;
}
long
ncp_get_queue_length(struct ncp_conn *conn,
__u32 queue_id,
__u32 *queue_length)
{
long result=-EINVAL;
ncp_init_request_s(conn, 125);
ncp_add_dword_hl(conn, queue_id);
if ((result = ncp_request(conn, 23)) != 0)
goto out;
if (conn->ncp_reply_size < 12)
{
ncp_printf("ncp_reply_size %d < 12\n",
conn->ncp_reply_size);
result=-EINVAL;
goto out;
}
if (ncp_reply_dword_hl(conn,0) != queue_id)
{
printf("Ouch! Server didn't reply with same queue id in ncp_get_queue_length!\n");
result=-EINVAL;
}
else
*queue_length = ncp_reply_dword_lh(conn,8);
out:
ncp_unlock_conn(conn);
return result;
}
long
ncp_get_queue_job_ids(struct ncp_conn *conn,
__u32 queue_id,
__u32 queue_section,
__u32 *length1,
__u32 *length2,
__u32 ids[])
{
long result;
ncp_init_request_s(conn,129);
ncp_add_dword_hl(conn, queue_id);
ncp_add_dword_lh(conn, queue_section);
if ((result = ncp_request(conn, 23)) != 0)
goto out;
if (conn->ncp_reply_size < 8)
{
ncp_printf("ncp_reply_size %d < 8\n",
conn->ncp_reply_size);
result=-EINVAL;
goto out;
}
*length2 = ncp_reply_dword_lh(conn,4);
if (conn->ncp_reply_size < 8 + 4*(*length2))
{
ncp_printf("ncp_reply_size %d < %d\n",
conn->ncp_reply_size, 8+4*(*length2));
result=-EINVAL;
goto out;
}
if (ids) {
int count = min(*length1, *length2)*sizeof(__u32);
int pos;
for (pos=0; pos<count; pos+=sizeof(__u32)) {
*ids++ = ncp_reply_dword_lh(conn, 8+pos);
}
}
*length1 = ncp_reply_dword_lh(conn,0);
out:
ncp_unlock_conn(conn);
return result;
}
long
ncp_get_queue_job_info(struct ncp_conn *conn,
__u32 queue_id,
__u32 job_id,
struct nw_queue_job_entry *jobdata)
{
long result;
ncp_init_request_s(conn,122);
ncp_add_dword_hl(conn, queue_id);
ncp_add_dword_lh(conn, job_id);
if ((result = ncp_request(conn, 23)) != 0)
goto out;
if (conn->ncp_reply_size < sizeof(struct nw_queue_job_entry))
{
ncp_printf("ncp_reply_size %d < %d\n",
conn->ncp_reply_size,sizeof(struct nw_queue_job_entry));
result=-EINVAL;
}
else
memcpy(jobdata,ncp_reply_data(conn,0), sizeof(struct nw_queue_job_entry));
out:
ncp_unlock_conn(conn);
return result;
}
long
NWRemoveJobFromQueue2
(
struct ncp_conn* conn,
__u32 queueID,
__u32 jobNumber
) {
long result;
ncp_init_request_s(conn, 0x80);
ncp_add_dword_hl(conn, queueID);
ncp_add_dword_lh(conn, jobNumber);
result = ncp_request(conn, 0x17);
if (result) {
if (result == NCPL_ET_REQUEST_ERROR) {
result = 0x8900 | conn->completion;
} else {
result = 0x88FF;
}
} else {
/* no output */
}
ncp_unlock_conn(conn);
return result;
}
static int
ncp_do_read(struct ncp_conn *conn, const char *file_id,
__u32 offset, __u16 to_read,
@@ -3243,12 +3538,16 @@ ncp_get_broadcast_message(struct ncp_conn *conn, char message[256])
long result;
int length;
ncp_init_request_s(conn, 1);
if ((result = ncp_request(conn, 21)) != 0)
ncp_init_request_s(conn, 0x0B);
if ((result = ncp_request(conn, 0x15)) != 0)
{
ncp_unlock_conn(conn);
return result;
ncp_init_request_s(conn, 0x01);
if ((result = ncp_request(conn, 0x15)) != 0)
{
ncp_unlock_conn(conn);
return result;
}
}
length = ncp_reply_byte(conn, 0);
message[length] = 0;
@@ -3325,3 +3624,180 @@ ncp_add_trustee_set(struct ncp_conn *conn,
ncp_unlock_conn(conn);
return result;
}
#ifdef SIGNATURES
long
ncp_sign_start(struct ncp_conn *conn, const char *sign_root)
{
char init_last[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
struct ncp_sign_init sign_init;
if (conn->sign_wanted)
{
memcpy(sign_init.sign_root, sign_root, 8);
memcpy(sign_init.sign_last, init_last, 16);
conn->sign_active = 1;
if (conn->is_connected == CONN_PERMANENT)
{
if (ioctl(conn->mount_fid, NCP_IOC_SIGN_INIT,
&sign_init))
return NCPL_ET_SIGNATURE_FAILED;
}
else
{
memcpy(conn->sign_root, sign_init.sign_root, 8);
memcpy(conn->sign_last, sign_init.sign_last, 16);
}
}
return 0;
}
#endif
#ifdef NDS_SUPPORT
long
ncp_send_nds_frag(struct ncp_conn *conn,
int ndsverb,
char *inbuf, int inbuflen,
char *outbuf, int outbufsize, int *outbuflen)
{
long result;
int sizeleft, i;
int maxdatasize = 514;
int first = 1;
int fraghnd = -1;
if (outbuflen) *outbuflen = 0;
do
{
sizeleft = maxdatasize;
ncp_init_request(conn);
ncp_add_byte(conn, 2);
ncp_add_dword_lh(conn, fraghnd);
if (first)
{
ncp_add_dword_lh(conn, maxdatasize - 8);
ncp_add_dword_lh(conn, inbuflen + 12);
ncp_add_dword_lh(conn, 0);
ncp_add_dword_lh(conn, ndsverb);
ncp_add_dword_lh(conn, outbufsize);
sizeleft -= 25;
first = 0;
}
else
sizeleft -= 5;
i = (sizeleft > inbuflen) ? inbuflen : sizeleft;
if (i) ncp_add_mem(conn, inbuf, i);
inbuflen -= i;
inbuf += i;
if ((result = ncp_request(conn, 0x68)) != 0)
{
ncp_unlock_conn(conn);
return result;
}
if (inbuflen)
{
if ((ncp_reply_dword_lh(conn, 0) != 4) ||
((fraghnd = ncp_reply_dword_lh(conn, 4)) == -1))
result = NCPL_ET_REPLY_FORMAT;
ncp_unlock_conn(conn);
if (result) return result;
}
} while (inbuflen);
i = ncp_reply_dword_lh(conn, 0) - 8;
if ((i < 0) || (ncp_reply_dword_lh(conn, 4) != -1))
{
ncp_unlock_conn(conn);
return NCPL_ET_REPLY_FORMAT;
}
if (i > outbufsize)
{
ncp_unlock_conn(conn);
return NCPL_ET_REPLY_TOO_LARGE;
}
if (outbuf)
{
memcpy(outbuf, ncp_reply_data(conn, 12), i);
if (outbuflen) *outbuflen = i;
}
if ((conn->completion = ncp_reply_dword_lh(conn, 8)))
result = NCPL_ET_REQUEST_ERROR;
ncp_unlock_conn(conn);
return result;
}
long
ncp_send_nds(struct ncp_conn *conn, int fn,
char *data_in, int data_in_len,
char *data_out, int data_out_max, int *data_out_len)
{
int i;
long err;
ncp_init_request(conn);
ncp_add_byte(conn, fn);
if (data_in) ncp_add_mem(conn, data_in, data_in_len);
if (!(err = ncp_request(conn, 0x68)))
{
i = conn->ncp_reply_size;
if (i > data_out_max) i = data_out_max;
if (data_out)
memcpy(data_out, ncp_reply_data(conn, 0), i);
if (data_out_len) *data_out_len = i;
}
else
if (data_out_len) *data_out_len = 0;
ncp_unlock_conn(conn);
return err;
}
long
ncp_change_conn_state(struct ncp_conn *conn, int new_state)
{
long err;
ncp_init_request_s(conn, 0x1d);
ncp_add_dword_lh(conn, new_state);
err = ncp_request(conn, 0x17);
ncp_unlock_conn(conn);
return err;
}
struct ncp_conn *
ncp_open_addr(struct sockaddr_ipx *target, long *err)
{
struct ncp_conn *conn;
FILE *p;
char buf[40];
sprintf(buf, "nwsfind -a %08x:%02x%02x%02x%02x%02x%02x:%04x",
(u_int32_t)ntohl(target->sipx_network),
(unsigned char)target->sipx_node[0],
(unsigned char)target->sipx_node[1],
(unsigned char)target->sipx_node[2],
(unsigned char)target->sipx_node[3],
(unsigned char)target->sipx_node[4],
(unsigned char)target->sipx_node[5],
ntohs(target->sipx_port));
if (!(p = popen(buf, "r"))) {
*err = errno;
return NULL;
}
fgets(buf, sizeof(buf), p);
if (pclose(p)) {
*err = EHOSTUNREACH;
return NULL;
}
if (!(conn = malloc(sizeof(struct ncp_conn))))
{
*err = ENOMEM;
return NULL;
}
memzero(*conn);
if ((*err = ncp_connect_addr(conn, target, 1)))
{
free(conn);
return NULL;
}
return conn;
}
#endif

View File

@@ -42,4 +42,16 @@ ec NCPL_ET_NO_IPX,
ec NCPL_ET_NO_NCPFS_FILE,
"The file is probably not on a ncpfs mounted directory"
end
ec NCPL_ET_REPLY_FORMAT,
"The reply packet is not in the expected format"
ec NCPL_ET_REPLY_TOO_LARGE,
"The reply packet/message is too large for the allocated buffer"
ec NCPL_ET_SIGNATURE_FAILED,
"Packet signature initializing failed"
ec NCPL_ET_TRANSPORT_UNKNOWN,
"Unknown transport type"
end

103
lib/ncpsign.c Normal file
View File

@@ -0,0 +1,103 @@
#ifdef SIGNATURES
/*
* ncpsign.c
*
* Arne de Bruijn (arne@knoware.nl), 1997
*
*/
#include <string.h>
#include "ncplib.h"
#include "ncpsign.h"
#define rol32(i,c) (((((i)&0xffffffff)<<c)&0xffffffff)| \
(((i)&0xffffffff)>>(32-c)))
/* i386: 32-bit, little endian, handles mis-alignment */
#ifdef __i386__
#define GET_LE32(p) (*(int *)(p))
#define PUT_LE32(p,v) { *(int *)(p)=v; }
#else
#define GET_LE32(p) DVAL_LH(p,0)
#define PUT_LE32(p,v) DSET_LH(p,0,v)
#endif
#define min(a,b) ((a)<(b)?(a):(b))
static void nwsign(char *r_data1, char *r_data2, char *outdata) {
int i;
unsigned int w0,w1,w2,w3;
static int rbit[4]={0, 2, 1, 3};
#ifdef __i386__
unsigned int *data2=(int *)r_data2;
#else
unsigned int data2[16];
for (i=0;i<16;i++)
data2[i]=GET_LE32(r_data2+(i<<2));
#endif
w0=GET_LE32(r_data1);
w1=GET_LE32(r_data1+4);
w2=GET_LE32(r_data1+8);
w3=GET_LE32(r_data1+12);
for (i=0;i<16;i+=4) {
w0=rol32(w0 + ((w1 & w2) | ((~w1) & w3)) + data2[i+0],3);
w3=rol32(w3 + ((w0 & w1) | ((~w0) & w2)) + data2[i+1],7);
w2=rol32(w2 + ((w3 & w0) | ((~w3) & w1)) + data2[i+2],11);
w1=rol32(w1 + ((w2 & w3) | ((~w2) & w0)) + data2[i+3],19);
}
for (i=0;i<4;i++) {
w0=rol32(w0 + (((w2 | w3) & w1) | (w2 & w3)) + 0x5a827999 + data2[i+0],3);
w3=rol32(w3 + (((w1 | w2) & w0) | (w1 & w2)) + 0x5a827999 + data2[i+4],5);
w2=rol32(w2 + (((w0 | w1) & w3) | (w0 & w1)) + 0x5a827999 + data2[i+8],9);
w1=rol32(w1 + (((w3 | w0) & w2) | (w3 & w0)) + 0x5a827999 + data2[i+12],13);
}
for (i=0;i<4;i++) {
w0=rol32(w0 + ((w1 ^ w2) ^ w3) + 0x6ed9eba1 + data2[rbit[i]+0],3);
w3=rol32(w3 + ((w0 ^ w1) ^ w2) + 0x6ed9eba1 + data2[rbit[i]+8],9);
w2=rol32(w2 + ((w3 ^ w0) ^ w1) + 0x6ed9eba1 + data2[rbit[i]+4],11);
w1=rol32(w1 + ((w2 ^ w3) ^ w0) + 0x6ed9eba1 + data2[rbit[i]+12],15);
}
PUT_LE32(outdata,(w0+GET_LE32(r_data1)) & 0xffffffff);
PUT_LE32(outdata+4,(w1+GET_LE32(r_data1+4)) & 0xffffffff);
PUT_LE32(outdata+8,(w2+GET_LE32(r_data1+8)) & 0xffffffff);
PUT_LE32(outdata+12,(w3+GET_LE32(r_data1+12)) & 0xffffffff);
}
/*
* Initialize packet signatures
* The first 16 bytes of logindata are the shuffled password,
* the last 8 bytes the encryption key as received from the server.
*/
void sign_init(const char *logindata, char *sign_root) {
char initlast[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
char *initdata="Authorized NetWare Client";
char msg[64];
char hash[16];
memset(msg, 0, 64);
memcpy(msg, logindata, 24);
memcpy(msg + 24, initdata, 25);
nwsign(initlast, msg, hash);
memcpy(sign_root, hash, 8);
}
/*
* Make a signature for the current packet and add it at the end of the
* packet.
*/
void sign_packet(struct ncp_conn *conn, int *size) {
char data[64];
memset(data,0,64);
memcpy(data,conn->sign_root,8);
PUT_LE32(data+8,(*size));
memcpy(data+12,conn->packet+sizeof(struct ncp_request_header)-1,
min((*size)-sizeof(struct ncp_request_header)+1,52));
nwsign(conn->sign_last,data,conn->sign_last);
memcpy(conn->packet+(*size),conn->sign_last,8);
(*size)+=8;
}
#endif

295
lib/ndscrypt.c Normal file
View File

@@ -0,0 +1,295 @@
/*
NDS client for ncpfs
Copyright (C) 1997 Arne de Bruijn
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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <string.h>
#include "ndscrypt.h"
static unsigned int rol16(unsigned int i, int c) {
return ((i << c) & 65535) | ((unsigned int)(i & 65535) >> (16 - c));
}
static unsigned int ror16(unsigned int i, int c) {
return ((unsigned int)(i & 65535) >> c) | ((i << (16 - c)) & 65535);
}
char nwcryptdata[256]={
0xD9,0x78,0xF9,0xC4,0x19,0xDD,0xB5,0xED,0x28,0xE9,0xFD,0x79,
0x4A,0xA0,0xD8,0x9D,0xC6,0x7E,0x37,0x83,0x2B,0x76,0x53,0x8E,
0x62,0x4C,0x64,0x88,0x44,0x8B,0xFB,0xA2,0x17,0x9A,0x59,0xF5,
0x87,0xB3,0x4F,0x13,0x61,0x45,0x6D,0x8D,0x09,0x81,0x7D,0x32,
0xBD,0x8F,0x40,0xEB,0x86,0xB7,0x7B,0x0B,0xF0,0x95,0x21,0x22,
0x5C,0x6B,0x4E,0x82,0x54,0xD6,0x65,0x93,0xCE,0x60,0xB2,0x1C,
0x73,0x56,0xC0,0x14,0xA7,0x8C,0xF1,0xDC,0x12,0x75,0xCA,0x1F,
0x3B,0xBE,0xE4,0xD1,0x42,0x3D,0xD4,0x30,0xA3,0x3C,0xB6,0x26,
0x6F,0xBF,0x0E,0xDA,0x46,0x69,0x07,0x57,0x27,0xF2,0x1D,0x9B,
0xBC,0x94,0x43,0x03,0xF8,0x11,0xC7,0xF6,0x90,0xEF,0x3E,0xE7,
0x06,0xC3,0xD5,0x2F,0xC8,0x66,0x1E,0xD7,0x08,0xE8,0xEA,0xDE,
0x80,0x52,0xEE,0xF7,0x84,0xAA,0x72,0xAC,0x35,0x4D,0x6A,0x2A,
0x96,0x1A,0xD2,0x71,0x5A,0x15,0x49,0x74,0x4B,0x9F,0xD0,0x5E,
0x04,0x18,0xA4,0xEC,0xC2,0xE0,0x41,0x6E,0x0F,0x51,0xCB,0xCC,
0x24,0x91,0xAF,0x50,0xA1,0xF4,0x70,0x39,0x99,0x7C,0x3A,0x85,
0x23,0xB8,0xB4,0x7A,0xFC,0x02,0x36,0x5B,0x25,0x55,0x97,0x31,
0x2D,0x5D,0xFA,0x98,0xE3,0x8A,0x92,0xAE,0x05,0xDF,0x29,0x10,
0x67,0x6C,0xBA,0xC9,0xD3,0x00,0xE6,0xCF,0xE1,0x9E,0xA8,0x2C,
0x63,0x16,0x01,0x3F,0x58,0xE2,0x89,0xA9,0x0D,0x38,0x34,0x1B,
0xAB,0x33,0xFF,0xB0,0xBB,0x48,0x0C,0x5F,0xB9,0xB1,0xCD,0x2E,
0xC5,0xF3,0xDB,0x47,0xE5,0xA5,0x9C,0x77,0x0A,0xA6,0x20,0x68,
0xFE,0x7F,0xC1,0xAD};
#if 0
char shuffle_table[32]=
{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};
char shuffle_table2[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};
#endif
char nwhashdata[256] =
{0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,
0x1B,0x33,0xFD,0xD0,0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,
0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,0x41,0x9F,0xE1,0xD9,
0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,
0x3E,0xEE,0xFB,0x95,0x1A,0xFE,0xCE,0xA8,0x34,0xA9,0x13,0xF0,
0xA6,0x3F,0xD8,0x0C,0x78,0x24,0xAF,0x23,0x52,0xC1,0x67,0x17,
0xF5,0x66,0x90,0xE7,0xE8,0x07,0xB8,0x60,0x48,0xE6,0x1E,0x53,
0xF3,0x92,0xA4,0x72,0x8C,0x08,0x15,0x6E,0x86,0x00,0x84,0xFA,
0xF4,0x7F,0x8A,0x42,0x19,0xF6,0xDB,0xCD,0x14,0x8D,0x50,0x12,
0xBA,0x3C,0x06,0x4E,0xEC,0xB3,0x35,0x11,0xA1,0x88,0x8E,0x2B,
0x94,0x99,0xB7,0x71,0x74,0xD3,0xE4,0xBF,0x3A,0xDE,0x96,0x0E,
0xBC,0x0A,0xED,0x77,0xFC,0x37,0x6B,0x03,0x79,0x89,0x62,0xC6,
0xD7,0xC0,0xD2,0x7C,0x6A,0x8B,0x22,0xA3,0x5B,0x05,0x5D,0x02,
0x75,0xD5,0x61,0xE3,0x18,0x8F,0x55,0x51,0xAD,0x1F,0x0B,0x5E,
0x85,0xE5,0xC2,0x57,0x63,0xCA,0x3D,0x6C,0xB4,0xC5,0xCC,0x70,
0xB2,0x91,0x59,0x0D,0x47,0x20,0xC8,0x4F,0x58,0xE0,0x01,0xE2,
0x16,0x38,0xC4,0x6F,0x3B,0x0F,0x65,0x46,0xBE,0x7E,0x2D,0x7B,
0x82,0xF9,0x40,0xB5,0x1D,0x73,0xF8,0xEB,0x26,0xC7,0x87,0x97,
0x25,0x54,0xB1,0x28,0xAA,0x98,0x9D,0xA5,0x64,0x6D,0x7A,0xD4,
0x10,0x81,0x44,0xEF,0x49,0xD6,0xAE,0x2E,0xDD,0x76,0x5C,0x2F,
0xA7,0x1C,0xC9,0x09,0x69,0x9A,0x83,0xCF,0x29,0x39,0xB9,0xE9,
0x4C,0xFF,0x43,0xAB};
void nwencrypt(const unsigned short *cryptbuf, const char *in, char *out) {
int i, j;
register unsigned int i1, i2, i3, i4;
unsigned short *p;
i1 = *((unsigned short *)in);
i2 = *((unsigned short *)in + 1);
i3 = *((unsigned short *)in + 2);
i4 = *((unsigned short *)in + 3);
p = (unsigned short *)cryptbuf;
for (j = 3; j; j--) {
for (i = (j == 2) ? 6 : 5; i; i--) {
i1 = rol16(i1 + (*p++) + (i4 & i3) + (~i4 & i2), 1);
i2 = rol16(i2 + (*p++) + (i1 & i4) + (~i1 & i3), 2);
i3 = rol16(i3 + (*p++) + (i2 & i1) + (~i2 & i4), 3);
i4 = rol16(i4 + (*p++) + (i3 & i2) + (~i3 & i1), 5);
}
if (j > 1) {
i1 += cryptbuf[i4 & 63];
i2 += cryptbuf[i1 & 63];
i3 += cryptbuf[i2 & 63];
i4 += cryptbuf[i3 & 63];
}
}
*((unsigned short *)out) = i1;
*((unsigned short *)out + 1) = i2;
*((unsigned short *)out + 2) = i3;
*((unsigned short *)out + 3) = i4;
}
void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out) {
int i, j;
unsigned short *p;
register unsigned int i1, i2, i3, i4;
i1 = *((unsigned short *)in);
i2 = *((unsigned short *)in + 1);
i3 = *((unsigned short *)in + 2);
i4 = *((unsigned short *)in + 3);
p = (unsigned short *)cryptbuf + 64;
for (j = 3; j; j--) {
for (i = (j == 2) ? 6 : 5; i; i--) {
i4 = ror16(i4, 5) - (~i3 & i1) - (i3 & i2) - (*--p);
i3 = ror16(i3, 3) - (~i2 & i4) - (i2 & i1) - (*--p);
i2 = ror16(i2, 2) - (~i1 & i3) - (i1 & i4) - (*--p);
i1 = ror16(i1, 1) - (~i4 & i2) - (i4 & i3) - (*--p);
}
if (j > 1) {
i4 -= cryptbuf[i3 & 63];
i3 -= cryptbuf[i2 & 63];
i2 -= cryptbuf[i1 & 63];
i1 -= cryptbuf[i4 & 63];
}
}
*((unsigned short *)out) = i1;
*((unsigned short *)out + 1) = i2;
*((unsigned short *)out + 2) = i3;
*((unsigned short *)out + 3) = i4;
}
void nwcryptinit(unsigned short *scryptbuf, const char *key) {
int i;
unsigned char cryptbuf[128], *p;
memcpy(cryptbuf, key, 8);
for (i = 0; i < 120; i++)
cryptbuf[i + 8] =
nwcryptdata[(unsigned char)(cryptbuf[i] + cryptbuf[i + 7]) & 255];
cryptbuf[128 - 8] = nwcryptdata[(unsigned char)cryptbuf[128 - 8] & 255];
for (i = 127 - 8; i >= 0; i--)
cryptbuf[i] = nwcryptdata[(unsigned char)cryptbuf[i + 1] ^
(unsigned char)cryptbuf[i + 8]];
for (i = 0, p = cryptbuf; i < 64; i++, p += 2)
scryptbuf[i] = (*p) | (*(p+1)) << 8;
}
void nwencryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf) {
int i;
char nhash[8];
unsigned short cryptbuf[64];
nwcryptinit(cryptbuf, cryptkey);
memset(nhash, 0, 8);
while (buflen >= 8) {
for (i = 0; i < 8; i++, buf++)
nhash[i] ^= *buf;
nwencrypt(cryptbuf, nhash, nhash);
memcpy(outbuf, nhash, 8);
outbuf += 8;
buflen -= 8;
}
memset(cryptbuf, 0, sizeof(cryptbuf));
}
void nwdecryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf) {
int i;
char nhash[16], *p;
unsigned short cryptbuf[64];
nwcryptinit(cryptbuf, cryptkey);
memset(nhash, 0, 16);
p = nhash;
while (buflen >= 8) {
memcpy(p, buf, 8);
p = nhash + 8 - (p - nhash);
nwdecrypt(cryptbuf, buf, outbuf);
for (i = 0; i < 8; i++, outbuf++)
*outbuf ^= p[i];
buf += 8;
buflen -= 8;
}
memset(cryptbuf, 0, sizeof(cryptbuf));
}
void nwhash1(char *hash, int hashlen, const char *data, int datalen) {
unsigned char *hp, *hp1, *dp, *hend, c;
hp1 = (hp = (unsigned char *)hash) + 1;
hend = hp + hashlen;
dp = (unsigned char *)data;
while (datalen--) {
*hp = nwhashdata[*hp1 ^ *hp] ^ *dp++;
hp = hp1++;
if (hp1 == hend)
hp1 = (unsigned char *)hash;
}
while (hp-- > (unsigned char *)hash) {
hp1 = (unsigned char *)hash;
c = *hp1++;
while (*(hp1 - 1) = *hp1, ++hp1 < (unsigned char *)hash + hashlen);
*(hp1 - 1) = c;
}
}
void nwhash2(char *hashbuf, char c) {
int i, j;
char *p = hashbuf + hashbuf[0x40];
p[0x20] = p[0x00] ^ (p[0x10] = c);
hashbuf[0x41] = (p[0x30] ^= nwhashdata[(unsigned char)(c ^ hashbuf[0x41])]);
if (!(hashbuf[0x40] = (hashbuf[0x40] + 1) & 15)) {
c = 0;
for (i = 18; i; i--)
for (j = 48, p = hashbuf; j; j--)
c = (*(p++) ^= nwhashdata[((unsigned char)c + j) & 255]);
}
}
void nwhash2block(char *hashbuf, const char *data, int datalen) {
while (datalen--)
nwhash2(hashbuf, *data++);
}
void nwhash2end(char *hashbuf) {
int i, j;
for(j = i = 16 - hashbuf[0x40]; j; j--)
nwhash2(hashbuf, i);
for(i = 0x30; i < 0x40; i++)
nwhash2(hashbuf, hashbuf[i]);
}
#if 0
void shuffle(const char *objid, const char *pwd, char *out) {
unsigned char temp[32];
int i, j, k;
i = strlen(pwd);
memset(temp, 0, 32);
for (j = 0; j < i; j++)
temp[j & 31] ^= pwd[j];
if (i)
for (j = i; j < 32; j += i) {
temp[j++] = shuffle_table[j];
k = 32 - j;
memcpy(temp + j, pwd, (k > i) ? i : k);
}
for (i = 0; i < 32; i++)
temp[i] ^= objid[i & 3];
j = 0;
for (k = 0; k < 2; k++)
for (i = 0; i < 32; i++)
(char)j += temp[i] = (temp[i] + j) ^
(temp[(i + j) & 31] - shuffle_table[i]);
for (i = 0; i < 16; i++)
out[i] = shuffle_table2[temp[i * 2]] |
(shuffle_table2[temp[i * 2 + 1]] << 4);
}
#endif

47
lib/ndscrypt.h Normal file
View File

@@ -0,0 +1,47 @@
/*
NDS client for ncpfs
Copyright (C) 1997 Arne de Bruijn
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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _NDSCRYPT_H
#define _NDSCRYPT_H
#include <string.h>
void nwencrypt(const unsigned short *cryptbuf, const char *in, char *out);
void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out);
void nwcryptinit(unsigned short *scryptbuf, const char *key);
void nwencryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf);
void nwdecryptblock(const char *cryptkey, const char *buf, int buflen,
char *outbuf);
#define nwhash1init(hash, hashlen) memset(hash, 0, hashlen)
void nwhash1(char *hash, int hashlen, const char *data, int datalen);
#define nwhash2init(hashbuf) memset(hashbuf, 0, 0x42)
void nwhash2(char *hashbuf, char c);
void nwhash2block(char *hashbuf, const char *data, int datalen);
void nwhash2end(char *hashbuf);
#if 0
void shuffle(const char *objid, const char *pwd, char *out);
#else
void shuffle(const char *objid, const char *pwd, int buflen, char *out);
#endif
#endif /* _NDSCRYPT_H */

1235
lib/ndslib.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -142,7 +142,7 @@ shuffle1(buf32 temp, unsigned char *target)
}
static void
void
shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
unsigned char *target)
{

218
lib/platform.h Normal file
View File

@@ -0,0 +1,218 @@
/* platform.h - computer platform customization for PGP
multiprecision math package. #Included in mpilib.h.
*/
#ifndef PLATFORM_H
#define PLATFORM_H
/* Platform customization:
* A version which runs on almost any computer can be implemented by
* defining PORTABLE and MPORTABLE, preferably as a command line
* parameter. Faster versions can be generated by specifying specific
* parameters, such as size of unit and MULTUNIT, and by supplying some
* of the critical in assembly.
*
* This file holds customizations for different environments.
* This is done in one of two ways:
* 1. A symbol is defined on the command line which designates a
* particular environment, such as MSDOS. This file detects the
* environment symbol and sets the appropriate low-level defines.
*
* 2. If no environment is named, the low-level defines are set in
* the same manner as for PGP 2.0, thereby providing an easy upgrade.
*
* Following are a description of the low-level definition symbols:
*
* The following preprocessor symbols should be conditionally set to
* optimize for a particular environment.
*
* Define one of the following:
* UNIT8, UNIT16, or UNIT32 - specifies size of operands for
* multiprecision add, subtract, shift, and initialization operations.
* Define one of the following:
* MUNIT8, MUNIT16, MUNIT32 - specified size of operands for
* multiprecision multiply and mod_mult. This must be less than or
* equal to unit size. It should be the word size for the native
* atomic multiply instruction. For a 16x16 bit multiply yielding a
* 32-bit product, MUNIT16 should be set.
* Define one (or more) of the following:
* PEASANT, MERRITT, UPTON, SMITH -algorithm used for modmult. All defined
* algorithms are compiled, but the first defined name listed will be
* assigned to the generic entry point symbols. Multiple algorithms are
* used primarily for testing.
* HIGHFIRST - specified if longs are stored with the most significant
* bit at the lowest address (Motorola), undefined otherwise. This should
* be defined on the command line, normally in the makefile.
*
* The following symbol, if initialized, is set to specific values:
* ALIGN - variable declaration attribute which forces optimum alignment
* of words, e.g. for VAX C: ALIGN=_align(quadword)
*
* The following symbols correspond to individual multiprecision routines
* that may be implemented with assembly language. If they are implemented
* in assembly, the symbols should be defined with the name of the
* corresponding external entry points, e.g., mp_addc=P_ADDC
* mp_setp - set precision for external routines
* mp_addc - add with carry
* mp_subb - subtract with borrow
* mp_rotate_left - rotate left
* mp_compare - compare
* mp_move - move
* unitfill0 - zero fill
* mp_smul - multiply vector by single word *
* mp_smula - multiply vector by single word and accumulate *
* mp_dmul - full multiply
* mp_set_recip - setup for mp_quo_digit
* mp_quo_digit - quotient digit for modulus reduction
*
* Either mp_smul or mp_smula should be defined. mp_smula provides
* for accumulation to an existing value, while mp_smul is for use of the
* older definition of mp_smul, used in PGP 2.0, which assumed that the high
* order accumulator word is zero. Use of mp_smula causes one less word of
* precision to be used, thereby slightly increasing speed.
*/
/********************************************************************
* Environment customization. Please send any additions or corrections
* to Philip Zimmermann.
*/
#ifndef PORTABLE
#ifdef MSDOS
#ifndef i386 /* gcc */
#define UNIT16
#define MUNIT16
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define mp_smula P_SMULA
#define mp_quo_digit P_QUO_DIGIT
#define mp_set_recip P_SETRECIP
#define SMITH
#define PLATFORM_SPECIFIED
#endif /* i386 */
#endif /* MSDOS */
#ifdef VMS
#define UNIT32 /* use 32-bit units */
#define MUNIT32 /* not used in C code, only in assembler */
#define UPTON
#define mp_setp p_setp
#define mp_addc p_addc
#define mp_subb p_subb
#define mp_rotate_left p_rotl
#define mp_smul p_smul
#define mp_dmul p_dmul
#define mp_compare p_cmp
#define ALIGN _align(quadword)
#ifdef VAXC
/*
* A VAX is a CISC machine. Unfortunately C is at to low a level to use
* many of the instruction set enhancements so we define some macros
* here that implement fast moves and fast zero fills with single
* instructions.
*/
#pragma builtins
#define mp_move( dst, src) _MOVC3( global_precision*4, (char *) src, (char *) dst)
#define unitfill0( r, unitcount) _MOVC5( 0, (char *) 0, 0, unitcount*4, (char *) r)
#define mp_burn(r) _MOVC5(0, (char *) 0, 0, global_precision*4, (char *) r)
#define mp_init0(r) mp_burn(r) /* Just for documentation purposes */
#endif /* VAXC */
#define PLATFORM_SPECIFIED
#endif /* VMS */
#ifdef mips
/*
* Needs r3kd.s and r3000.s (or r3000.c)
*/
#define UNIT32
#define MUNIT32
#define SMITH
#define mp_dmul p_dmul
#define mp_setp p_setp
#define mp_addc p_addc
#define mp_subb p_subb
#define mp_rotate_left p_rotl
#define mp_smula p_smula
#define mp_quo_digit p_quo_digit
#define mp_set_recip p_setrecip
#define PLATFORM_SPECIFIED
#endif /* mips */
#ifdef i386
/*
* Needs 80386.S
*/
#define UNIT32
#define MUNIT32
#define SMITH
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#define mp_smula P_SMULA
#define mp_quo_digit p_quo_digit
#define mp_set_recip p_setrecip
#define PLATFORM_SPECIFIED
#endif /* i386 */
#ifdef sparc
/*
* Needs sparc.s
*/
#define UNIT32
#define MERRITT
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#define PLATFORM_SPECIFIED
#endif /* sparc */
#if defined(mc68000) || defined(mc68020)
/*
* Needs mc68020.S
*/
#define UNIT32
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#if defined(sun3) || defined(mc68020)
# define UPTON
# define MUNIT32
# define mp_smul P_SMUL
/* # define mp_dmul P_DMUL */ /* mc68020.s has a bug in P_DMUL */
#else
# define SMITH
# define MUNIT16
#endif
#define PLATFORM_SPECIFIED
#endif /* mc68000 */
/* Add additional platforms here ... */
/**************** End of system specification ************************/
#ifndef PLATFORM_SPECIFIED
/* No platform explicitly selected. Customization is controlled by
* PORTABLE and MPORTABLE.
*/
#define mp_setp P_SETP
#define mp_addc P_ADDC
#define mp_subb P_SUBB
#define mp_rotate_left P_ROTL
#define UPTON
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
#ifndef MPORTABLE
#define mp_smul P_SMUL
#endif /* MPORTABLE */
#endif /* PLATFORM_SPECIFIED */
#endif /* PORTABLE */
#endif /* PLATFORM_H */

41
lib/usuals.h Normal file
View File

@@ -0,0 +1,41 @@
/* usuals.h - The usual typedefs, etc.
*/
#ifndef USUALS /* Assures no redefinitions of usual types...*/
#define USUALS
typedef unsigned char boolean; /* values are TRUE or FALSE */
typedef unsigned char byte; /* values are 0-255 */
typedef byte *byteptr; /* pointer to byte */
typedef char *string; /* pointer to ASCII character string */
typedef unsigned short word16; /* values are 0-65535 */
#ifdef __alpha
typedef unsigned int word32; /* values are 0-4294967295 */
#else
typedef unsigned long word32; /* values are 0-4294967295 */
#endif
#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif /* if TRUE not already defined */
#ifndef min /* if min macro not already defined */
#define min(a,b) (((a)<(b)) ? (a) : (b) )
#define max(a,b) (((a)>(b)) ? (a) : (b) )
#endif /* if min macro not already defined */
/* void for use in pointers */
#ifndef NO_VOID_STAR
#define VOID void
#else
#define VOID char
#endif
/* Zero-fill the byte buffer. */
#define fill0(buffer,count) memset( buffer, 0, count )
/* This macro is for burning sensitive data. Many of the
file I/O routines use it for zapping buffers */
#define burn(x) fill0((VOID *)&(x),sizeof(x))
#endif /* if USUALS not already defined */