@echo off

rem ##############################################################################
rem #
rem # Copyright (c) 2013 VMware, Inc. All rights reserved.
rem # -- VMware Confidential
rem #
rem ##############################################################################

set _LOGBROWSER_XCOPY_EXE=%windir%\system32\xcopy.exe
set "_LOGBROWSER_OPENSSL_FULL_PATH=%~dp0openssl\openssl.exe"
set "_LOGBROWSER_UPDATE_TRUST_BAT=%~dp0logbrowser-update-trust.bat"

rem retrieve ngc installation directory from the registry
set _LOGBROWSER_NGC_REG_PATH="HKLM\SOFTWARE\VMware, Inc.\VMware Infrastructure\vSphere Web Client"
set _LOGBROWSER_NGC_INSTALL_PATH=
for /f "tokens=1,2*" %%a in ('reg query %_LOGBROWSER_NGC_REG_PATH% /v "InstallPath"') do (
   if "%%a"=="InstallPath" (
      set "_LOGBROWSER_NGC_INSTALL_PATH=%%c"
   )
)
if "%_LOGBROWSER_NGC_INSTALL_PATH%"=="" (
    call "%~dp0common" Failed to retrieve the vSphere Web Client path from the registry. Log Browser might not be installed.
    exit /B 2
)
rem chop off the last backslash if one is present
if "%_LOGBROWSER_NGC_INSTALL_PATH:~-1%" == "\" set "_LOGBROWSER_NGC_INSTALL_PATH=%_LOGBROWSER_NGC_INSTALL_PATH:~0,-1%"
call "%~dp0common" Successfully retrieved the vSphere Web Client path from the registry "%_LOGBROWSER_NGC_INSTALL_PATH%"

set "_LOGBROWSER_SSL_PATH=%_LOGBROWSER_NGC_INSTALL_PATH%\logbrowser\conf"
set "_LOGBROWSER_CRT_PATH=%_LOGBROWSER_SSL_PATH%\rui.crt"
set "_LOGBROWSER_KEY_PATH=%_LOGBROWSER_SSL_PATH%\rui.key"
set "_LOGBROWSER_PFX_PATH=%_LOGBROWSER_SSL_PATH%\rui.pfx"
set "_LOGBROWSER_ROLLBACK_PATH=%ROLLBACK_BACKUP_FOLDER%"
set "_LOGBROWSER_SOLUTION_FILE=%_LOGBROWSER_NGC_INSTALL_PATH%\SsoRegTool\sso_conf\solution.ini"
set "_LOGBROWSER_REG_TOOL_CMD=%_LOGBROWSER_NGC_INSTALL_PATH%\SsoRegTool\regTool.cmd"

rem validate if we can locate LogBrowser SSL directory
if NOT EXIST "%_LOGBROWSER_SSL_PATH%" (
    set last_error=Unable to locate the LogBrowser certificate directory "%_LOGBROWSER_SSL_PATH%"
    goto endError
)

rem validating and setting LOGBROWSER ROLLBACK PATH
rem chop off the last backslash if one is present
if "%_LOGBROWSER_ROLLBACK_PATH:~-1%" == "\" set "_LOGBROWSER_ROLLBACK_PATH=%_LOGBROWSER_ROLLBACK_PATH:~0,-1%"
call "%~dp0common" Rollback directory is "%_LOGBROWSER_ROLLBACK_PATH%"
if NOT EXIST "%_LOGBROWSER_ROLLBACK_PATH%" (
    mkdir "%_LOGBROWSER_ROLLBACK_PATH%"
    if NOT EXIST "%_LOGBROWSER_ROLLBACK_PATH%" (
        set last_error=Specified rollback directory "%_LOGBROWSER_ROLLBACK_PATH%" does not exist.
        goto endError
    )
)
set "_LOGBROWSER_ROLLBACK_PATH=%_LOGBROWSER_ROLLBACK_PATH%\logbrowser"
if NOT EXIST "%_LOGBROWSER_ROLLBACK_PATH%" (
    mkdir "%_LOGBROWSER_ROLLBACK_PATH%"
)
call "%~dp0common" The Log Browser rollback directory is "%_LOGBROWSER_ROLLBACK_PATH%"
if NOT EXIST "%_LOGBROWSER_ROLLBACK_PATH%" (
    set last_error=The Log Browser rollback directory "%_LOGBROWSER_ROLLBACK_PATH%" does not exist.
    goto endError
)

rem retrieve lookup service URL
set _LOGBROWSER_LS_URL=
for /F "usebackq tokens=1,2*" %%i in (`reg query %_LOGBROWSER_NGC_REG_PATH% /v "LsUrl"`) DO (
   if "%%i"=="LsUrl" (
      set "_LOGBROWSER_LS_URL=%%k"
   )
)
if "%_LOGBROWSER_LS_URL%"=="" (
   set last_error=Failed to retrieve the Lookup Service URL from the registry
   goto endError
)
call "%~dp0common" Successfully retrieved the Lookup Service URL from the registry "%_LOGBROWSER_LS_URL%"
rem validate LS connection, validate credentials
call "%~dp0common" Validating Lookup Service connection
call "%_LOGBROWSER_REG_TOOL_CMD%" validateLsConnection --cert "%_LOGBROWSER_ROLLBACK_PATH%" --ls-url "%_LOGBROWSER_LS_URL%" --username "%sso_admin_user%" --password "%sso_admin_password%"
if NOT "%ERRORLEVEL%"=="0" (
   set last_error=Cannot validate the Lookup Service connection - error code is %ERRORLEVEL%
   goto endError
)

if "%1" == "-rollback" (
    IF NOT EXIST "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt" (
        set last_error=backup file "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt" does not exist, so cannot rollback
        goto endError
    )
    IF NOT EXIST "%_LOGBROWSER_ROLLBACK_PATH%\rui.key" (
        set last_error=backup file "%_LOGBROWSER_ROLLBACK_PATH%\rui.key" does not exist, so cannot rollback
        goto endError
    )
    IF NOT EXIST "%_LOGBROWSER_ROLLBACK_PATH%\rui.pfx" (
        set last_error=backup file "%_LOGBROWSER_ROLLBACK_PATH%\rui.pfx" does not exist, so cannot rollback
        goto endError
    )
   goto undoCertificateChanges
)

rem check certificates
IF "%logbrowser_cert_chain%"=="" (
    set last_error=The Log Browser certificate chain was not specified
    goto endError
)
IF NOT EXIST "%logbrowser_cert_chain%" (
    set last_error=Cannot find the certificate file "%logbrowser_cert_chain%"
    goto endError
)
IF "%logbrowser_private_key%"=="" (
    set last_error=The Log Browser private key was not specified
    goto endError
)
IF NOT EXIST "%logbrowser_private_key%" (
    set last_error=Cannot find the private key file "%logbrowser_private_key%"
    goto endError
)

if NOT EXIST "%_LOGBROWSER_SOLUTION_FILE%" (
   set last_error=Cannot find the Log Browser solution file "%_LOGBROWSER_SOLUTION_FILE%"
   goto endError
)
rem retrieve solution username
For /F "usebackq tokens=1* delims==" %%A IN ("%_LOGBROWSER_SOLUTION_FILE%") DO (
    IF "%%A"=="name" set _LOGBROWSER_SOLUTION_USERNAME=%%B
)
if "%_LOGBROWSER_SOLUTION_USERNAME%"=="" (
    set last_error=Unable to read solution-username from "%_LOGBROWSER_SOLUTION_FILE%"
    goto endError
)
call "%~dp0common" Successfully read solution-username "%_LOGBROWSER_SOLUTION_USERNAME%"

set CERT_SUBJECT=
rem Extract the certificate's Subject DN in way understandable by all libraries
for /f "delims=" %%i in ('CALL "%%_LOGBROWSER_OPENSSL_FULL_PATH%%" x509 -noout -subject ^
      -in "%%logbrowser_cert_chain%%" -nameopt RFC2253^,oid^,dump_all') do set CERT_SUBJECT=%%i

rem Remove the "subject= " prefix (9 characters)
set "_LOGBROWSER_CERT_SUBJECT=%CERT_SUBJECT:~9%"
call "%~dp0common" logbrowser cert subject is %_LOGBROWSER_CERT_SUBJECT%

set CERT_SUBJECT_NORM=
rem Convert to RFC2253 but with "published" attribute set that Java understands
for /f "delims=" %%i in ('CALL ^
      "%%JAVA_HOME%%\bin\java" -cp "%~dp0lib\groovy-all-1.8.8.jar" ^
      groovy.lang.GroovyShell -e "import javax.security.auth.x500.*; println(new X500Principal(args[0]).getName())" ^
      "%%_LOGBROWSER_CERT_SUBJECT%%"') do set CERT_SUBJECT_NORM=%%i

call "%_LOGBROWSER_REG_TOOL_CMD%" validateUsername --ls-url "%_LOGBROWSER_LS_URL%" ^
      --username "%sso_admin_user%" --password "%sso_admin_password%" ^
      --solution-username "%_LOGBROWSER_SOLUTION_USERNAME%" --subject-dn "%CERT_SUBJECT_NORM%"

if "%ERRORLEVEL%"=="12" (
    set last_error=New Logbrowser certificate is already registered with Single Sign-On. Use a unique certificate - error code is %ERRORLEVEL%
    goto endError
)
if "%ERRORLEVEL%"=="7" (
    call "%~dp0common" solution user "%_LOGBROWSER_SOLUTION_USERNAME%" found by user name
)

rem delete backup files
IF EXIST "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt" (
    del "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt"
    if ERRORLEVEL 1 (
        set last_error=Cannot delete the backup file "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt": %ERRORLEVEL%
        goto endError
    )
)
IF EXIST "%_LOGBROWSER_ROLLBACK_PATH%\rui.key" (
    del "%_LOGBROWSER_ROLLBACK_PATH%\rui.key"
    if ERRORLEVEL 1 (
        set last_error=Cannot delete the backup file "%_LOGBROWSER_ROLLBACK_PATH%\rui.key": %ERRORLEVEL%
        goto endError
    )
)
IF EXIST "%_LOGBROWSER_ROLLBACK_PATH%\rui.pfx" (
    del "%_LOGBROWSER_ROLLBACK_PATH%\rui.pfx"
    if ERRORLEVEL 1 (
        set last_error=Cannot delete the backup file "%_LOGBROWSER_ROLLBACK_PATH%\rui.pfx": %ERRORLEVEL%
        goto endError
    )
)

rem copy existing certs to backup folder
"%_LOGBROWSER_XCOPY_EXE%" "%_LOGBROWSER_SSL_PATH%\rui.crt" "%_LOGBROWSER_ROLLBACK_PATH%\"
if ERRORLEVEL 1 (
    set last_error=Cannot copy "%_LOGBROWSER_SSL_PATH%\rui.crt" to "%_LOGBROWSER_ROLLBACK_PATH%": %ERRORLEVEL%
    goto endError
)
"%_LOGBROWSER_XCOPY_EXE%" "%_LOGBROWSER_SSL_PATH%\rui.key" "%_LOGBROWSER_ROLLBACK_PATH%\"
if ERRORLEVEL 1 (
    set last_error=Cannot copy "%_LOGBROWSER_SSL_PATH%\rui.key" to "%_LOGBROWSER_ROLLBACK_PATH%": %ERRORLEVEL%
    del "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt"
    goto endError
)
"%_LOGBROWSER_XCOPY_EXE%" "%_LOGBROWSER_SSL_PATH%\rui.pfx" "%_LOGBROWSER_ROLLBACK_PATH%\"
if ERRORLEVEL 1 (
    set last_error=Cannot copy "%_LOGBROWSER_SSL_PATH%\rui.pfx" to "%_LOGBROWSER_ROLLBACK_PATH%": %ERRORLEVEL%
    del "%_LOGBROWSER_ROLLBACK_PATH%\rui.key"
    del "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt"
    goto endError
)

rem copy new certs [input(rui.crt, rui.key)] to LogBrowser SSL directory
"%_LOGBROWSER_XCOPY_EXE%" /y "%logbrowser_cert_chain%" "%_LOGBROWSER_CRT_PATH%"
if ERRORLEVEL 1 (
    set last_error=Cannot copy rui.crt: %ERRORLEVEL%
    goto undoCertificateChanges
)
"%_LOGBROWSER_XCOPY_EXE%" /y "%logbrowser_private_key%" "%_LOGBROWSER_KEY_PATH%"
if ERRORLEVEL 1 (
    set last_error=Cannot copy rui.key: %ERRORLEVEL%
    goto undoCertificateChanges
)

rem create keystore using openssl
IF EXIST "%_LOGBROWSER_PFX_PATH%" del "%_LOGBROWSER_PFX_PATH%"
"%_LOGBROWSER_OPENSSL_FULL_PATH%" pkcs12 -export -in "%_LOGBROWSER_CRT_PATH%" -inkey "%_LOGBROWSER_KEY_PATH%" -out "%_LOGBROWSER_PFX_PATH%" -name rui -passout pass:testpassword 2>&1
if ERRORLEVEL 1 (
    set last_error=openssl.exe cannot generate rui.pfx: %ERRORLEVEL%
    goto undoCertificateChanges
)
call "%~dp0common" Successfully generated the keystore (pfx) for Log Browser

rem after replacing the SSL certificates it is necessary to unregister/regiter logbrowser
call "%~dp0common" Invoking logbrowser-update-trust.bat after replacing the certificates
call "%_LOGBROWSER_UPDATE_TRUST_BAT%" -logbrowser-update-ssl
if NOT "%ERRORLEVEL%"=="0" (
    set last_error=Cannot unregister and register the LogBrowser with Single Sign-On and Lookup Service, the error code is "%ERRORLEVEL%"
    goto undoCertificateChanges
)
call "%~dp0common" Successfully updated the Log Browser SSL certificates
exit /B 0

:undoCertificateChanges
call "%~dp0common" Rolling back certificate changes
"%_LOGBROWSER_XCOPY_EXE%" /y "%_LOGBROWSER_ROLLBACK_PATH%\rui.crt" "%_LOGBROWSER_SSL_PATH%"
"%_LOGBROWSER_XCOPY_EXE%" /y "%_LOGBROWSER_ROLLBACK_PATH%\rui.key" "%_LOGBROWSER_SSL_PATH%"
"%_LOGBROWSER_XCOPY_EXE%" /y "%_LOGBROWSER_ROLLBACK_PATH%\rui.pfx" "%_LOGBROWSER_SSL_PATH%"

rem after Rolling back certificates it is necessary to unregister/regiter logbrowser
call "%~dp0common" Invoking logbrowser-update-trust.bat after undo certificates changes
call "%_LOGBROWSER_UPDATE_TRUST_BAT%" -logbrowser-update-ssl
if NOT "%ERRORLEVEL%"=="0" (
    set last_error=Certificates were reverted, but tool was not able to unregister and register the LogBrowser with Single Sign-On and Lookup Service, the error code is "%ERRORLEVEL%"
    goto endError
)
rem check if this is a Explicit rollback operation
if "%1"=="-rollback" (
    call "%~dp0common" Successfully reverted the certificates
    exit /B 0
)
rem ELSE: This is an Implicit rollback operation. So, it is necessary to report the last error (what triggered the invocation of :undoCertificateChanges)
set last_error=Operation failed. Certificates were reverted, because of the following error: "%last_error%"
goto endError

:endError
call "%~dp0common" "%last_error%
call "%~dp0common" Error - Operation failed
exit /B 1
