NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF SBIN/LOGIN
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/KERNEL.I
				.INB INC/MLI.I
				.INB INC/LIBCRYPT.I
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPUsrID			.BS 1

ZPShellPtr		.BS 2
ZPRetryCnt		.BS 1
ZPbValidUser	.BS 1

ZPhGetLine		.BS 1
ZPGetLinePtr	.BS 2
ZPbGetLineSecret	.BS 1
ZPbEsc			.BS 1
ZPGetLineLen	.BS 1
ZPGetLineMax	.BS 1

ZPhSID			.BS 1

ZPhFile			.BS 1
ZPStrPtr		.BS 2
ZS.END
				.ED
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					BIN Layout Version 1
				.DA #S.PS.F.EVENT		S.PS.F
				.DA #0
				.DA CS.END-CS.START		Code Size (without Constants)
				.DA DS.END-DS.START		Data Segment Size
				.DA #64					Stack Size
				.DA #ZS.END-ZS.START	Zero Page Size
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT
				.DA	CS.QUIT
L.MSG.NOAUTH	.DA MSG.NOAUTH
L.LIBCRYPT		.DA LIBCRYPT
L.MSG.LOGIN		.DA MSG.LOGIN
L.MSG.PASSWORD	.DA MSG.PASSWORD
L.MSG.BAD		.DA MSG.BAD
L.MSG.CRLF		.DA MSG.CRLF
L.MSG.BS		.DA MSG.BS
L.SESSION.ROOT	.DA SESSION.ROOT
L.ETCISSUE		.DA ETCISSUE
L.ETCMOTD		.DA ETCMOTD
L.SHELL			.DA SHELL
				.DA 0
*--------------------------------------
CS.INIT			clc
CS.INIT.RTS		rts
*--------------------------------------
CS.RUN			>LDYAI 256
				>SYSCALL getmem
				bcs CS.INIT.RTS

				>STYA ZPGetLinePtr
				stx ZPhGetLine
				
				>LDYA L.ETCISSUE
				jsr CS.RUN.DUMPFILE

				>PUSHW pData			PW
				lda #0
				>SYSCALL GetPWUID
				bcc CS.RUN.AUTH
				
				jmp CS.RUN.NOAUTH
*--------------------------------------
CS.RUN.AUTH		>LDYA L.LIBCRYPT
				>SYSCALL LoadLib
				bcs CS.INIT.RTS
				
				sta hLIBCRYPT

				lda #3
				sta ZPRetryCnt

.1				>PUSHBI 0
				>LDYA L.MSG.LOGIN
				>SYSCALL printf
				bcs .9
				
				lda #16
				clc
				jsr CS.RUN.GetLine
				bcs .9
				
				>PUSHW pData
				>LDYA ZPGetLinePtr
				>SYSCALL GetPWName
				ror ZPbValidUser
				
				>PUSHBI 0
				>LDYA L.MSG.PASSWORD
				>SYSCALL printf
				bcs .9
				
				lda #128
				sec
				jsr CS.RUN.GetLine
				bcs .9
				
				>PUSHBI 0
				>LDYA L.MSG.CRLF
				>SYSCALL printf
				bcs .9

				jsr CS.RUN.CHECKPWD
				bcc CS.RUN.LOGIN
				
				>PUSHBI 0
				>LDYA L.MSG.BAD
				>SYSCALL printf
				bcs .9
				
				dec ZPRetryCnt
				bne .1
				
				lda #E.IUSR
*				sec				
.9				rts
*--------------------------------------
CS.RUN.CHECKPWD	rol ZPbValidUser
				bcs CS.RUN.CHECK.9

				>PUSHW ZPGetlinePtr
				>PUSHW ZPGetlinePtr
				>LIBCALL hLIBCRYPT,LIBCRYPT.MD5
				
				>PUSHEA.G PW+S.PW.PASSWD
				>LDYA ZPGetlinePtr
				>SYSCALL strcmp

CS.RUN.CHECK.9	rts
*--------------------------------------
CS.RUN.LOGIN	jsr CS.RUN.SetUserSession
				
				bcc CS.RUN.EXEC
CS.RUN.LOGIN.9	rts
*--------------------------------------
CS.RUN.NOAUTH	>PUSHBI 0
				>LDYA L.MSG.NOAUTH
				>SYSCALL printf
				bcs CS.RUN.CHECK.9
				
				jsr CS.RUN.SetRootSession
				bcs CS.RUN.LOGIN.9

CS.RUN.EXEC		ldx #1

.1				lda S.Table.hSession-1,x
				beq .2
				inx
				cpx #K.USR.MAX+1
				bne .1
				
				lda #E.OOH
*				sec				
				rts	
				
.2				stx ZPUsrID
				txa
				
				ldy #S.PS.hSID
				sta (pPS),y
				
				lda ZPhSID
				ldx ZPUsrID
				sta S.Table.hSession-1,x
				
				ldy #S.PS.hStdIn
				lda (pPS),y
				sta S.Table.hFILE-1,x				

				>LDYA L.ETCMOTD
				jsr CS.RUN.DumpFile
				
				>PUSHBI S.PS.F.HOLD
				>LDYA L.SHELL
				>SYSCALL ExecL
				bcs .9
				
				>SLEEP
				
				ldx ZPUsrID
				lda S.Table.hSession-1,x
				stz S.Table.hSession-1,x
				stz S.Table.hFILE-1,x
				>SYSCALL freemem
				
.9				rts
*--------------------------------------
CS.RUN.SetRootSession
				>LDYA L.SESSION.ROOT
				>STYA ZPStrPtr
		
				>LDYAI SESSION.ROOT.Size			
				>SYSCALL getmem
				bcs .9
				>STYA pSession
				stx ZPhSID
				
				ldy #SESSION.ROOT.Size-1
				
.1				lda (ZPStrPtr),y
				sta (pSession),y
				dey
				bpl .1
				
*				clc
.9				rts
*--------------------------------------
CS.RUN.SetUserSession
				ldx #S.SESSION.NAME		P+UID+GID
				
				ldy #S.PW.NAME-1
				
.1				inx
				iny
				lda (pData),y
				bne .1					NAME len
				
				inx
				
				ldy #S.PW.GECOS-1
				
.2				inx
				iny
				lda (pData),y
				bne .2					GECOS len
				
				inx
				
				ldy #S.PW.DIR-1
				
.3				inx
				iny
				lda (pData),y
				bne .3					DIR len
				
				inx

				ldy #S.PW.SHELL-1
				
.4				inx
				iny
				lda (pData),y
				bne .4					SHELL len

				txa
				tay
				lda #0
				
				>SYSCALL getmem
				bcs .9
				>STYA pSession
				>STYA ZPStrPtr

				stx ZPhSID

*				clc

				ldy #S.PW.GID
				lda (pData),y
				tax
				bne .5
				
				sec
				
.5				ldy #S.PW.UID
				lda (pData),y
				bne .6
				
				sec
				
.6				lda #0
				ror
				jsr CS.RUN.AddByte			PRIV
				lda (pData),y
				jsr CS.RUN.AddByte			UID
				txa
				jsr CS.RUN.AddByte			GID
				
				ldy #S.PW.NAME
				jsr CS.RUN.AddStr
				
				ldy #S.PW.GECOS
				jsr CS.RUN.AddStr
				
				ldy #S.PW.DIR
				jsr CS.RUN.AddStr
				
				ldy #S.PW.SHELL
				jsr CS.RUN.AddStr
				
				lda #0
				jsr CS.RUN.AddByte

				clc
.9				rts
*--------------------------------------
CS.RUN.AddStr	lda (pData),y
				jsr CS.RUN.AddByte
				iny
				tax
				bne CS.RUN.AddStr
				rts
*--------------------------------------
CS.RUN.AddByte	sta (ZPStrPtr)
				inc ZPStrPtr
				bne .8
				inc ZPStrPtr+1
.8				rts
*--------------------------------------
CS.RUN.GetLine	sta ZPGetLineMax
				ror ZPbGetLineSecret
				stz ZPGetLineLen
				stz ZPbEsc
				
.1				>SYSCALL getchar
				bcs .9
				
				bit ZPbEsc
				bpl .11
				
*				clc
				ror ZPbEsc
				cmp #'D'
				bne .1
				bra .3
				
.11				cmp #C.DEL
				beq .3
				
				cmp #C.SPACE
				bcc .2
				
				ldy ZPGetLineLen
				cpy ZPGetLineMax
				beq .1
				
				sta (ZPGetLinePtr),y
				inc ZPGetLineLen
				
				bit ZPbGetLineSecret
				bmi .1
				
				>SYSCALL putchar
				bra .1

.2				cmp #3					Ctrl-C
				beq .9

				cmp #C.CR
				beq .8
				
				cmp #C.ESC
				bne .1
				
*				sec
				ror ZPbEsc
				bra .1
				
.3				ldy ZPGetLineLen
				beq .1
				dec ZPGetLineLen
				
				bit ZPbGetLineSecret
				bmi .1
				
				>PUSHBI 0
				>LDYA L.MSG.BS
				>SYSCALL printf
				bra .1
				
.8				ldy ZPGetLineLen
				lda #0
				sta (ZPGetLinePtr),y
				
				clc
				
.9				rts	
*--------------------------------------
CS.RUN.DumpFile	pha

				>PUSHWI 0				Aux type
				>PUSHBI S.FI.T.TXT
				>PUSHBI	O.RDONLY+O.TEXT
				
				pla
				>SYSCALL FOpen
				bcs .9
				
				stx ZPhFile		
				
.1				>PUSHWI	256
				>PUSHW ZPGetLinePtr
				lda ZPhFile

				>SYSCALL fgets
				bcs .8
				
				>LDYA ZPGetLinePtr
				>SYSCALL ExpandStr
				bcc .2

				php
				pha
				jsr .8
				pla
				plp
				rts
				
.2				phx
				>STYA ZPStrPtr
	
				ldy #$ff

.3				iny
				lda (ZPStrPtr),y
				bne .3
				
				lda #C.CR
				sta (ZPStrPtr),y
				iny
				lda #C.LF
				sta (ZPStrPtr),y
				iny
				lda #0
				sta (ZPStrPtr),y
				
				>PUSHBI 0
				>LDYA ZPStrPtr
				>SYSCALL printf
				
				pla
				>SYSCALL freemem
				bra .1
	
.8				lda ZPhFile
				>SYSCALL fclose
				
.9				rts				
*--------------------------------------
CS.DOEVENT		
				sec
				rts		
*--------------------------------------
CS.QUIT			lda ZPhGetLine
				beq .1
				
				>SYSCALL freemem
				
.1				lda hLIBCRYPT
				beq .8
				
				>SYSCALL UnloadLib
				
.8				clc
				rts
*--------------------------------------
CS.END
*--------------------------------------
LIBCRYPT		.AZ "libcrypt"
hLIBCRYPT		.BS 1
MSG.NOAUTH		.AS "\r\n\r\nA2osX-Login:No ETC/PASSWD file present, Logged as ROOT.\r\n"
				.AS "Consider adding ROOT password with USERADD command.\r\n"
MSG.CRLF		.AZ "\r\n"
MSG.LOGIN		.AZ "\r\nlogin:"
MSG.PASSWORD	.AZ "\r\npassword:"
MSG.BAD			.AZ "Bad user or password\r\n"
MSG.BS			.DA #C.BS,#C.SPACE,#C.BS,#0
ETCISSUE		.AZ "${ROOT}ETC/ISSUE"
ETCMOTD			.AZ "${ROOT}ETC/MOTD"
SHELL			.AZ "${SHELL}"
*--------------------------------------
SESSION.ROOT	.DA #S.SESSION.P.ROOT
				.DA #0					UID
				.DA #0					GID
				.AZ "ROOT"				NAME
				.AZ "Root User"			GECOS
				.AZ "${ROOT}ROOT/"		DIR
				.AZ "${ROOT}BIN/SH"		SHELL
SESSION.ROOT.Size	.EQ	*-SESSION.ROOT
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
PW				.BS S.PW
DS.END
				.ED
*--------------------------------------
MAN
SAVE USR/SRC/SBIN/LOGIN.S
ASM
