SHARE
TWEET

openvpn inline export (also for viscosity)

al_sedano Jul 19th, 2019 (edited) 114 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ####
  2. ### Exporting openvpn client to inline unique file
  3. ####
  4. # This ps1 script exports multifile openvpn client configs
  5. # to one inline .ovpn file
  6. #
  7. # The Viscosity (also Tunnelblick) format is valid for MacOS
  8. # This file format uses the UTF8bom encoding.
  9. #
  10. # openVPN Client must be installed in this computer.
  11.  
  12. # Tested on PowerShell 5.1
  13. # Created by Alvaro Sedano Galindo. al_sedano@hotmail.com
  14. #
  15. # https://github.com/alvarsedano/openvpn-configuration-inline-export-also-for-viscosity-
  16. #
  17.  
  18. $ErrorActionPreference = 'SilentlyContinue'
  19.  
  20. #
  21. # Functions
  22. #
  23.  
  24. Function Get-BeginEnd {
  25.     Param([Parameter(Mandatory=$true, Position=0)]
  26.           [string]$path)
  27.  
  28.     [string[]]$text = Get-Content $path -Encoding UTF8
  29.     [int]$beg = ($text | Select-String -Pattern "-BEGIN " -Encoding utf8 | Select -ExpandProperty LineNumber) - 1
  30.     [int]$end =  $text | Select-String -Pattern "-END "   -Encoding utf8 | Select -ExpandProperty LineNumber
  31.     $text[$beg..$end]
  32. }
  33.  
  34. Function BufferAdd {
  35.     Param([Parameter(Mandatory=$true, Position=0)]
  36.           [ref]$dir,
  37.           [Parameter(Mandatory=$true, Position=1)]
  38.           [ref]$buffer,
  39.           [Parameter(Mandatory=$true, Position=2)]
  40.           [string]$pa)
  41.  
  42.     $buffer.Value += "<$pa>"
  43.     $buffer.Value += Get-BeginEnd -path ($dir.value)
  44.     $buffer.Value += "</$pa>"
  45. }
  46.  
  47. Function IfExists {
  48.     Param([Parameter(Mandatory=$true, Position=0)]
  49.           [ref]$ovpn,
  50.           [Parameter(Mandatory=$true, Position=1)]
  51.           [ref]$dir,
  52.           [Parameter(Mandatory=$true, Position=2)]
  53.           [ref]$buffer,
  54.           [Parameter(Mandatory=$true, Position=3)]
  55.           [string]$pa)
  56.  
  57.     $pattern = "^$pa (?<a>.*) *$"
  58.     [string]$a = ($ovpn.Value) -match $pattern
  59.     if ($a -ne $null -and $a -match $pattern) {
  60.         # Pattern found
  61.         [string]$arch = "$($dir.Value)\$($Matches.a)"
  62.  
  63.         if(Test-Path $arch) {
  64.             BufferAdd -dir ([ref]$arch) -buffer $buffer -pa $pa
  65.         }
  66.         else {
  67.             Write-Host "ERROR: The $pa file '$arch' was not found. Process stopped." -BackgroundColor DarkRed
  68.             Exit(2)
  69.         }
  70.     }
  71. }
  72.  
  73. #
  74. # BODY
  75. #
  76.  
  77. # Get from registry the OpenVPN Client path
  78. [string]$rutaREG = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN"
  79. if (-not (Test-Path($rutaREG))) {
  80.     Write-Output "No openvpn installation found. You must install openvpn client to use this script." -BackgroundColor DarkRed
  81.     Exit (1)
  82. }
  83.  
  84. # openVPN Client installation found
  85. [string[]]$rutaConfig = (Get-ItemProperty -Path $rutaREG).config_dir
  86. $rutaConfig += @("$env:USERPROFILE\OpenVPN\config" `
  87.                 , "$([Environment]::GetFolderPath("MyDocuments"))" )
  88.  
  89. [string]$openSSL = ((Get-ItemProperty -Path $rutaREG).exe_path).Replace("openvpn.exe", "openssl.exe")
  90.  
  91. # List every ovpn tunnel
  92. [string[]]$tunnels = (Get-ChildItem -Filter "*.ovpn" -Path $rutaConfig -Depth 1 -Recurse).Fullname
  93.  
  94. if ($tunnels -eq $null -or $tunnels.Count -eq 0) {
  95.     Write-Host "No ovpn config tunnels found in" -BackgroundColor DarkRed
  96.     foreach ($p in $rutaConfig) {
  97.         Write-Host "`t'$p'"
  98.     }
  99.     Write-Host "and its level 1 subfolders." -BackgroundColor DarkRed
  100.     exit(3)
  101. }
  102.  
  103. for($i=0; $i -lt $tunnels.Count; $i++) {
  104.     Write-Host $([string]::Format("[{0}] - {1}", $i+1, $tunnels[$i]) )
  105. }
  106.  
  107. [int]$max = $tunnels.Count
  108. do {
  109.     [string]$resp = Read-Host "`nWhich ovpn tunnel do you want to export? [1-$max] (Ctrl+C to exit)"
  110. } While ([int]$resp -lt 1 -or [int]$resp -gt $max)
  111. [string]$tun = $tunnels[$resp-1]
  112. [string[]]$content = Get-Content -Path $tun
  113. [string]$retls = "^tls-auth (?<a>.*) (?<b>[0-1])"
  114. [string]$reca = "^ca (?<a>.*) *$"
  115. [string]$recert = "^cert (?<a>.*) *$"
  116. [string]$rekey = "^key (?<a>.*) *$"
  117. [string]$repkcs = "^pkcs12 (?<a>.*)"
  118.  
  119. [string[]]$exported = @()
  120. $exported += $content | Select-String -NotMatch -Pattern $retls  | `
  121.                             Select-String -NotMatch -Pattern $reca   | `
  122.                             Select-String -NotMatch -Pattern $recert | `
  123.                             Select-String -NotMatch -Pattern $rekey  | `
  124.                             Select-String -NotMatch -Pattern $repkcs | `
  125.                             Select-String -NotMatch -Pattern '^#'    | `
  126.                             Select-String -NotMatch -Pattern '^;'
  127. #$exported += ""
  128.  
  129. [System.IO.FileSystemInfo]$ar = Get-ChildItem -Path ($tunnels[$resp-1])
  130. [string]$dir = $ar.Directory.FullName
  131.  
  132. #PKCS12 section found
  133. [string]$a = $content -match $repkcs
  134. if ($a -ne $null -and $a -match $repkcs) {
  135.     # pkcs12 section found
  136.     [string]$arch = "$dir\$($Matches.a)"
  137.  
  138.     #Extract from .p12 the ca,crt,key files
  139.     $f1CA  = New-TemporaryFile
  140.     $f2cer = New-TemporaryFile
  141.     $f3key = New-TemporaryFile
  142.     try {
  143.         & "$openSSL" pkcs12 -in "$arch" -nomac -nokeys -cacerts -out "$($f1CA.FullName)"  -passin pass:
  144.         & "$openSSL" pkcs12 -in "$arch" -nomac -nokeys -clcerts -out "$($f2cer.FullName)" -passin pass:
  145.         & "$openSSL" pkcs12 -in "$arch" -nomac -nodes  -nocerts -out "$($f3key.FullName)" -passin pass:
  146.    
  147.         BufferAdd -dir ([ref]($f1CA.FullName))  -buffer ([ref]$exported) -pa 'ca'
  148.         BufferAdd -dir ([ref]($f2cer.FullName)) -buffer ([ref]$exported) -pa 'cert'
  149.         BufferAdd -dir ([ref]($f3key.FullName)) -buffer ([ref]$exported) -pa 'key'
  150.     }
  151.     catch {}
  152.     finally {
  153.         Remove-Item $f1CA.FullName  -Force
  154.         Remove-Item $f2cer.FullName -Force
  155.         Remove-Item $f3key.FullName -Force
  156.     }
  157. }
  158. else {
  159.     # No PKCS12 section, search for ca, cert, key section
  160.     IfExists -ovpn ([ref]$content) -dir ([ref]$dir) -buffer ([ref]$exported) -pa 'ca'
  161.     IfExists -ovpn ([ref]$content) -dir ([ref]$dir) -buffer ([ref]$exported) -pa 'cert'
  162.     IfExists -ovpn ([ref]$content) -dir ([ref]$dir) -buffer ([ref]$exported) -pa 'key'
  163. }
  164.  
  165. #TLS-AUTH section
  166. [string]$a = $content -match $retls
  167. if ($a -ne $null -and $a -match $retls) {
  168.     # tls-auth section found
  169.     [string]$arch = "$dir\$($Matches.a)"
  170.     [string]$keydir = "key-direction $($Matches.b)"
  171.  
  172.     [string[]]$c = Get-Content $arch
  173.  
  174.     $exported += $keydir
  175.     $exported += "<tls-auth>"
  176.     $exported += Get-Content $arch
  177.     $exported += "</tls-auth>"
  178. }
  179.  
  180. # Obtener nombre archivo
  181. [int]$beg = 1 + $tun.LastIndexOf('\')
  182. [string]$fSal = $tun.Substring($beg)
  183.  
  184. # To choose the exported file type (Viscosity uses UTF8bom encoding), Default/ANSI encodig for the rest
  185. [string]$isVisc = Read-Host "Export for MacOS (Viscosity/Tunnelblick) (UTF8 w BOM)? [y/N]"
  186. if ($isVisc -eq 'y') {
  187.     # Viscosity. Export with "UTF8 w BOM" encoding
  188.     [string]$nombre = $fSal.Replace('.ovpn', '')
  189.     [string[]]$visco = @('#-- Config Generated by ParseOpenVPN for Viscosity --#', '' `
  190.                         ,'#viscosity startonopen false' `
  191.                         ,'#viscosity dhcp true' `
  192.                         ,'#viscosity dnssupport true' `
  193.                         ,"#viscosity name $nombre")
  194.    
  195.     $UTF8bomEnc = [System.Text.UTF8Encoding]::new($true);
  196.     $fSal = $fSal.Replace('.ovpn', '-viscosity.ovpn')
  197.     [System.IO.File]::WriteAllLines("$env:UserProfile\$fSal", $visco + $exported, $UTF8bomEnc)
  198. }
  199. else {
  200.     # Rest of platforms. Export with ANSI encoding
  201.     # TODO: validation pending: is 'default' valid for every Windows OS languages?
  202.     $fSal = $fSal.Replace('.ovpn', '-inline.ovpn')
  203.     $exported | Out-File -Encoding default -FilePath "$env:UserProfile\$fSal"
  204. }
  205.  
  206. Write-host $([string]::Format("`nInline config file '{0}' created in folder '{1}'.", $fSal, $env:UserProfile)) -BackgroundColor DarkGreen
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top