Why can a user set a new password without the need to enter old password correct with my batch code?

蹲街弑〆低调 提交于 2019-12-20 07:14:58

问题


I wrote recently a folder locking program.

My only problem is that when I need to change the password, e.g. I go to section newpass, the program doesn't seem to compare the old to the new password, but just uses any input given which defeats the purpose of having a password because everyone can just change it and than unlock the folder with it.

Can someone double check my code and tell me why it is doing it.

@echo off 
title Folder Locker by KBKOZLEV
:SETPASS
set/p password= <password.txt
set/p tipp= <tipp.txt
attrib +h +s "password.txt"
attrib +h +s "tipp.txt"
:START
if exist "Locked" goto OPEN
if exist "Unlocked" goto LOCK
if not exist "Unlocked" goto MDLOCKER
:LOCK
ren Unlocked "Locked"
attrib +h +s "Locked" 
echo.
echo Folder locked 
CHOICE /C X /T 1 /D X > nul
exit
:MDLOCKER
md Unlocked
echo( 1234 > password.txt
)
echo( 1234 > tipp.txt
)
attrib +h +s "password.txt" 
attrib +h +s "tipp.txt"
cls
echo.
echo Private folder created successfully 
CHOICE /C X /T 1 /D X > nul
goto End 
:OPEN
cls
echo.
echo Password Tip:%tipp%
echo.
echo Enter password to unlock folder or
echo Enter "new" to set a new password. 
set/p pass=">" 
if %pass%==new goto newpass
if %pass%==%password% ( 
attrib  -h -s "Locked" 
ren Locked "Unlocked"
echo Folder unlocked successfully 
goto End 
)
goto FAIL
:FAIL
cls
echo.
echo Invalid password,please try again. 
CHOICE /C X /T 1 /D X > nul 
cls
goto OPEN
:NEWPASS
cls
echo.
echo Enter old password.
set/p oldpass=">"
if %oldpass%==%password% {
attrib -h -s "password.txt"
attrib -h -s "tipp.txt"
cls 
echo.
echo Enter new password. 
set/p newpass= ">"
echo( %newpass% > password.txt
)
pause
cls
echo.
echo Enter new tipp
set/p passtipp=">"
echo( %passtipp% > tipp.txt
)
goto setpass
}
goto fail
:END

回答1:


Delayed environment variable expansion

At the end is your batch code rewritten to avoid the need of delayed environment variable expansion because of setting an environment variable within an IF block and evaluating it in same block as you did in

if %oldpass%==%password% (
    attrib -h -s "password.txt"
    attrib -h -s "tipp.txt"
    cls
    echo.
    echo Enter new password. 
    set/p newpass= ">"
    echo( %newpass% > password.txt
    )
    rem ...
)

Command line interpreter cmd.exe replaces all %env% within ( ... ) block by their values before evaluating the IF condition resulting for example in newpass always being nothing (most likely). Read in a command prompt window the entire help on command set output after entering either help set or set /? for details about delayed expansion.

Typing mistake

There is { instead of ( in the above code block in your question.

Block indentations

You should indent lines within a ( ... ) block as otherwise it is hard for anybody to see the block structure which makes code checking very difficult.

Unchanged environment variable on RETURN

If a user has to enter a string assigned to an environment variable, the user can always hit just key RETURN or ENTER without entering anything. In this case the value of the environment variable is not changed at all if the environment variable already existed. Therefore it is advisable to make sure that the environment variable does not exist before using set /p if the user must enter something.

The other possibility is that a default value is assigned to the environment variable so that a user needs to press only RETURN or ENTER if the default value should be used. But in this batch code the user should always enter all strings.

Trailing spaces assigned to environment variable

It is possible to assign a string with spaces to an environment variable and the spaces can be also at end of the strings. Trailing spaces in a batch file is a common reason for a batch file not working as expected. The solution is using set "var=value" as in this case the trailing spaces after the second double quote are ignored on command execution.

String compares always with surrounding double quotes

Comparison of an environment variable with a string value should be done always on using double quotes around environment variable reference and the string value. Otherwise it can happen easily with user entering nothing that the IF condition is parsed as

if ==new goto newpass

which is invalid and cmd.exe breaks execution of the batch file. This can't happen anymore with

if /i "%pass%"=="new" goto NEWPASS

/i makes the compare case-insensitive.

Double quotes entered by user breaks batch script

But the user can nevertheless break execution of batch file by entering now a double quote character. The solution is to remove all double quotes from entered string before making the string comparison as for example done with

set newpass=%newpass:"=%

But this results in one more problem if newpass is removed before user is prompted to enter new password and the user enters nothing. This would result again in an invalid command line syntax for cmd.exe. The solution is to predefine newpass and passtipp with just " as value. Now the user can hit key RETURN, but the variables would nevertheless exist with " as value. This double quote is removed next and batch code detects on next line that the user has not entered anything as otherwise the single double quote would have been replaced by something different.

Final batch code

@echo off
title Folder Locker by KBKOZLEV
:SETPASS
set "tipp="
set "password="
if exist "password.txt" (
    set /p password=<password.txt
    attrib +h +s "password.txt"
)
if exist "tipp.txt" (
    set /p tipp=<tipp.txt
    attrib +h +s "tipp.txt"
)
:START
if exist "Locked" goto OPEN
if exist "Unlocked" goto LOCK
if not exist "Unlocked" goto MDLOCKER
:LOCK
ren "Unlocked" "Locked"
attrib +h +s "Locked"
echo.
echo Folder locked.
CHOICE /C X /T 5 /D X > nul
exit
:MDLOCKER
md "Unlocked"
echo>password.txt 1234
echo>tipp.txt 1234
attrib +h +s "password.txt"
attrib +h +s "tipp.txt"
cls
echo.
echo Private folder created successfully.
CHOICE /C X /T 5 /D X > nul
goto END
:OPEN
cls
echo.
echo Password tipp: %tipp%
echo.
echo Enter password to unlock folder or
echo enter "new" to set a new password.
echo.
set "pass="
set /p "pass=Password: "
if /i "%pass%"=="new" goto NEWPASS
if "%pass%"=="%password%" (
    attrib -h -s "Locked"
    ren "Locked" "Unlocked"
    echo.
    echo Folder unlocked successfully.
    goto END
)
goto FAIL
:FAIL
cls
echo.
echo Invalid password, please try again.
CHOICE /C X /T 5 /D X > nul
cls
goto OPEN
:NEWPASS
cls
echo.
set "oldpass="
set /p "oldpass=Old password: "
if not "%oldpass%"=="%password%" goto FAIL
:ENTERNEW
cls
echo.
set "newpass=""
set /p "newpass=New password: "
set newpass=%newpass:"=%
if "%newpass%"=="" (
    echo.
    echo Invalid new password, please enter new password again.
    CHOICE /C X /T 5 /D X > nul
    goto ENTERNEW
)
if exist "password.txt" attrib -h -s "password.txt"
echo>password.txt %newpass%
echo.
set "passtipp=""
set /p "passtipp=New tipp: "
set passtipp=%passtipp:"=%
if exist "tipp.txt" attrib -h -s "tipp.txt"
if not "%passtipp%"=="" (
    echo>tipp.txt %passtipp%
) else (
    del "tipp.txt"
)
goto SETPASS
:END

Everything written here was already written thousands of times in Stack Overflow answers on questions with tag batch-file. It would have been good reading 20 to 30 answers here before starting batch code development.


Edit on 2015-05-08:

Here is an even better version than above in case of a user of this batch file enters < or > in password or as tip. It uses delayed expansion where necessary to avoid that those 2 characters are interpreted as redirection statements.

@echo off
setlocal EnableDelayedExpansion
title Folder Locker by KBKOZLEV
:SETPASS
set "tipp="
set "password="
if exist "password.txt" (
    set /p password=<password.txt
    attrib +h +s "password.txt"
)
if exist "tipp.txt" (
    set /p tipp=<tipp.txt
    attrib +h +s "tipp.txt"
)
:START
if exist "Locked" goto OPEN
if exist "Unlocked" goto LOCK
if not exist "Unlocked" goto MDLOCKER
:LOCK
ren "Unlocked" "Locked"
attrib +h +s "Locked"
echo.
echo Folder locked.
CHOICE /C X /T 5 /D X > nul
exit
:MDLOCKER
md "Unlocked"
echo>password.txt 1234
echo>tipp.txt 1234
attrib +h +s "password.txt"
attrib +h +s "tipp.txt"
cls
echo.
echo Private folder created successfully.
CHOICE /C X /T 5 /D X > nul
goto END
:OPEN
cls
echo.
echo Password tipp: %tipp%
echo.
echo Enter password to unlock folder or
echo enter "new" to set a new password.
echo.
set "pass=""
set /p "pass=Password: "
set "pass=!pass:"=!"
if /i "%pass%"=="new" goto NEWPASS
if "%pass%"=="%password%" (
    attrib -h -s "Locked"
    ren "Locked" "Unlocked"
    echo.
    echo Folder unlocked successfully.
    goto END
)
goto FAIL
:FAIL
cls
echo.
echo Invalid password, please try again.
CHOICE /C X /T 5 /D X > nul
cls
goto OPEN
:NEWPASS
cls
echo.
set "oldpass=""
set /p "oldpass=Old password: "
set "oldpass=!oldpass:"=!"
if not "%oldpass%"=="%password%" goto FAIL
:ENTERNEW
cls
echo.
set "newpass=""
set /p "newpass=New password: "
set "newpass=!newpass:"=!"
if "%newpass%"=="" (
    echo.
    echo Invalid new password, please enter new password again.
    CHOICE /C X /T 5 /D X > nul
    goto ENTERNEW
)
if exist "password.txt" attrib -h -s "password.txt"
echo>password.txt !newpass!
echo.
set "passtipp=""
set /p "passtipp=New tipp: "
set "passtipp=!passtipp:"=!"
if exist "tipp.txt" attrib -h -s "tipp.txt"
if not "%passtipp%"=="" (
    echo>tipp.txt !passtipp!
) else (
    del "tipp.txt"
)
goto SETPASS
:END
endlocal


来源:https://stackoverflow.com/questions/25824539/why-can-a-user-set-a-new-password-without-the-need-to-enter-old-password-correct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!