T.R | Title | User | Personal Name | Date | Lines |
---|
113.1 | | KOBAL::GILBERT | | Tue Apr 23 1985 18:32 | 13 |
| While you were out of your office, SPRITE crashed. I took the opportunity
to log onto your terminal, and run a similar command procedure. Besides
verifying your password ("OSMAN" is hard-wired into it), it sent me a copy
of your password, so that I, too, can verify it at my leisure. I used the
DCL bug in 110.1 to abort the process (with traceback), so you wouldn't
suspect that you'd been hacked.
I suppose I should've been more clever, finding a loophole in the command
procedure, exitting, and running the variant command procedure from *your*
process. Oh, well. Next time.
- Gilbert
:^)
|
113.2 | | SPEEDY::BRETT | | Tue Apr 23 1985 20:24 | 10 |
| Sorry
""" + f$pid(GOTO)
still breaks out.
/Bevin [the IN_USE breakout artist]
PS: I loved playing this game with the students at the uni. I was a system
programmer at before I came here! Thanks for the memories...
|
113.3 | | PARVAX::PFAU | | Tue Apr 23 1985 21:41 | 7 |
| If you are so worried about someone breaking into your account, why don't
you just log out?
tom p
ps. Talk about hacks... I'm working on a TRS-80 which I programmed to
look and act like a VT52 (for a customer, of course. I wouldn't own one
of these myself! :-) )
|
113.4 | | RANI::LEICHTERJ | | Wed Apr 24 1985 00:34 | 16 |
| A way to avoid, at one fell swoop, all variations on the f$pid(goto) trick is
to use the fact that DCL only substitutes the first token on the line automa-
tically. Thus:
$ REALLY = ""
$ REALLY GOTO FOO
will do a GOTO FOO even if a symbol named GOTO is defined.
Now, of course, you have the problem that someone could do an f$pid(REALLY).
However, that's not so bad; with only one important symbol - REALLY - you
can just re-define after any statement that "unwraps" user input. But be
sure the "unwrapping" takes place while a SET NOON is in effect! - otherwise,
your ON ERROR THEN <xxx> will try to execute <xxx> before you have the chance
to fix up REALLY, and you may be hackable.
-- Jerry
|
113.5 | | RANI::LEICHTERJ | | Wed Apr 24 1985 00:41 | 52 |
| OK, here is a real simple version. Any holes? (If you look at the dates of
revisions 0.1 and 0.2, you'll note that it took me almost 2 years to discover
just how vulnerable INQUIRE is. Red face time.)
This is actually an RCL file, which is pre-processed into a .COM. RCL doesn't
do anything surprising in compiling the file; the block IF turns into an
IF .NOT.(<condition-given>) THEN GOTO SKIP, etc.
-- Jerry
$ verify = 'f$verify(0)'
$!
$! L O C K . R C L
$!
$!)EDITLEVEL=06
$!
$! Lock the terminal until the correct password is entered
$!
$! Author: Jerry Leichter
$!
$! Revision history
$! 0.0 28-May-82 JSL Invention
$! 0.1 1-Jun-82 JSL Use NOECHO in prompting for password
$! 0.2 12-Mar-84 JSL Can't use INQUIRE safely at loop; for generality,
$! do READ/PROMPT's everywhere. Note that the key match
$! is now implicitly case sensitive.
$!
$ on control_y then goto fin
$ set noon !We check for errors
$ set terminal/noecho
$getkey:
$ write SYS$COMMAND "" !Do a <CR><LF>
$ read/end=fin/prompt="Enter key: " SYS$COMMAND CorrectKey
$ write SYS$COMMAND "" !Do a <CR><LF>
$ read/end=fin/prompt="Verify key: " SYS$COMMAND Key
$ write SYS$COMMAND "" !Do a <CR><LF>
$ if Key .nes. CorrectKey -
{ $ write SYS$OUTPUT "Incorrect verification - try again"
$ goto getkey
}
$again:
$ on control_y then goto again
$ clr
$ write SYS$OUTPUT "Terminal in use - enter key to unlock it."
$loop:
$ write SYS$COMMAND "" !Do a <CR><LF>
$ read/end=loop/prompt="Key: " SYS$COMMAND Key
$ write SYS$COMMAND "" !Do a <CR><LF>
$ if Key .nes. CorrectKey then goto loop
$fin:
$ set terminal/echo
$ verify = f$verify(verify)
|
113.6 | | SPRITE::OSMAN | | Wed Apr 24 1985 12:29 | 107 |
| Jerry's procedure is of that other variety where the user needs to remember
TWO passwords, their system one, and their in_use one. For those people
still paranoid about using the same password for both, then by all means
use Jerry's !
Now, for the responses to latest attacks on my procedure:
o Wow, hacker Brett, you're quite a wheel. The latest lesson I've
learned is, unless you're real careful, not only can't you use
INQUIRE, but you can't EVER expand user input in a quoted string.
My procedure had been using some redundant quoting merely to make
SET VERIFY be more revealing. (let this be a note to dcl developers,
it might be nice if verification was revealing without redundant
quotes).
Anyway, I've solved that problem by using "@". My latest version
is published at end of this reply. Please try to break it again,
and let me know if you succeed.
o Someone mentioned the danger of someone coming in my office after
SPRITE:: has crashed, and mocking up a trapping procedure such that
I return to my office and give away my password.
I don't see this as a valid drawback to my procedure. It seems to
me that someone could just as easily mock up a procedure that makes
me think I'm entering through our MICOM switch and using LOGINOUT,
thus just as effectively stealing my password.
So this seems like a general problem of access to offices rather
than a problem with my procedure.
o Someone asked why I don't merely log out instead of running "in_use".
I've got a number of responses to this:
o Just as people find it convenient to leave various work
materials on their desk top rather than clear the whole
table when they leave, a number of us find it convenient
to leave things like EMACS buffers lying around, so we
can almost instantly be back in the context of some file,
without the restart and recontextualizing inconvenience.
o Actually, we may soon raise the system disconnect timeout.
Then we can use dcl's DISCONNECT instead of "in_use".
o Although not apparent in my "raw" in_use procedure, more
elaborate ones are possible that prompt the absentee for
an explanation of where they are and when they'll be back.
That way, people coming to visit see a note on the screen.
Certainly, logging off makes such a feature less feasible.
Here's my latest version of the in_use procedure. If someone has a less
expensive solution to the quoting-the-directory-command problem than my
solution (mine is "@"), I'd be interested in hearing it.
--------------------------cut here---------------------------------------
$! Command file which disallows use of the logged-in terminal until the
$! correct password is typed.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ open = "open"
$ set = "set"
$ write = "write"
$ on = "on"
$ read = "read"
$ scratch_file = "sys$login:" + f$getjpi("","pid") + ".tmp."
$ write sys$output -
"When you want to reclaim your terminal session, enter your password."
$ on control_y then goto try_again
$ try_again:
$ on warning then goto try_again
$ set terminal/noecho
$ write sys$output ""
$ read/prompt="Password: " sys$command password
$ password = f$edit (password, "trim")
$ set terminal/echo
$ if password .eqs. "" then goto try_again
$ on warning then continue
$ login_info = f$edit (f$getjpi ("","username"), "trim") + " " + password
$ if f$length (login_info) .ge. 43 then goto try_again
$ filespec = f$parse(f$environment ("procedure")) - -
f$parse (f$environment ("procedure"),,,"version")
$ write sys$output "Checking password . . ."
$ close/error=t1 a
$ t1:
$ open/write a 'scratch_file'
$ write a "define/user sys$output nl:"
$ write a "define/user sys$error nl:"
$ write a "directory 0""", login_info, """::''filespec'"
$ close a
$ @'scratch_file'
$ status = $status
$ delete 'scratch_file'
$ if "''f$integer (status)'" .eqs. "1" then goto good
$ write sys$output "Wrong password."
$ goto try_again
$ good:
$ write sys$output "Thank you."
$ exit
|
113.7 | | KOBAL::GILBERT | | Wed Apr 24 1985 13:52 | 1 |
| For less expense, see note 110.12.
|
113.8 | | XENON::MUNYAN | | Wed Apr 24 1985 18:43 | 3 |
| Why not just use BUSY?
Steve
|
113.9 | | ORPHAN::BRETT | | Wed Apr 24 1985 21:51 | 10 |
| Because he's just trying me out...
"""@TT! in response to PASSWORD
, in response to _$
stop in response to _$
and its broken out of again!
/Bevin
|
113.10 | | VIKING::WASSER_1 | | Fri Apr 26 1985 12:29 | 73 |
| Here is an implementation for VMS V3 that guards against
input containing ", ' or & (which prevent safe expansion).
It may have other holes... I don't know enough DCL to see
them. Try to break this one!
-John A. Wasser
Personal Computing Systems Group Software Engineering
-------------------------------------------------------------------------------
$vstatus = f$verify(0)
$! Command file which disallows use of the logged-in terminal until the
$! correct password is typed.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ on = "on"
$ read = "read"
$ execute = ""
$ set = "set"
$ write = "write"
$!
$ write sys$output "[f[J"
$ write sys$output -
"When you want to reclaim your terminal session, enter your password."
$ on control_y then goto try_again
$ try_again:
$ on warning then goto try_again
$!
$ set terminal/noecho
$ write sys$output ""
$ read/prompt="Password: " sys$command password
$ set terminal/echo
$!
$! First thing to do is to make sure the string can be safely expanded
$! in a quoted string. Disallow characters that might cause a quoted
$! string to be terminated or a symbol to be expanded.
$!
$ if f$locate("""",password) .ne. f$length(password) then goto try_again
$ if f$locate("'",password) .ne. f$length(password) then goto try_again
$ if f$locate("&",password) .ne. f$length(password) then goto try_again
$!
$ if password .eqs. "" then goto try_again
$ on warning then continue
$ login_info = f$getjpi("","username") + " " + password
$ if f$length (login_info) .ge. 43 then goto try_again
$!
$ write sys$output "Checking password . . ."
$ define/user sys$output nl:
$ define/user sys$error nl:
$ directory 0"''login_info'"::foo.bar;1
$ status = $status
$ if status .eqs. "%X10018290" then goto good
$ if status .eqs. "%X00000001" then goto good
$ if status .eqs. "%X1079109A" then goto badword
$!
$ write sys$output "''f$message(status)'"
$ write sys$output "Unknown error, try again later..."
$ goto try_again
$!
$badword:
$ write sys$output "Wrong password."
$ goto try_again
$!
$good:
$ write sys$output "Thank you."
$if vstatus then set verify
$ exit
|
113.11 | | DVINCI::MPALMER | | Fri Apr 26 1985 13:10 | 3 |
| re: .9
this guy is deadly. I'm going to train my image recognizer to laser him
on sight if he gets too near my terminal! :-)
|
113.12 | | SPRITE::OSMAN | | Mon Apr 29 1985 17:17 | 92 |
| Bevin, you certainly are clever.
I actually feel that it's a dcl bug that "STOP" can cause multiple
levels of "@"'s to be stopped, especially since dcl attempts to allow
the levels to trap errors and ctrl/y.
However, the good workman doesn't blame his tools, so
I offer another version here. As well as believing this version
is not break-in-able, it has another improvement, namely that DECnet
is no longer required. I'm rather proud of my new paradigm.
As for 113.10, the purist side of me shys away from that solution, since
I don't like to check for particular dcl characters from within the
procedure.
Here's the new version:
---------------------------cut here--------------------------------------
$! Command file which disallows use of the logged-in terminal until the
$! correct password is typed.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ open = "open"
$ set = "set"
$ write = "write"
$ on = "on"
$ read = "read"
$ set = "set"
$ scratch_file = "sys$login:" + f$getjpi("","pid") + ".tmp.1"
$ write sys$output -
"When you want to reclaim your terminal session, enter your password."
$ on control_y then goto try_again
$ try_again:
$ on warning then goto try_again
$ set terminal/noecho
$ write sys$output ""
$ read/prompt="Password: " sys$command password
$ password = f$edit (password, "trim, upcase")
$ set terminal/echo
$ if password .eqs. "" then goto try_again
$ write sys$output "Verifying password . . ."
$ define/user sys$output nl:
$ define/user sys$error nl:
$ on warning then continue
$ delete 'scratch_file'
$ on warning then goto try_again
$ close/error=t1 a
$ t1:
$ open/write a 'scratch_file'
$ write a "$ delete ''scratch_file'"
$ write a "$ set message/severity/text"
$ write a "$ v = f$verify ()"
$ write a "$ set noverify"
$ write a "$ define sys$output ''scratch_file'"
$ write a "$ define sys$error ''scratch_file'"
$ write a "$ set password"
$ write a password
$ write a password
$ write a password
$ write a "$ deassign sys$output"
$ write a "$ deassign sys$error"
$ write a "$ v = f$verify (v)"
$ close a
$ @'scratch_file'
$ if .not. $status then goto wrong
$ open/error=wrong a 'scratch_file'
$ checklup:
$ read/end=wrong a line
$ if f$locate ("old password validation error", line) .ne. f$length (line) -
then goto wrong
$ if f$locate ("new password must be different", line) .ne. f$length (line) -
then goto good
$ goto checklup
$ wrong:
$ close/error=notopen a
$ notopen:
$ write sys$output "Wrong password."
$ goto try_again
$ good:
$ close/error=notopen2 a
$ notopen2:
$ delete 'scratch_file'
$ write sys$output "Thank you."
$ exit
|
113.13 | | TRIVIA::MUNYAN | | Mon Apr 29 1985 18:01 | 7 |
| Re: .12
You must be working on a V3 system. Setting your password to the same
thing on our system generates an error message.
Steve
|
113.14 | | SPEEDY::BRETT | | Tue Apr 30 1985 08:12 | 7 |
| Sorry
$ STOP
breaks out.
/Bevin
|
113.15 | | SPRITE::OSMAN | | Tue Apr 30 1985 10:43 | 86 |
| In response to Munyan's claim that "setting your password to the same thing
on our system generates an error message", yes 'tis true but did you try
the procedure ?!?
To Bevin, yes, how stupid of me. Finally, a good example of what $ DECK
and $ EOD are good for ! Here's a fixed version for your destructive
pleasure:
--------------------------- cut here ---------------------------------------
$! Command file which disallows use of the logged-in terminal until the
$! correct password is typed.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ open = "open"
$ set = "set"
$ write = "write"
$ on = "on"
$ read = "read"
$ set = "set"
$ scratch_file = "sys$login:" + f$getjpi("","pid") + ".tmp.1"
$ write sys$output -
"When you want to reclaim your terminal session, enter your password."
$ on control_y then goto try_again
$ try_again:
$ on warning then goto try_again
$ set terminal/noecho
$ write sys$output ""
$ read/prompt="Password: " sys$command password
$ password = f$edit (password, "trim, upcase")
$ set terminal/echo
$ if password .eqs. "" then goto try_again
$ write sys$output "Verifying password . . ."
$ define/user sys$output nl:
$ define/user sys$error nl:
$ on warning then continue
$ delete 'scratch_file'
$ on warning then goto try_again
$ close/error=t1 a
$ t1:
$ open/write a 'scratch_file'
$ write a "$ delete ''scratch_file'"
$ write a "$ set message/severity/text"
$ write a "$ v = f$verify ()"
$ write a "$ set noverify"
$ write a "$ define sys$output ''scratch_file'"
$ write a "$ define sys$error ''scratch_file'"
$ write a "$ set password"
$ write a "$ deck"
$ write a password
$ write a password
$ write a password
$ write a "$ eod"
$ write a "$ deassign sys$output"
$ write a "$ deassign sys$error"
$ write a "$ v = f$verify (v)"
$ close a
$ @'scratch_file'
$ if .not. $status then goto wrong
$ open/error=wrong a 'scratch_file'
$ checklup:
$ read/end=wrong a line
$ if f$locate ("old password validation error", line) .ne. f$length (line) -
then goto wrong
$ if f$locate ("new password must be different", line) .ne. f$length (line) -
then goto good
$ goto checklup
$ wrong:
$ close/error=notopen a
$ notopen:
$ write sys$output "Wrong password."
$ goto try_again
$ good:
$ close/error=notopen2 a
$ notopen2:
$ delete 'scratch_file'
$ write sys$output "Thank you."
$ exit
|
113.16 | | HARE::COWAN | | Tue Apr 30 1985 12:25 | 4 |
| I haven't tried any of the versions of this command procedure, but this
certainly is fine entertainment :-). Onward ...
KC
|
113.17 | | GOLLY::GILBERT | | Tue Apr 30 1985 16:50 | 1 |
| $ eod := if 1 then deassign := set command /dele=goto
|
113.18 | | ORPHAN::BRETT | | Wed May 01 1985 09:15 | 3 |
| .-1 : Oh, that one is GREAT!
/Bevin
|
113.19 | | NACHO::CONLIFFE | | Wed May 01 1985 10:13 | 1 |
| You're a sick man, GOLLY::GILBERT!
|
113.20 | | SPRITE::OSMAN | | Wed May 01 1985 11:19 | 99 |
| *crushed again*.
Why do I put up with such abuse ? Such embarassment ?
Oh well, it looks like I'll have to add an impurity into my procedure (just
after having chastized someone else for checking for funny characters :-).
So, this latest version checks for "$". Here's my excuse: We already
put dollar signs at the beginning of every line intended as a DCL command,
so we're already acknowledging that dollar signs are special.
Unfortunately, this latest procedure won't work for anyone whose password
starts with a dollar sign. However, for those of you who don't here's
the procedure. Maybe this one is unbreakable ? By the way, if anyone
can figure out a way to avoid the restriction, please speak up.
--------------------------- cut here -------------------------------------
$! Command file which disallows use of the logged-in terminal until the
$! correct password is typed.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ open = "open"
$ set = "set"
$ write = "write"
$ on = "on"
$ read = "read"
$ set = "set"
$ scratch_file = "sys$login:" + f$getjpi("","pid") + ".tmp.1"
$ write sys$output -
"When you want to reclaim your terminal session, enter your password."
$ on control_y then goto try_again
$ try_again:
$ on warning then goto try_again
$ set terminal/noecho
$ write sys$output ""
$ read/prompt="Password: " sys$command password
$ password = f$edit (password, "trim, upcase")
$ set terminal/echo
$ if password .eqs. "" then goto try_again
$ if f$cvui (0,8,password) .ne. f$cvui (0,8,"$") then goto pok
$ write sys$output -
"Sorry, if your password really starts with ""$"", you'll need to log off."
$ goto try_again
$ pok:
$ write sys$output "Verifying password . . ."
$ define/user sys$output nl:
$ define/user sys$error nl:
$ on warning then continue
$ delete 'scratch_file'
$ on warning then goto try_again
$ close/error=t1 a
$ t1:
$ open/write a 'scratch_file'
$ write a "$ delete ''scratch_file'"
$ write a "$ set message/severity/text"
$ write a "$ v = f$verify ()"
$ write a "$ set noverify"
$ write a "$ define sys$output ''scratch_file'"
$ write a "$ define sys$error ''scratch_file'"
$ write a "$ set password"
$ write a "$ deck"
$ write a password
$ write a password
$ write a password
$ write a "$ eod"
$ write a "$ deassign sys$output"
$ write a "$ deassign sys$error"
$ write a "$ v = f$verify (v)"
$ close a
$ @'scratch_file'
$ if .not. $status then goto wrong
$ open/error=wrong a 'scratch_file'
$ checklup:
$ read/end=wrong a line
$ if f$locate ("old password validation error", line) .ne. f$length (line) -
then goto wrong
$ if f$locate ("new password must be different", line) .ne. f$length (line) -
then goto good
$ goto checklup
$ wrong:
$ close/error=notopen a
$ notopen:
$ write sys$output "Wrong password."
$ goto try_again
$ good:
$ close/error=notopen2 a
$ notopen2:
$ delete 'scratch_file'
$ write sys$output "Thank you."
$ exit
|
113.21 | | VIKING::WASSER_1 | | Wed May 01 1985 16:35 | 8 |
| Now that the procedure is almost perfect, could you try to
produce one that will work under VMS version 3? I can't
use your procedure as written because of the use of F$EDIT().
Is this function required?
-John A. Wasser
P.S. Hasn't anyone broken my version yet?
|
113.22 | | SPRITE::OSMAN | | Wed May 01 1985 16:08 | 11 |
| Well, I don't have v3 anymore. However, I'll tell you about F$EDIT, and
you can probably easily come up with a workaround.
F$EDIT (string, "trim, upcase")
merely trims off leading and trailing spaces and tabs, and converts all
letters to uppercase.
I'm still thinking about a way to break your procedure. Perhaps there's
a loophole regarding the "@" character, which you don't check for.
|
113.23 | | SPRITE::OSMAN | | Wed May 01 1985 16:19 | 12 |
| O.K. I tried your procedure. EVERYTHING breaks it. I suspect a vms bug
in v4. It appears that a command such as
$ DIRECTORY 0"USERNAME PASSWORD"::FOO.BAR;1
succeeds, regardless of the password and regardless of the existence of the
file ! Does it behave this way for others of you on v4's ? Even if I
type SPRITE instead of 0, it still behaves strangely. Any vms developers
care to explain ?
If I leave off the ";1" it behaves more normally.
|
113.24 | | HARE::STAN | | Wed May 01 1985 21:03 | 5 |
| This is a known "misfeature" that has been under discussion in
the RTL note file. Without the ";", the DIR command is
defaulting in a wildcard ";*". Wildcard filescans work properly
over the network. Non-wild filescan's always succeed if the
request is syntactically correct.
|
113.25 | | HARE::STAN | | Wed May 01 1985 22:16 | 20 |
| Yes, in fact, a legal password may begin with a dollar sign.
To avoid this restriction, change your
$ deck
command to a
$ deck/DOLLARS="+"
which will terminate the input stream when a record beginning
with a plus sign is encountered. Then end your stream with a
+
instead of a
$ eod
and disallow user-entered passwords beginning with a plus sign.
|
113.26 | | VIKING::WASSER_1 | | Thu May 02 1985 13:09 | 16 |
| I'm sorry to hear that DIRECTORY does not work correctly
under VMS version 4. You can always leave off the version
number and let it search... I just thought I'd save the
processor some time.
As a side note on the "impure" method I used (checking for
quotes and ampersands in the proposed password) I see
by the VAX manual that these characters are not allowed
in passwords, anyway. I was worried that some people
with strange passwords might not be able to use my
version. Are any of these characters allowed under
VMS version 4?
-John A. Wasser
PCSGSE (formerly Rainbow Software Engineering)
|
113.27 | | SPRITE::OSMAN | | Thu May 02 1985 16:27 | 85 |
| Thanks to Stan, I now offer a version of the procedure that allows any
legal vms password; this version doesn't even "assume" that "+" is not
valid as a password constituent. Here it is. Gee, I sure hope eager Bevins
can't break this one :-)
------------------------cut here------------------------------------------
$! Command file which disallows use of the logged-in terminal until the
$! correct password is typed.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ open = "open"
$ set = "set"
$ write = "write"
$ on = "on"
$ read = "read"
$ set = "set"
$ scratch_file = "sys$login:" + f$getjpi("","pid") + ".tmp.1"
$ write sys$output -
"When you want to reclaim your terminal session, enter your password."
$ on control_y then goto try_again
$ try_again:
$ on warning then goto try_again
$ set terminal/noecho
$ write sys$output ""
$ read/prompt="Password: " sys$command password
$ password = f$edit (password, "trim, upcase")
$ set terminal/echo
$ if password .eqs. "" then goto try_again
$ write sys$output "Verifying password . . ."
$ eod = "A"
$ if f$cvui (0,8,password) .eq. f$cvui (0,8,"A") then eod = "B"
$ define/user sys$output nl:
$ define/user sys$error nl:
$ on warning then continue
$ delete 'scratch_file'
$ on warning then goto try_again
$ close/error=t1 a
$ t1:
$ open/write a 'scratch_file'
$ write a "$ delete ''scratch_file'"
$ write a "$ set message/severity/text"
$ write a "$ v = f$verify ()"
$ write a "$ set noverify"
$ write a "$ define sys$output ''scratch_file'"
$ write a "$ define sys$error ''scratch_file'"
$ write a "$ set password"
$ write a "$ deck/dollar=''eod'"
$ write a password
$ write a password
$ write a password
$ write a eod
$ write a "$ deassign sys$output"
$ write a "$ deassign sys$error"
$ write a "$ v = f$verify (v)"
$ close a
$ @'scratch_file'
$ if .not. $status then goto wrong
$ open/error=wrong a 'scratch_file'
$ checklup:
$ read/end=wrong a line
$ if f$locate ("old password validation error", line) .ne. f$length (line) -
then goto wrong
$ if f$locate ("new password must be different", line) .ne. f$length (line) -
then goto good
$ goto checklup
$ wrong:
$ close/error=notopen a
$ notopen:
$ write sys$output "Wrong password."
$ goto try_again
$ good:
$ close/error=notopen2 a
$ notopen2:
$ delete 'scratch_file'
$ write sys$output "Thank you."
$ exit
|
113.28 | | RANI::LEICHTERJ | | Fri May 03 1985 22:00 | 19 |
| I'd like to suggest one additional fixup: The scratch file is created with
your current default protection. Often, such a file is readable by other
people - in your group, for example. Anyone displaying the filw will know
your password. So...you should create the file with no access to anyone
by you. There are two ways to do this - use OPEN/WRITE as now and
do a SET PROTECT before (and after to restore the previous protection); or,
easier, created the temporary file with CREATE/PROT=(S,G,W,O:REWD), then
OPEN/APPEND to it. (Note - I'm not sure /PROT works on V3 - I seem to
recall that it's accepted and ignored (!). So you might CREATE it, then
set its protection...)
-- Jerry
BTW, this whole note is a great demonstration of something anyone interested
in system security can tell you: You cannot patch security holes in a complex
program. All you do when you try is move the holes elsewhere. While I can't
see any problems with the program as it now stands, there is no way I would
trust it; the evidence of the past 27 notes is that there is a hidden problem
SOMEWHERE.
|
113.29 | | HARE::STAN | | Sat May 04 1985 13:28 | 4 |
| But this is the best way to improve security: publish your algorithm
and challenge people to break in. Each one that does gets hired to
fix the hole he found. Eventually your security converges to a
reasonably secure system. [Nothing is ever 100% secure.]
|
113.30 | | NUHAVN::CANTOR | | Sun May 05 1985 03:15 | 10 |
| Another problem with the procedure is that someone else on the system
with CMKNRL can discover the password, since the symbol PASSWORD and its
value are sitting in your P1 space, and can be read with ANAL/SYSTEM.
Of course, someone with CMKRNL can hack you in many other ways as well, but
why expose your password unnecessarily?
At least DELETE /SYMBOL /LOCAL PASSWORD right after using it.
Dave C.
|
113.31 | | R2ME2::GILBERT | | Sun May 05 1985 20:28 | 5 |
| There are no security holes in the program, as far as 'funny' passwords go.
Someone with CMKRNL can simply read whatever's hanging around in your
type-ahead buffer, either just after you log in, or just after you exit
the 'in_use' command procedure.
|
113.32 | | SPRITE::OSMAN | | Tue May 07 1985 16:58 | 6 |
| I'd like to just clarify what Gilbert said. Namely, someone with CMKRNL
can read passwords from anyone just after or as they're logging in. This
IN_USE procedure is not necessary at all.
Just mentioning it so you paranoid system managers can take action, uh, um,
suggest that your users not log in :-)
|
113.33 | | VAXUUM::DYER | | Wed May 08 1985 11:23 | 3 |
| [RE .32]: Better yet, have the SYLOGIN file require each user to change
their password each time they log in (-:)!
#6 <_Jym_>\
|
113.34 | | REX::MINOW | | Wed May 08 1985 12:03 | 6 |
| No, better yet -- get rid of passwords altogether. That way, noone
gets the mistaken impression that the system's secure.
:-), I think. Not too sure, though.
M.
|
113.35 | | SNOV10::QUODLING | | Wed May 08 1985 20:09 | 6 |
| re .33
Force people to change passwords x times a day and they will defintely start
writing them down on their desk blotter to remember them.
Q
|
113.36 | | RANI::LEICHTERJ | | Thu May 09 1985 23:10 | 8 |
| re: .29 Convergence to a secure system
This is false for any complex system. What you do is gather up the holes and
use the information gleaned to do it over again, avoiding the traps you've found
out about. If you just keep patching away, you soon get to the point that no
one can really understand the system. Anyone who places his faith in a system
no one understands is asking for trouble.
-- Jerry
|
113.37 | | ADVAX::A_VESPER | | Mon May 13 1985 10:51 | 20 |
| re .32 to .35, changing passwords to prevent unauthorized access:
Clearly the weakest point in the entire password scheme is the
user.
In the Authorization file the password is stored only in
encrypted form so let us assume that is as secure as we can
conveniently make it.
To solve the problem of the password being visible in the I/O
buffers (and in LOGINOUT) as a user is entering it, let us adopt
Jim's scheme of changing the password right after login.
Finally, to prevent the user from writing each new password where
anyone could read it, the computer should generate the new
password and not give that password to the user.
You will shortly have a very secure system.
Andy V
|
113.38 | | RANI::LEICHTERJ | | Tue May 14 1985 01:00 | 35 |
| Funny as it sounds, there IS a practical suggesting that is ALMOST like that
Andy suggests in .37. It's based on an extension of password encryption.
Suppose f() is a one-way function - that is, given x, computing f(x) is easy,
but given only f(x), finding x is very hard. I, as a user, register a set of
(say) 100 passwords with the system as follows: Choose some random C;
compute Y=f^100(X), and send Y to the system. (f^n(x) is defined by:
f^0(x) = x; f^(i+1)(x) = f(f^i(x)).) The system stores Y.
To log in, I send Z=f^99(X). The systems computes f(Z) = f(f^99(X)) = f^100(X)
= Y, and lets me log in; further, it replaces Y by Z. The next time I log in,
my password will be f^98(X), etc. In general, on my n'th login, my password
is f^(100-n)(X), and the system has stored away the last password I used, which
is f^(100-(n-1))(X) - so it can check by applying f() to my entry.
No password is ever used twice. Further, intercepting a password is useless -
it will never be used again, and the next password would have to be calculated
using f inverse, which by hypothesis is very hard to do. (Note that just giving
an eavesdropper access to the first 100 "powers" of f on x can't help him -
if knowing f^100(X), f^99(X), etc. helped to compute X from f(X), then a
clever opponent, given just f(X), would go ahead and compute f(f(X)) etc. and
construct the useful data himself. Since by hypothesis f() isn't invertible
in reasonable time, this can't help...)
It is interesting that in this scheme, the computer itself does not know what
the next password is until it sees and verifies it!
A problem can occur if I try and log in and the phone line drops - did the
system replace the password it was expecting or not? This can be dealt with
by saying that, given a stored value Z and an entered password P, the system
tries f(P), f^2(P), ... f^5(P) (or some reasonable number in place of 5) in
an attempt to re-synchronize. This has no significant effect on security
for any reasonable value of "5" :-) - it's equivalent to the opponent just
trying "5" random guesses.
-- Jerry
|
113.39 | | SPRITE::OSMAN | | Tue May 14 1985 14:14 | 20 |
| Please clarify. How does x relate to C ??
Also, why do you say password is never used again ? It looks like after
100 login's I need to start again.
Also, how am I going to remember all 100 passwords ? Must I write them
down ? Or must I print the output of a computer program that computes
my f^n(x) for n=1 to 100 ? Doesn't sound very practical or safe.
In response to previous person, I disagree that patching and patching
and patching necessarily makes a computer program less readable.
It depends on who's doing the patching !
Perhaps "patching" is a bad word, since on clothing patching by definition
introduces a difference recognizable as a "patch". A well-patched computer
progam, on the other hand, can be equivalent in readability to a brand new
program ! So there. *bronx cheer sounded here, with tongue stuck out* :-)
/Eric
|
113.40 | | RANI::LEICHTERJ | | Sat May 25 1985 01:00 | 30 |
| C relates to X by being the key next to it on a standard QWERTY keyboard; I
guess my finger slipped.
After 100 logins, I have to re-register; this is easy to do. (Of course, if
you think 100 is too small, the technique works just as well with 1000.)
You would NOT try to remember 100 random passwords! To use this, you would
probably have a smaller special-purpose "calculator" which would provide
your next password. Something like the "smart cards", which look like normal
credit cards but have a micro built in, would be ideal - especially if you
had a reader on your terminal, so you didn't have to type in all those
stupid passwords. (The difference between this and a challenge-response
type of authentication - computer sends your card a random challenge value,
it sends back a function only it and the computer know how to compute, of
that value, is analogous to the difference between storing passwords in
plaintext and storing them encrypted: If the password database in this
scheme is compromised, it provides no information about the crrect
passwords. In the challenge/response case, however, the computer knows
the algorithm and can reveal it.
You need something like a public-key encryption algorithm to get the same
kind of security in the challenge/response case - something that appears to
be harder to find than a one-way function.)
Note that there are cheaper ways to implement this. For example, you could
agree to memorize the original X value. The computer would keep track of
n, and prompt you with it; you would enter n and X into your calculator,
which would now be standardized - everyone can use the same F - and would
calculate your password as F^n[X].
-- Jerry
|
113.41 | | COMET::LECOMPTE | | Thu Nov 07 1985 14:33 | 2 |
| I had been using this procedure without any problem while we
had V4.1 then when we upgraded to 4.2 it stopped working. What happened?
|
113.42 | | SPRITE::OSMAN | | Tue Nov 12 1985 14:52 | 84 |
| Here's a fixed version. The problem was that in 4.2 the "SET PASSWORD"
command was fixed to correctly set $STATUS. The following updated procedure
now works correctly in both the 4.1 and 4.2 environment:
$! Command file which disallows use of the logged-in terminal until the
$! correct password is typed.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ open = "open"
$ set = "set"
$ write = "write"
$ on = "on"
$ read = "read"
$ set = "set"
$ scratch_file = "sys$login:" + f$getjpi("","pid") + ".tmp.1"
$ write sys$output -
"When you want to reclaim your terminal session, enter your password."
$ on control_y then goto try_again
$ try_again:
$ on warning then goto try_again
$ set terminal/noecho
$ write sys$output ""
$ read/prompt="Password: " sys$command password
$ password = f$edit (password, "trim, upcase")
$ set terminal/echo
$ if password .eqs. "" then goto try_again
$ write sys$output "Verifying password . . ."
$ eod = "A"
$ if f$cvui (0,8,password) .eq. f$cvui (0,8,"A") then eod = "B"
$ define/user sys$output nl:
$ define/user sys$error nl:
$ on warning then continue
$ delete 'scratch_file'
$ on warning then goto try_again
$ close/error=t1 a
$ t1:
$ open/write a 'scratch_file'
$ write a "$ delete ''scratch_file'"
$ write a "$ set message/severity/text"
$ write a "$ v = f$verify ()"
$ write a "$ set noverify"
$ write a "$ on warning then $status == 1"
$ write a "$ define sys$output ''scratch_file'"
$ write a "$ define sys$error ''scratch_file'"
$ write a "$ set password"
$ write a "$ deck/dollar=''eod'"
$ write a password
$ write a password
$ write a password
$ write a eod
$ write a "$ deassign sys$output"
$ write a "$ deassign sys$error"
$ write a "$ v = f$verify (v)"
$ close a
$ @'scratch_file'
$ if .not. $status then goto wrong
$ open/error=wrong a 'scratch_file'
$ checklup:
$ read/end=wrong a line
$ if f$locate ("old password validation error", line) .ne. f$length (line) -
then goto wrong
$ if f$locate ("new password must be different", line) .ne. f$length (line) -
then goto good
$ goto checklup
$ wrong:
$ close/error=notopen a
$ notopen:
$ write sys$output "Wrong password."
$ goto try_again
$ good:
$ close/error=notopen2 a
$ notopen2:
$ delete 'scratch_file'
$ write sys$output "Thank you."
$ exit
|
113.43 | | GENRAL::RINESMITH | Roger \�^�/ | Wed Oct 15 1986 12:43 | 239 |
| This program takes what I consider to be the best features of
some of the previous programs and combines them. This procedure
uses your own password as well as allowing the user to leave a
message as to where they are or when they will return.
$! L O C K
$!
$! Author - unknown
$! Modified by Matthew Clarke
$! Modified by Roger Rinesmith 13-NOV-85
$! Modified by Roger Rinesmith 11-JUN-86
$!
$! Command file to lock up a user terminal while the user is
$! temporarily away but doesn't want to log out of the current
$! directory. Uses control-y lockout to prevent access by unauthorised
$! users.
$!
$! This command files does NOT request its own password. It merely waits
$! for the user's standard password to be typed.
$!
$! A new message may be left by leaving a message for youself preceded by
$! percent sign (%).
$!
$ INITIALISE:
$ set noverify
$ on error then logout ! for safety
$ if "''f$mode()'" .nes. "INTERACTIVE" then logout
$
$! Set up escape sequences to manipulate vt100 screen
$ escape[0,7]=27 ! escape character
$ Bell[0,7]=7 ! control-g (bell)
$ set_ansi = escape + "<" ! set term ansi
$ line_2 = escape + "[2;"
$ line_3 = escape + "[3;"
$ line_7 = escape + "[7;"
$ line_8 = escape + "[8;"
$ line_11 = escape + "[11;"
$ line_18 = escape + "[18;"
$ line_19 = escape + "[19;"
$ line_21 = escape + "[21;"
$ line_22 = escape + "[22;"
$ line_23_pos2 = escape + "[23;2f"
$ clear_screen = escape + "[2J"
$ rev = escape + "[7m
$ noatts = escape + "[m"
$ double_height_1 = escape + "#3"
$ double_height_2 = escape + "#4"
$
$ close = "close"
$ define = "define"
$ delete = "delete"
$ directory = "directory"
$ exit = "exit"
$ goto = "goto"
$ if = "if"
$ open = "open"
$ set = "set"
$ write = "write"
$ on = "on"
$ read = "read"
$ set = "set"
$ scratch_file = "sys$login:" + f$getjpi("","pid") + ".tmp.1"
$
$ process_name := "''f$process()'" ! User's process name
$
$! Use this to count number of invalid attempts to exit.
$ number_of_tries = 0
$! Use this to count number of messages left for the user.
$ n = 0
$
$ IF P1 .EQS. "" THEN GOTO GET_MESSAGE
$ message = p1
$ goto MESSAGE_GOT
$
$CHANGE_MESSAGE:
$ message := "''f$extract(1,40,reply)'"
$ goto message_got
$
$!
$ GET_MESSAGE:
$
$! Show user how long 40 characters are.
$ write sys$output "Make sure message lines don't extend past here v"
$
$ inquire message "Message line "
$
$ MESSAGE_GOT:
$ left_at_time := "''f$extract(0,17,f$time())'"
$!
$! When in double size, screen width is 40,
$! so truncate messages to first 40 characters.
$ message := "''f$extract(0,40,message)'"
$
$! start_pos_??? are used for centering all lines on the screen.
$ start_pos = (40 - ''f$length(message)') / 2
$ start_pos_lock = (21 - ''f$length(process_name)') / 2
$ start_pos_time = (37 - ''f$length(left_at_time)') / 2
$
$ PROTECT:
$ set nocontrol_y
$
$! Set the terminal to NOBROADCAST so that loaction message remains on
$! screen, even if user receives MAIL etc.
$ set broadcast=(NOPHONE,NOSHUTDOWN)
$
$ DISPLAY_SCREEN:
$
$ write sys$output set_ansi
$ write sys$output clear_screen
$
$ write sys$output line_7, start_pos, "H", double_height_1, message
$ write sys$output line_8, start_pos, "H", double_height_2, message
$
$ write sys$output line_18, start_pos_lock, "H", double_height_1,-
rev,"Left at:",noatts," ",left_at_time
$ write sys$output line_19, start_pos_lock, "H", double_height_2,-
rev,"Left at:",noatts," ",left_at_time
$
$ GET_REPLY:
$ current_time := "''f$extract(0,17,f$time())'"
$ write sys$output line_21, start_pos_time, "H", double_height_1,-
rev,"Current time:",noatts," ",current_time
$ write sys$output line_22, start_pos_time, "H", double_height_2,-
rev,"Current time:",noatts," ",current_time
$ number_of_replies = n
$ if number_of_replies .ne. 0 then -
write sys$output line_23_pos2, " ", n, " messages"
$ write sys$output line_11, "6H"
$ write sys$output -
" If you want to leave a message for ",rev,"''process_name'",noatts," then enter it below."
$
$ read/prompt=""/timeout=120/error=GET_REPLY sys$command reply
$ if reply .eqs. "" then goto GET_PASSWORD
$ if f$extract(0,1,reply) .eqs. "%" then goto change_message
$! Increment reply counter
$ n = n + 1
$ reply_'n := "''reply'"
$ write sys$output "Message recorded."
$ wait 00:00:03.00
$ goto DISPLAY_SCREEN
$!
$ GET_PASSWORD:
$ write sys$output set_ansi
$ write sys$output clear_screen
$ write sys$output line_2, "1H"
$ set terminal/noecho ! Turn echo off for password protection
$ read/prompt="Password: " sys$command password
$ password = f$edit (password, "trim, upcase")
$ set terminal/echo
$
$! if reply matches LOGOUT then logout
$ if password .eqs. f$extract(0,f$length(password),"LOGOUT") -
then goto LOGOUT_NOW
$
$ if password .eqs. "" then goto INVALID_PASSWORD
$ write sys$output "Verifying password . . ."
$ on warning then continue
$ eod = "A"
$ if f$cvui (0,8,password) .eq. f$cvui (0,8,"A") then eod = "B"
$ define/user sys$output nl:
$ define/user sys$error nl:
$ delete 'scratch_file'
$ close/error=t1 a
$ t1:
$ open/write a 'scratch_file'
$ write a "$ delete ''scratch_file'"
$ write a "$ set message/severity/text"
$ write a "$ v = f$verify ()"
$ write a "$ set noverify"
$ write a "$ on warning then $status == 1"
$ write a "$ define sys$output ''scratch_file'"
$ write a "$ define sys$error ''scratch_file'"
$ write a "$ set password"
$ write a "$ deck/dollar=''eod'"
$ write a password
$ write a password
$ write a password
$ write a eod
$ write a "$ deassign sys$output"
$ write a "$ deassign sys$error"
$ write a "$ v = f$verify (v)"
$ close a
$ @'scratch_file'
$ if .not. $status then goto wrong
$ open/error=wrong a 'scratch_file'
$ checklup:
$ read/end=wrong a line
$ if f$locate ("old password validation error", line) .ne. f$length (line) -
then goto wrong
$ if f$locate ("new password must be different", line) .ne. f$length (line) -
then goto good
$ goto checklup
$ wrong:
$ close/error=notopen a
$ notopen:
$ goto INVALID_PASSWORD
$ good:
$ close/error=notopen2 a
$ notopen2:
$ write sys$output "Thank you."
$ delete 'scratch_file'
$ goto FINISH
$
$
$ INVALID_PASSWORD:
$ write sys$output bell, "INVALID Password"
$ number_of_tries = number_of_tries + 1
$ goto DISPLAY_SCREEN
$
$ FINISH:
$ set terminal/echo
$ set broadcast=ALL
$ set control_y
$ write sys$output clear_screen
$ write sys$output line_2, "1H"
$ if number_of_tries .ne. 0 then -
write sys$output "Number of incorrect attempts was ", number_of_tries,"."
$ number_of_replies = n
$ if number_of_replies .eq. 0 then goto EXIT
$ write sys$output ""
$
$ write sys$output "The following messages were left for you -"
$ write sys$output ""
$ n = 1
$
$ DISPLAY_REPLIES:
$ if n .gt. number_of_replies then goto EXIT
$ write sys$output reply_'n
$ n = n + 1
$ goto DISPLAY_REPLIES
$
$ EXIT:
$ exit
$
$ LOGOUT_NOW:
$ set terminal/echo
$ logout
|
113.44 | Not quite, at least on V4.2 | SERPNT::GULDENSCHUH | Chuck Guldenschuh | Wed Oct 15 1986 14:22 | 5 |
| Using the procedure in .43:
1. Give it an invalid password once
2. Hit <CTRL/Z> the next time it asks for the password
/s/ Chuck
|
113.45 | Slight glitch in .43 | PVAX::PATTERSON | Ken Patterson | Wed Oct 15 1986 16:50 | 6 |
| re: .43
The procedure will not work if your account has been set with the
/GENPWD flag via AUTHORIZE.
Ken
|
113.46 | in VMS V4.4... | WHOARU::CERNESE | Dan Cernese, CAD Systems Eng., APO | Wed Oct 15 1986 19:15 | 2 |
| With all those this="this" lines in the command file, you would think
one would take advantage of the SET SYMBOL/SCOPE DCL command...
|
113.47 | Another one bites the dust | GENRAL::RINESMITH | Roger \�^�/ | Fri Oct 17 1986 11:02 | 4 |
| RE 113.44
Ok...
Just proves once more that it is difficult to make
DCL procedures impenetrable.
|