diff --git a/misc/bitwarden-cli-otp/README.md b/misc/bitwarden-cli-otp/README.md new file mode 100644 index 00000000..21bd58cd --- /dev/null +++ b/misc/bitwarden-cli-otp/README.md @@ -0,0 +1,16 @@ +# Bitwarden CLI OTP Scripts + + +These scripts (based on [kensykora's automatic OTP entry](https://gist.github.com/kensykora/b220573b4230d7622c5a23a497c75fd3)) allow you to keep your OTP secret secure inside a Bitwarden vault, storing your master vault key in an encrypted blob. + +## Requirements +1. [Bitwarden CLI](https://bitwarden.com/help/cli/#download-and-install) +2. [PS2EXE](https://github.com/MScholtes/PS2EXE) (Optional) + +## Getting Started +1. After installing the requirements above, you'll want to choose whether you want to see the main screen of the launcher ([manual-login.ps1](/misc/bitwarden-cli-otp/manual-login.ps1)) or just log into the game ([automatic-login.ps1](/misc/bitwarden-cli-otp/automatic-login.ps1)). The automatic log in script has fewer side effects as it's not waiting for the port to open, but you miss out on the news posts. +2. Login to Bitwarden CLI (`bw login`). If self-hosting Bitwarden, set the URL with `bw config server https://your.bw.domain.com`. +3. (Optional) If using the automatic log in script, generate an encrypted blob of your Bitwarden master password by running a PowerShell command: `Read-Host -AsSecureString | ConvertFrom-Securestring | Out-File "$env:HOMEPATH\Documents\bitwarden.key"`. If you don't use this blob, it will prompt you for your master password. +4. Make sure line 4 of either script matches your vault item's name. It is "Square Enix" by default. +5. Check "Enable XL Authenticator app/OTP macro support" in Settings and if you're using the automatic login script, check "Log in automatically" on the main launcher screen. +6. (Optional) Win-PS2EXE allows you to convert the script into an executable. This has the added benefit of being able to be pinned to the taskbar with Windows 11, but it also provides more context in the Windows Hello prompt by using the exe name you choose instead of the generic "powershell" requesting access. **Note: Windows Defender and other anti-virus software will likely take issue with these built exes so ensure they are approved for use.** diff --git a/misc/bitwarden-cli-otp/automatic-login.ps1 b/misc/bitwarden-cli-otp/automatic-login.ps1 new file mode 100644 index 00000000..216ab98e --- /dev/null +++ b/misc/bitwarden-cli-otp/automatic-login.ps1 @@ -0,0 +1,31 @@ +# You shouldn't need to modify this unless you have a custom launcher install +$LauncherPath = "$env:LOCALAPPDATA\XIVLauncher\XIVLauncher.exe" +# The name of the login item containing your FFXIV OTP +$VaultItemName = "Square Enix" + +# Generate encrypted key file with: +# Read-Host -AsSecureString | ConvertFrom-Securestring | Out-File "$env:HOMEPATH\Documents\bitwarden.key" +$EncryptedKeyPath = "$env:HOMEPATH\Documents\bitwarden.key" + +# Check if encrypted master key blob exists. If so, login with session for seamless login. Otherwise default to prompting. +if ([System.IO.File]::Exists($EncryptedKeyPath)) { + $env:BW_PASSWORD = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((Get-Content $EncryptedKeyPath | ConvertTo-SecureString))) + # Get BW session from encrypted master password + $env:BW_SESSION=bw unlock --passwordenv BW_PASSWORD --raw 2>$null +} + +$OTP = bw get totp $VaultItemName + +if ($OTP.length -eq 6) { + # Check "Enable XL Authenticator app/OTP macro support" in Settings + # Check "Log in automatically" on the main launcher screen + Start-Process powershell -ArgumentList $LauncherPath + [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } + Start-Sleep -Seconds 4 + try { + Invoke-WebRequest -URI "http://127.0.0.1:4646/ffxivlauncher/$OTP" + } catch { } +} else { + Write-Error "Failed to authenticate or malformed OTP" + Read-Host -Prompt "Press Enter to exit" +} \ No newline at end of file diff --git a/misc/bitwarden-cli-otp/manual-login.ps1 b/misc/bitwarden-cli-otp/manual-login.ps1 new file mode 100644 index 00000000..32c71f2d --- /dev/null +++ b/misc/bitwarden-cli-otp/manual-login.ps1 @@ -0,0 +1,32 @@ +# You shouldn't need to modify this unless you have a custom launcher install +$LauncherPath = "$env:LOCALAPPDATA\XIVLauncher\XIVLauncher.exe" +# The name of the login item containing your FFXIV OTP +$VaultItemName = "Square Enix" + +# Check "Enable XL Authenticator app/OTP macro support" in Settings +$Launcher = Start-Process -FilePath $LauncherPath -PassThru +Start-Sleep -Seconds 1 +$Launcher = (Get-WmiObject win32_process | where {$_.ParentProcessId -eq $Launcher.Id }).ProcessId +[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } + +$ServerUp = netstat -na | Select-String ":4646" +while (($ServerUp.length -eq 0) -and ((Get-Process -Id $Launcher).ProcessName -eq "XIVLauncher" 2>$null)) { + Start-Sleep -Seconds 1 + $ServerUp = netstat -na | Select-String ":4646" +} + +if ((Get-Process -Id $Launcher).ProcessName -eq "XIVLauncher" 2>$null) { + # Suppress any errors here to minimize error dialog spam in exe builds + $OTP = bw get totp $VaultItemName + # Allows for some padding of time in case OTP service loads slowly + Start-Sleep -Seconds 1 + if ($OTP.length -eq 6) { + try { + Invoke-WebRequest -URI "http://127.0.0.1:4646/ffxivlauncher/$OTP" + } catch { } + } else { + # Can't get dialog to show up on top of launcher when built as an exe so kill it first + Stop-Process -name XIVLauncher + Write-Error "Failed to authenticate or the OTP was malformed. The launcher has closed." -Category AuthenticationError + } +} \ No newline at end of file