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

前端 未结 1 916
后悔当初
后悔当初 2021-01-26 03:16

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 se

相关标签:
1条回答
  • 2021-01-26 03:29

    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
    
    0 讨论(0)
提交回复
热议问题