home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / filutl / passwd30.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  9.5 KB  |  360 lines

  1. ;    title    'PASSWORD.ASM'
  2. ;    page    60
  3. ;
  4. ;
  5. ;        PASSWORD.ASM
  6. ;        Version 3.0
  7. ;     By Bo McCormick       8/6/81
  8. ;
  9. ; This is a program that adds password protection
  10. ; to programs. Format:
  11. ;
  12. ; PASSWORD name_of_file
  13. ;
  14. ; Then answer the prompt with the password to be
  15. ; applied to the program:
  16. ;
  17. ; Password?  enter password here
  18. ;
  19. ; If everything goes well, the program will be saved to disk.
  20. ; If not, a message is printed and control is passed
  21. ; to the CCP.
  22. ;
  23. ; The good part of this is, when you type in the program
  24. ; program name next time, instead of running the program
  25. ; right away, the program asks you for the password. If you
  26. ; reply with something other than the original password, the
  27. ; program doesn't run, and it returns to the ccp.
  28. ;
  29. ; 2/10/82: Set DMA before open because 1.4 CP/M uses buffer at 80H
  30. ; Removed "$" from labels so other assemblers can be used. Fixed
  31. ; "offset" to use tpa instead of 100H so it would work with
  32. ; modified CP/M.  Added encryption of password so dumping .COM
  33. ; file will not reveal it.  (Thanks to author of XYZZY.COM)
  34. ; Fixed test of supplied password to check all characters.
  35. ; Ted Shapin
  36. ;
  37. ; 12/10/81: changed ot$pw routine to input password one character
  38. ; at a time invisibly from BIOS rather than using BDOS's string input
  39. ; function.  This allows password to be typed in without anyone
  40. ; seeing what it was that was typed.  Jim Mills
  41. ;
  42. ;EQUATES
  43. rdchar: equ    1
  44. mesout: equ    9        ;BDOS functions
  45. incon:    equ    10
  46. open:    equ    15
  47. close:    equ    16
  48. delete: equ    19
  49. read:    equ    20
  50. write:    equ    21
  51. setdma: equ    26
  52. ;
  53. cr    equ    0dh        ;ascii values
  54. lf    equ    0ah
  55. eos    equ    '$'
  56. ;
  57. boot    equ    0;4200H     ;0 for standard CP/M
  58.                 ;4200H for ALT. CP/M;
  59. bdos    equ    boot+5
  60. fcb    equ    boot+5ch
  61. defbuf    equ    boot+80h
  62. tpa    equ    boot+100h
  63. stack    equ    tpa        ;out of way of tpa
  64. ;
  65.     org    tpa
  66.  
  67. ;
  68. ;
  69. start:    lxi    h,0        ;save stack pointer
  70.     dad    sp        ;put stack in hl
  71.     shld    oldstack-offset ;save it
  72.     lxi    sp,stack    ;get new stack
  73. ;
  74. ; stack saved so program can return to CCP without
  75. ; intervening warm start.
  76. ;
  77.     lda    fcb+9        ;get first char of extension
  78.     cpi    ' '        ;if ' ' then change to .COM
  79.     jz    notype
  80.     cpi    'C'        ;If there is an extension,
  81.     jnz    notright    ;make sure it's .COM
  82.     lda    fcb+10        ;check second letter
  83.     cpi    'O'
  84.     jnz    notright
  85.     lda    fcb+11
  86.     cpi    'M'        ;last letter
  87.     jz    iscom        ;if it is a COM, then cont.
  88. notright:
  89.     call    endmes        ;it's not a com file, so tell
  90. ;
  91.     db    cr,lf,'Must be a command (.COM) file'
  92.     db    cr,lf,eos
  93. ;
  94. endmes:
  95.     pop    d        ;get address of message
  96.     mvi    c,mesout    ;PRINT STRING command
  97.     call    bdos        ;print error message
  98. ;
  99. finish: lhld    oldstack-offset ;get old stack
  100.     sphl            ;put it in HL
  101.     ret            ;return to CP/M
  102. ;
  103. notype: mvi    a,'C'        ;if there was space, change
  104.     sta    fcb+9        ;to COM
  105.     mvi    a,'O'
  106.     sta    fcb+10
  107.     mvi    a,'M'
  108.     sta    fcb+11
  109. ;
  110. iscom:    lxi    d,buffer-offset ;point to where program goes
  111.     mvi    c,setdma    ;SET DMA command
  112.     push    d        ;save it
  113.     call    bdos        ;and tell CP/M
  114.     mvi    a,0        ;zero record count
  115.     sta    fcb+32
  116.     mvi    c,open        ;OPEN file command
  117.     lxi    d,fcb        ;load address of FCB in DE
  118.     call    bdos        ;Open file
  119.     inr    a        ;successful?
  120.     jnz    openok        ;if so, then continue
  121.     call    endmes        ;if not, then tell
  122. ;
  123.     db    cr,lf,'Cannot open file',cr,lf,eos
  124. ;
  125. openok: pop    d        ;get starting dma back
  126. rloop:    mvi    c,setdma    ;and set it in loop
  127.     push    d        ;save it
  128.     call    bdos
  129.     lxi    d,fcb        ;point to FCB
  130.     mvi    c,read        ;READ sector command
  131.     call    bdos        ;do it
  132.     pop    d        ;get DMA address back
  133.     ana    a        ;EOF?
  134.     jnz    doneread    ;if so, then ask for password
  135.     lxi    h,80h        ;length of sector
  136.     dad    d        ;bump DMA
  137.     xchg            ;put new address in DE
  138.     jmp    rloop        ;and read some more
  139. ;
  140. doneread:
  141.     xchg            ;dma ==> hl
  142.     shld    endprog-offset    ;save last address
  143. gpasag    call    getpas        ;print password message
  144. ;
  145. pasmes    db    'Password? ',eos
  146. ;
  147. getpas    pop    d        ;get address of message
  148.     mvi    c,mesout    ;PRINT STRING function
  149.     call    bdos        ;print it
  150.     lxi    d,defbuf    ;point to default buffer
  151.     mvi    a,8        ;tell CP/M max chars
  152.     stax    d        ;put it there
  153.     mvi    c,incon     ;READ LINE command
  154.     call    bdos        ;do it
  155.     lxi    h,defbuf+1    ;point to length
  156.     lxi    d,password-offset    ;point to storage
  157.     mov    a,m        ;get length
  158.     ana    a        ;set flags
  159.     jz    gpasag        ;if 0 then ask again
  160.     inr    a        ;plus 1 for length byte
  161.     mov    b,a        ;put length in B
  162.     xra    b        ;cancel first xra in loop
  163.     mov    m,a        ;and put it back
  164. mploop    mov    a,m        ;get char
  165.     xra    b        ;encrypt it
  166.     stax    d        ;save it
  167.     inx    h        ;increment pointer
  168.     inx    d        ;  "          "
  169.     dcr    b        ;decrement length
  170.     jnz    mploop        ;if not zero, then next char
  171.     xra    a        ;zero a
  172.     sta    fcb+12        ;zero bytes in FCB
  173.     sta    fcb+14
  174.     sta    fcb+32
  175.     mvi    c,open        ;OPEN file command
  176.     lxi    d,fcb        ;point to FCB
  177.     call    bdos        ;open the file
  178.     lxi    d,nstart    ;point to new program start
  179. ;
  180.     push    d
  181. wloop1    pop    d        ;get DMA
  182.     push    d        ;put it back on stack
  183.     mvi    c,setdma    ;SET DMA command
  184.     call    bdos        ;tell CP/M
  185.     lxi    d,fcb        ;point to FCB
  186.     mvi    c,write     ;WRITE SECTOR command
  187.     call    bdos        ;do it
  188.     pop    h        ;get DMA address from stack
  189.     lxi    d,80h        ;length of sector
  190.     dad    d        ;HL has new DMA
  191.     push    h        ;put it on stack
  192.     mov    a,h        ;this is to get 2's complement
  193.     cma            ;of address. We are subtracting
  194.     mov    d,a        ;the current address from the
  195.     mov    a,l        ;high address. If the high byte
  196.     cma            ;<1 , we are done
  197.     mov    e,a        ;
  198.     inx    d        ;Now 2's comp. of address in DE
  199.     lhld    endprog-offset    ;get ending address
  200.     dad    d        ;Subtract (add 2's comp)
  201.     mov    a,h        ;get high byte
  202.     inr    a        ;is it FF (-1)?
  203.     ana    a        ;set flags
  204.     jnz    wloop1        ;if not, write another sector
  205. ;
  206.     mvi    c,close     ;That's it. Close the file
  207.     lxi    d,fcb        ;point to FCB
  208.     call    bdos        ;do it
  209.     jmp    finish        ;goto finish
  210. ;
  211. ;
  212. nstart:
  213. offset    equ    tpa-nstart
  214. ;
  215. ;    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  216. ;    %% WARNING -                        %%
  217. ;    %% From now on, all labels are in            %%
  218. ;    %% the form:                        %%
  219. ;    %%    LABEL    EQU  $+OFFSET                %%
  220. ;    %%  This is to allow the program to run at100H        %%
  221. ;    %% when it is saved by the earlier portion.        %%
  222. ;    %%  ALL new labels added MUST be in the form        %%
  223. ;    %% LABEL   EQU    $+OFFSET for this program to work   %%
  224. ;    %% properly.                        %%
  225. ;    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  226. ;
  227. ;This is portion of the program is placed at the beginning
  228. ;of the program to be PASSWORDed. When it is executed, it will
  229. ;ask for a password. If the password is incorrect, the program
  230. ;warm starts. If the password is correct, the program is moved
  231. ;to the TPA and executed.
  232. ;
  233.     lxi    h,0        ;save stack pointer
  234.     dad    sp        ;stack is in HL
  235.     shld    oldstack    ;save it
  236.     lxi    sp,stack    ;get new stack
  237.     call    otpw        ;print password message
  238. ;
  239.     db    cr,lf,'Password? '
  240.     db    eos
  241. ;
  242. otpw    equ    $+offset
  243.     pop    d        ;get address of message
  244.     mvi    c,mesout    ;PRINT STRING command
  245.     call    bdos        ;print it
  246.  
  247.     lxi    d,newbuf+1    ;point to storage area
  248.     xra    a
  249.     mov    b,a        ;init counter
  250.     stax    d        ;# of chars typed (for compare)
  251.     inx    d        ;and point to string
  252. ;
  253. ; we don't want to allow 'lookers' to see the password, so call
  254. ; bios instead of bdos to prevent echo.  also allows control chars.
  255. ;
  256.     lhld    boot+1        ;get addr of warm start routine
  257.     push    d
  258.     lxi    d,6        ;+ offset to kbd input routine
  259.     dad    d
  260.     pop    d
  261.     shld    bconin+1    ;now init'd to bios conin
  262.  
  263. otpw1    equ    $+offset
  264.     push    b        ;save counter..
  265.     push    d        ;..& pointer
  266. bconin    equ    $+offset
  267.     call    $-$        ;to be filled in by above routine
  268.     pop    d        ;restore pointer..
  269.     pop    b        ;..& counter
  270.     stax    d        ;store char
  271.     inx    d        ;bump pointer..
  272.     inr    b        ;..& counter
  273.     cpi    cr
  274.     jnz    otpw1        ;loop until cr typed
  275. ; B has the length of password furnished + 1 for count.
  276.     lxi    h,password    ;point to actual password
  277.     lxi    d,newbuf+1    ;point to user's input
  278.     xra    a        ;this 0 xra with length in B
  279.     stax    d        ;should equal count in passwd
  280. ;
  281. ; first char compared is a count of # of chars in password,
  282. ; followed by password itself.
  283. ;
  284. clp    equ    $+offset
  285.     ldax    d        ;get char
  286.     xra    b        ;encrypt it
  287.     cmp    m        ;are they the same?
  288.     jnz    boot        ;if not, restart
  289.     inx    h        ;point to next characters
  290.     inx    d        ;  "    "  "        "
  291.     dcr    b        ;decrement length
  292.     jnz    clp        ;if not done, then loop
  293. ;
  294. ; Now we move a segment of code to a part of the default
  295. ; buffer. This segment moves the actual program down to the
  296. ; TPA
  297. ;
  298.     lxi    h,nmv        ;point to code
  299.     lxi    d,defbuf+20h    ;point to new postion
  300.     mvi    b,nmlen ;length
  301. ;
  302. move    equ    $+offset
  303.     mov    a,m        ;get byte
  304.     stax    d        ;save it
  305.     inx    d        ;point to next addresses
  306.     inx    h        ;  "   "    "       "
  307.     dcr    b        ;decrement length
  308.     jnz    move        ;if not done, loop
  309.     jmp    defbuf+20h    ;go to segment
  310. ;
  311. nmv    equ    $+offset    ;segment that gets moved
  312.     lhld    oldstack    ;get stack pointer
  313.     push    h        ;save it on stack
  314.     lxi    h,buffer    ;get start of actual program
  315.     mov    a,h        ;We have to compute the length
  316.     cma            ;and because X-Y equals
  317.     mov    d,a        ;X + Two's complent(Y), we have
  318.     mov    a,l        ;to find the 2's comp. of the
  319.     cma            ;first address
  320.     mov    e,a        ;
  321.     inx    d        ;Y is in DE
  322.     lhld    endprog ;get last address
  323.     dad    d        ;subtract (add 2's comp)
  324.     mov    b,h        ;put length in BC
  325.     mov    c,l        ; "    "     "    "
  326.     lxi    d,tpa        ;point to TPA
  327.     lxi    h,buffer    ;point to first address
  328. nmlp    equ    defbuf+20h+$+offset-nmv
  329.     mov    a,m        ;get byte
  330.     stax    d        ;save byte
  331.     inx    h        ;increment address
  332.     inx    d        ;    "          "
  333.     dcx    b        ;decrement length
  334.     mov    a,b        ;check for zero left
  335.     ora    c        ;Are we done?
  336.     jnz    nmlp        ;if not, loop some more
  337.     pop    h        ;get stack from stack
  338.     sphl            ;put stack in SP
  339.     jmp    tpa        ;run program
  340. ;
  341. nmlen    equ    $+offset-nmv    ;length of segment
  342. ;
  343. ;
  344. password    equ    $+offset ;password storage
  345.     db    0,'        '
  346. ;
  347. ;12/10/81 changed to allow use of tbuf as input area
  348. ;
  349. newbuf    equ    $+offset    ;Users input buffer
  350.     db    10H,0,'            '
  351. ;
  352. oldstack    equ    $+offset ;place for stack
  353.     ds    2
  354. ;
  355. endprog equ    $+offset ;place for address
  356.     ds    2
  357. ;
  358. buffer    equ    $+offset    ;where actual program goes
  359.     end
  360.