Creating a Custom URL Protocol for SSH

It can sometimes be very useful to have links in your web browser spawn third-party applications for you. A user recently submitted a question wanting to have a URL open an SSH connection with PuTTY. As he learned, this can be done by creating a custom URL protocol.

I am trying to set up Firefox to launch a putty session upon the entry of ssh://nodename in the address bar and I am having some issues. I have successfully added the necessary keys to the registry such that putty is launched, however, putty doesn’t accept the input correctly and tries to connect to a non-existent host.

I was thinking about writing a bat file which would accept the input from Firefox […] but I am unsure how to do so since I am not a scripter or a windows guru. Any help you could provide would be greatly appreciated. Thanks!
– Kyle V.

Well, Kyle, you are so very close to your solution. The problem here is that the browser is passing the complete URL to the PuTTY application. Since PuTTY does not accept full URLs as host names, you receive a non-existent host name error.

As you suggested, the easiest way to solve this problem is to use a script to parse the URL into a valid host name and, in turn, launch the PuTTY application. You suggested a batch file, but you’ll see why this is much easier in WSH. But first, let’s show our readers how to create the custom protocol necessary to make this all work.

Adding custom protocols is extremely easy but it does require editing the Windows Registry. If you are uncomfortable editing the registry, I’ve written an installer that will do this for you. You can find the link at the end of this article.

You’re going to be creating several registry keys and values to create the key structure necessary for this to work. To begin, you’ll need to click the start button and choose Run… to open the Run Dialog box. Enter regedit and choose OK to open the Registry Editor.

In the left pane, expand the HKEY_CLASSES_ROOT hive. Right-click in the right pane and choose New > Key. Name the newly created key SSH and press enter.

Again in the right pane, double-click the default string value. Enter URL:SSH Protocol and click OK to change its value data. Right-click and create a new text string value named URL Protocol. Leave its value data blank.

Right-click again in the right pane and create a new key named shell. Continue creating new sub-keys until you have a directory structure that looks like this:

HKEY_CLASSES_ROOT\SSH\shell\open\command

Be sure that the command sub-key is selected in the left pane. Double-click its default value and change the value data. You want to provide the command line that should be executed for this custom protocol. In this example, it should launch the script file that we will be creating:

wscript.exe “C:\SSH\ssh.vbs” “%1”

The quotation marks are optional unless your path contain spaces. I’ve included them here for demonstration purposes. Likewise, the quotation marks around the %1 are also optional in this case since valid URLs cannot contain spaces.

By the way, the %1 instructs the browser to append the URL data to the command line we’ve provided. If you simply wanted to launch an application without passing any data to it, you could leave that out.

Now let’s create a script that will parse the URL from our command line into a valid host name for the PuTTY application.

Here’s where the problem lies. Entering the URL SSH://hostname into the address bar in Firefox actually passes the following URL to command line provided in our registry settings:

SSH://hostname/

There are two items of concern here. The first is that the browser has included the SSH protocol identifier in the URL. The second is that some browsers, including Firefox, append a trailing forward slash to all URLs. We’ll need a script to remove both of these elements before launching the SSH client.

strSSH = "C:\ssh\putty.exe"

Begin your WSH script by providing a path to the SSH client. If you’re using a client other than PuTTY, be sure to include any necessary command line switches as well.

Select Case WScript.Arguments.Count
	Case 0
		WScript.Echo "No hostname provided.  Aborting SSH operation."
		WScript.Quit
	Case Else
		Set colArgs = WScript.Arguments
		For i = 0 To WScript.Arguments.Count - 1
			strHost = " " & WScript.Arguments.Item(i)
		Next
End Select

Next, our script needs to read the URL that has been passed to it via the command line and store it in a variable. I’ve also added a little error-handling that will quit script execution if there was no URL.

Set WshShell = CreateObject("WScript.Shell")
WshShell.Run """" & strSSH & """ """ & CleanHostname(strHost) & """"
WScript.Quit

We finish our script by telling it to launch the SSH client. I’ve used the WshShell object’s Run method to execute a command line. Notice that I’m passing our URL through the CleanHostname function. This is the function that will strip the URL string into a valid host name.

Finally, we add the CleanHostname function.

Function CleanHostname(strHost)
	strHost = Trim(strHost)
	'Remove protocol if it was passed
	If InStr(strHost, "ssh://") = 1 Then
		strHost = Right(strHost, Len(strHost) - 6)
	End If
	'Remove trailing slash if present
	If InStrRev(strHost, "/") = Len(strHost) Then
		strHost = Left(strHost, Len(strHost) - 1)
	End If
	'Return cleaned hostname
	CleanHostname = strHost
End Function

This function performs the two steps I mentioned earlier. It removes the protocol from the beginning of the URL and removes a trailing forward slash if one exists.

Save the file as ssh.vbs and make sure that it is located at the path specified by the command line in the registry key you created earlier.

Now open any browser and enter a URL in the form of SSH://nodename and watch PuTTY open a connection to the node name provided!

If you are not comfortable making the registry edits or creating the script discussed in this article, you can simply download the installer below to do it for you. The installer also includes the free PuTTY SSH client software.

SSH Protocol Installer

Tags

Like the read? Share it!

28 Comments

  • Robert,

    Thanks so much for your help. The insight you gave into the nature of the issue along with the suggestions and ultimately a packaged software solution was exactly what I was looking for. Keep up the great work!

    Kyle

  • Thank you so much, Kyle. It was a pleasure. I’m glad I could help!

  • Hi,

    I made a small mod to your ssh.vbs script to enable it to accept custom ports. Did it quick and dirty could be done a bit better but works.

    Tim

    ‘ Region Description

    ‘ Name: ssh.vbs
    ‘ Author: Robert Dunham (Nilpo)
    ‘ Website: http://www.nilpo.com
    ‘ Description: This script is for use with a custom SSH protocol for Putty.

    ‘ EndRegion

    strSSH = “C:\ssh\putty.exe”
    strPort = “22”

    Select Case WScript.Arguments.Count
    Case 0
    WScript.Echo “No hostname provided. Aborting SSH operation.”
    WScript.Quit
    Case Else
    Set colArgs = WScript.Arguments
    For i = 0 To WScript.Arguments.Count – 1
    strHost = ” ” & WScript.Arguments.Item(i)
    Next
    End Select

    Set WshShell = CreateObject(“WScript.Shell”)
    strHost = CleanHostname(strHost)
    WshShell.Run “””” & strSSH & “”” -P ” & strPort & ” “”” & strHost & “”””
    WScript.Quit

    Function CleanHostname(strHost)
    strHost = Trim(strHost)
    ‘Remove protocol if it was passed
    If InStr(strHost, “ssh://”) = 1 Then
    strHost = Right(strHost, Len(strHost) – 6)
    End If
    ‘Remove trailing slash if present
    If InStrRev(strHost, “/”) = Len(strHost) Then
    strHost = Left(strHost, Len(strHost) – 1)
    End If
    If InStrRev(strHost, “:”) > 0 Then
    strPort = right(strHost, Len(strHost) – InStrRev(strHost, “:”))
    strHost = Left(strHost, InStrRev(strHost, “:”) – 1)
    End If
    ‘Return cleaned hostname
    CleanHostname = strHost
    End Function

  • Looks good, Tim. Thanks for the addition!

  • Thank you for your article. It’s very good. I search very long time how to create my own protocol. I customise your script for my usage.

    LePiaf

  • I used the install package at the end of the article. It worked well. However, our my specific usage is to access a device through a terminal server (communications server) i.e a router, switch, etc. The typical host string is… a.b.c.d:port# or 10.10.10.1:2018.
    With the current install configuration, the port number is disregarded. I need to have the ssh app i.e. Putty, open the session all the way through. Port numbers vary depending upon the link so… … any help would be greatly appreciated. Thanks. Chuck

  • Take a look at Tim Koopman’s post above. He has made a modification that allows you to specify a custom port number. Let me know how that works out for you.

  • Thanks Nilpo and Tim. However, I’m not a “coder” and wouldn’t know what to do with what was written. If it is already in the download / install link, then I have it and it does not behave as I would want. what next? thanks. Chuck

  • Hi, Chuck. Try this.

    ' Name: ssh.vbs
    ' Author: Robert Dunham (Nilpo)
    ' Website: http://www.nilpo.com
    ' Description: This script is for use with a custom SSH protocol for Putty.
    
    strSSH = "C:\ssh\putty.exe"
    strPort = "2018"
     
    Select Case WScript.Arguments.Count
    	Case 0
    		WScript.Echo "No hostname provided. Aborting SSH operation."
    		WScript.Quit
    	Case Else
    		Set colArgs = WScript.Arguments
    		For i = 0 To WScript.Arguments.Count - 1
    			strHost = " " & WScript.Arguments.Item(i)
    		Next
    End Select
     
    Set WshShell = CreateObject("WScript.Shell")
    strHost = CleanHostname(strHost)
    WshShell.Run """" & strSSH & """ -P " & strPort & " """ & strHost & """"
    WScript.Quit
     
    Function CleanHostname(strHost)
    	strHost = Trim(strHost)
    	'Remove protocol if it was passed
    	If InStr(strHost, "ssh://") = 1 Then
    		strHost = Right(strHost, Len(strHost) - 6)
    	End If
    	'Remove trailing slash if present
    	If InStrRev(strHost, "/") = Len(strHost) Then
    		strHost = Left(strHost, Len(strHost) - 1)
    	End If
    	If InStrRev(strHost, ":") > 0 Then
    		strPort = Right(strHost, Len(strHost) - InStrRev(strHost, ":"))
    		strHost = Left(strHost, InStrRev(strHost, ":") - 1)
    	End If
    	'Return cleaned hostname
    	CleanHostname = strHost
    End Function

  • Nilpo, thanks for the modification. However, it didn’t work. Actually, it failed to open a session or respond to keyboard input. I renamed the original script file and saved this modified file as the same name “SSH.VBS”. When I clicked on the link in the browser, the application (putty) launched but, didn’t open a session or respond to any keyboard entry. I deleted the modified file and renamed the original file back to SSH.VBS and the application functioned as before; opened a session only to the terminal server and no farther. I did note that in the modified file, you made mention of a port number “2018”. I was not attempting to access any device on that port. How this application should work is to open a session through the terminal server to the device located on the port number that is configured in the data field of the link. Port numbers could range from 2000 – 3000 depending upon the type of terminal server used.

    Thank you.
    Chuck

  • Hi, Chuck.

    So you’re saying that you need this script to not only connect with Putty, but also to automate part of that connection? If I’m understanding you correctly, you need this script to send commands to Putty to connect to a remote device after the initial connection is made.

  • Hi,

    I am trying to use Reflection 12 instead of putty for the default client and it requires a /w switch. I’ve tried a number of places in the vsb script to add the switch, but just cannot seem to find the right spot.

    Here are some of my tries.
    strSSH = “C:\Program Files\Reflection\r2win.exe /w”
    or
    WshShell.Run “””” & strSSH & “/w” & “”” “”” & CleanHostname(strHost) & “”””

    The above change causes the return of the Error “the system cannot find the file specified”

    Once I click “okay” to the error message, Relections starts up without any connection info.

    If I don’t have the /w switch anywhere then I get a settings file not found message. This is the same message that I get when I telnet without the /w switch. To fix the telnet I was able to put the switch in the URL: telnet protocol in my Windows registered file types.

    Thanks in advance for any help
    Joe

  • Hi,

    I have updated the script again as I also now required rdp urls to work. Also should be easy to add your own if needed.

    helper.vbs
    ‘ Region Description

    ‘ Name: ssh.vbs
    ‘ Author: Robert Dunham (Nilpo)
    ‘ Tim Koopman
    ‘ Website: http://www.nilpo.com
    ‘ Description: This script is for use with a custom protocol like ssh for Putty.

    ‘ EndRegion

    strSSH = “C:\URL_Helper\putty.exe”
    strRDP = “mstsc /v:”
    strPort = “”
    strApp = “”

    Select Case WScript.Arguments.Count
    Case 0
    WScript.Echo “No hostname provided. Aborting operation.”
    WScript.Quit
    Case Else
    Set colArgs = WScript.Arguments
    For i = 0 To WScript.Arguments.Count – 1
    strHost = ” ” & WScript.Arguments.Item(i)
    Next
    End Select

    Set myRegExp = New RegExp
    myRegExp.IgnoreCase = True
    myRegExp.Global = True
    myRegExp.Pattern = “(\w+)\://((?:\d{1,3}\.){3}\d{1,3})(?:\:(\d+))?”

    Set myMatches = myRegExp.Execute(strHost)

    If myMatches.count = 1 Then
    strApp = lcase(myMatches(0).SubMatches(0))
    strHost = myMatches(0).SubMatches(1)
    strPort = myMatches(0).SubMatches(2)

    Set WshShell = CreateObject(“WScript.Shell”)

    Select Case strApp
    Case “ssh”
    If strPort = “” Then
    strPort = “22”
    End If
    WshShell.Run “””” & strSSH & “”” -P ” & strPort & ” “”” & strHost & “”””
    Case “rdp”
    If strPort “” Then
    strPort = “:” & strPort
    End If
    WshShell.Run strRDP & strHost & strPort
    Case Else
    WScript.Echo “Invalid application ” & strApp
    WScript.Quit
    End Select
    End If
    _____________________________________________________
    For each protocol you also need the registry updated. Save the below in a .reg file and install.

    Windows Registry Editor Version 5.00

    [HKEY_CLASSES_ROOT\SSH]
    @=”URL:SSH Protocol”
    “URL Protocol”=””

    [HKEY_CLASSES_ROOT\SSH\shell]

    [HKEY_CLASSES_ROOT\SSH\shell\open]

    [HKEY_CLASSES_ROOT\SSH\shell\open\command]
    @=”wscript.exe C:\\URL_Helper\\helper.vbs %1″

    [HKEY_CLASSES_ROOT\RDP]
    @=”URL:RDP Protocol”
    “URL Protocol”=””

    [HKEY_CLASSES_ROOT\RDP\shell]

    [HKEY_CLASSES_ROOT\RDP\shell\open]

    [HKEY_CLASSES_ROOT\RDP\shell\open\command]
    @=”wscript.exe C:\\URL_Helper\\helper.vbs %1″

  • Hi

    I have installed this SSH Protocol and it works fine in Google Chrome and Opera but it doesn’t works in Firefox.

    It gives error as”Unable to open connection to ssh Host does not exist”

    Any suggestion or clue, what could be wrong.

    Thank you
    Manish

  • Nilpo,
    Thanks for this. Every bit of what I was looking for.
    Tim, Thank you for the add on for custom ports. Everything works perfect.

    Craig.

  • Instead of a hostname how can I pass the name of a saved Putty session?
    This is vital for auto-login using SSH keys.
    Thanks a bunch.

  • Oh MY!

    Find:
    WshShell.Run “””” & strSSH & “”” -P ” & strPort & ” “”” & strHost & “”””

    Replace with:
    WshShell.Run “””” & strSSH & “”” -load “”” & strHost & “”””

    Use in Browser:
    ssh://session_name/

    ^^^
    The above actually works(!!) for me (WinXP), but only with IE([email protected]#%!!)………..
    …any ideas on how to fix for Firefox w/ “host does not exist?”

    Thanks again

  • Firefox answer = Tools > Options > Applications > ssh
    Set to use ” wscript.exe C:\ssh\ssh.vbs %1 ”

    Nilpo, this is great :o), and now it works w/ [ ssh://session_name ] too!

  • PFS, nice work. Thanks for the contribution.

  • Sure, you are welcome. 🙂
    ssh://session_name (+ the changes noted above) also confirmed to work on Vista (tested only on Firefox)

  • Would you mind updating the installer to include the port functions in the VBS script??

  • Hi Nilpo, how can I change this script to launch ssh session with SecureCRT vs. Putty?
    Thanks

  • How do I adapt this to use Telnet instead of SSH?

    If I call ssh://64.xx.xx.xx it opens up my Term client fine, but there is an extra ” (that’s a quote) at the end of the IP address? for example:

    My Term program says.. Connecting to 64.xx.xx.xx” (this extra quote at the end is causing it to fail..)

    Any ideas..?

  • The script works fine on Windoze 7 too. For Firefox users, don’t forget to select Tools -> Options -> Appications -> and scroll down to ssh and use drop down box to select wscript.exe after you run the very hand script provided by the author. GOOD STUFF!

  • you have got a excellent weblog here! want to develop invite posts on my weblog?

  • It’s actually a nice and useful piece of info. I’m glad that you shared this helpful info with us. Please stay us informed like this. Thanks for sharing.

  • Hi there

    Trying to adapter this for telnet:// URLs also. Have tried creating a copy of the SSH script above and altering it for Telnet only but can’t seem to get it to work;

    Any help would be appreciated.

    Thanks

  • how to have this worked for ssh2 protcol

Leave a Reply

Contact

Wanna say hello?
Drop us a line!

You'll find us here

1 Microsoft Way,
Redmond,
WA 98052, United States