4. – Server side integration

4.1 – HTTP API

You can use HTTP request to create a server, symlink dynamically if you don't want to write a plug-in for the gateway.

To use the HTTP server, you’ll need to configure a password in gateway.conf:

Password = yourPassword

Then you can use MD5 hash of this password with the HTTP API.

Create servers on gateway:

http://gatewayAddress/SERVER?id=serverId&displayName=Name&server=hostName&gatewayPwd=passwordInGateway.conf&...

gatewayPwd is hexadecimal MD5 hash of the password which is configured in gateway.conf.

To delete a server add "&action=delete" to the URL; to update a server, add "&action=update" to the URL.

List servers:

http://w-think/SERVER?action=list&gatewayPwd=21232f297a57a5a743894a0e4a801fc3&id=ATPlus

It returns the asked server if id is specified:

{"id":"ATPlus","displayName":"ATPlus","server":"cloud.thinrdp.net","shadowing":false,"protocols":"rdp","icon":"kbd.png","rdp":{"username":"demo","password":"demo"}}

It returns all servers if id is not specified:

{
  "display" : true,
  "type" : "NORMALLIST",
  "cols" : [
    {"name" : "id"},
    {"name" : "displayName"},
    {"name" : "server"},
    {"name" : "remoteProgram"},
    {"name" : "command"}
  ],
  "rows" : [
    ["ATPlus", "ATPlus", "192.168.12.117", "", ""],
    ["WordPad", "WordPad", "192.168.0.118", "", "wordpad.exe"]
  ]
}

http://gatewayAddress/SYMLINK?symlink=symlinkId&server=existingServerId&validTime=20m&gatewayPwd=passwordInGateway.conf&...

You can also use "validFrom", "validTo" parameters. Please check http://www.remotespark.com/view/doc/com/toremote/gateway/connection/SymLink.html for more information.

To delete a symlink, add "&action=delete" to the URL; to update a symlink, add "&action=update" to the URL.

List symlinks:

http://w-think/SYMLINK?action=list&gatewayPwd=21232f297a57a5a743894a0e4a801fc3&symlink=212a155ee951-40db-95ea-177183174fa7

It returns the asked symlink if symlink is specified:

{"id":"212a155e-e951-40db-95ea-177183174fa7","resourceId":"169.254.146.243","validFrom":"Aug 26, 2015 12:00:00 AM","parameters":""}

It returns all the symlinks if symlink is not specified:

{
  "cols":[
    {"name":"id"},
    {"name":"resourceId"},
    {"name":"password"},
    {"name":"validFrom"},
    {"name":"validTime"},
    {"name":"validTo"},
    {"name":"parameters"},
    {"name":"comment"}
  ],
  "rows":[
    ["212a155e-e951-40db-95ea-177183174fa7", "169.254.146.243", "", 1440568800000, "", 0, "", ""],
    ["c5c6bc9d-f8a7-42ca-af9c-bd28c86adab4", "169.254.146.243", "", 1452544860000, "", 0, "", ""]
  ]
}

List sessions:

http://w-think/SESSION?action=list&gatewayPwd=21232f297a57a5a743894a0e4a801fc3&id=a29575a9-08c2-4162-9bfb-4876820953db

It returns the single session information if session id is specified:

{"id":"a29575a9-08c2-4162-9bfb4876820953db","server":"192.168.12.118","clientIp":"169.254.84.132","clientAgent":"Mozilla\/5.0 (Windows NT 10.0; WOW64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/47.0.2526.111 Safari\/537.36","thumbnail":"","startTime":"Tue Jan 26 15:38:55 MST 2016","numericId":621779525,"user":"","domain":"","rdpId":1,"startTime2":1453847935826}

It returns all sessions if session id is not specified:

{
  "cols":[
    {"name":"id"},
    {"name":"server"},
    {"name":"clientIp"},
    {"name":"clientAgent"},
    {"name":"startTime"},
    {"name":"numericId"},
    {"name":"user"},
    {"name":"domain"},
    {"name":"join"},
    {"name":"protocol"},
    {"name":"symlink"},
    {"name":"thumbnail"}
  ],
  "size":1,
  "rows":[
    ["a29575a9-08c2-4162-9bfb-4876820953db","192.168.12.118","169.254.84.132","Mozilla\/5.0 (Windows NT 10.0; WOW64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/47.0.2526.111 Safari\/537.36","Tue Jan 26 15:38:55 MST 2016",621779525,"","","","RDP","",""]
  ]
}

It returns multiple session information if ids parameter is used:

http://w-think/SESSION?action=list&gatewayPwd=21232f297a57a5a743894a0e4a801fc3&id=a29575a9-08c2-4162-9bfb-4876820953db&ids=sessinId1,sessionId2

[{session1}, {session2}]

Upload license file:

http://wthink/CONTROL?licenseFile=base64encodedLicenseFile&gatewayPwd=21232f297a57a5a743894a0e4a801fc3

Please make sure you encode the value of licenseFile. For example:

encodeURIComponent(base64encodedLicenseFile)

The new license file information will be returned in JSON format if the license file was uploaded successfully.

To query the current license file information, you can use:
http://w-think/CONTROL?licenseFile=.&gatewayPwd=21232f297a57a5a743894a0e4a801fc3

Get gateway information

http://w-think/CONTROL?target=gateway

{"version":"5.8.0","buildNumber":"941","buildTime":"2020_03_04_10","startTime":1583342850085}

Password is not needed for this gateway information request.

Reset Two Factor Authentication

http://w-think/CONTROL?target=twofa&user=Username&gatewayPwd=21232f297a57a5a743894a0e4a801fc3

curl -k -G --data-urlencode "target=twofa" --data-urlencode "user=svtest\user1" https://127.0.0.1/CONTROL

Error handling:

HTTP request will return HTTP Status code 500 and {"error:": "error information"} in JSON if there is an error. For example, server or symlink with specified id was not found when you try to get a server or symlink.

HTTP request will return status code 200 if operation succeeded.

4.2 – Plug-in

The gateway is a multi-thread application, so make sure your plug-in is:

Please refer to the related links:

4.2.1 – Start gateway and the plug-in example project in Eclipse

Download the plug-in example:
http://remotespark.com/Plugin.zip

Extract the zip to your Eclipse workspace and run the follwing actions:

  1. File -> Import
  2. Click "Next"
  3. "Browse" to your workspace directory
  4. Select the Plugin project.
  5. Click "Finish"
  6. Right click on the Plugin project, "Run As" -> "Java Application"
  7. Make sure "SparkGateway – com.toremote.gateway" is selected.
  8. Click "OK"

Now the gateway with the plug-in is running in Eclipse. You can use the "Debug As" -> Java Application to debug your plug-in code.

Checklist:

4.2.2 – Handshake plug-in

Handshake plug-in is invoked before establishing a RDP connection. It’s a good place to verify, modify or refuse the connection.

You can put any parameter you want when you create a connection on the client side. For example, you can put user’s session id (session on your portal) into a RDP connection:

var rdp = new svGlobal.Rdp(‘ws://myGateway/RDP?server=myServer&token=mySessionId&…’);

Then in the handshake plug-in, you can get the parameter and verify it through a web server on your portal.

class SimpleHandshakePlugin implements HandshakeInterface{
@Override
public Map<String, String> onHandshake(Map<String, String> parameters) throws ClientException{
  String token = parameters.get("token");
  if (isInvalidSession(token)){
    throw new ClientException("Invalid sessioin");
  }
  return parameters;
}

You can also encrypt the token from your portal (encrypted on server side), then decrypt it in the plug-in:

public Map<String, String> onHandshake(Map<String, String> parameters) throws ClientException{
  String token = decryptToken(token);//throw ClientException if not valid
  Map<String, String> paramsFromToken = parseToken(token);
  parameters.put(RdpParameter.server, paramsFromToken.get("server"));
  parameters.put(RdpParameter.user, paramsFromToken.get("user"));
  parameters.put(RdpParameter.pwd, paramsFromToken.get("pwd"));
  String userIp = parameters.get(RdpParameter.ARG_CLIENT_IP);
  //enable recording
  parameters.put(RdpParameter.sessionRecord, "1"); //enable session recording
  //specify the recording file name (optional)
  parameters.put(RdpParameter.RECRODING_FILE_NAME, "myFileName");
  return parameters;
}

Best practices:

4.2.3 – Deploy your plug-in

Export the jar file:

  1. Right click on the project, "Export", select "Runable JAR file" under Java.
  2. Choose "SparkGateway - Plugin" in Launch configuration.
  3. Choose export destination.
  4. Click "Finish"

Make sure "Extract required libraries into generated JAR" selected in "Library handling"

It’s better to put your plug-in can be in a separated jar file. In this case, you should set up your plug-in file path in gateway.conf:

pluginFile=theLocationOfYourPlugin.jar

Here is how to export the plug-in into a separated jar file (without the content of SparkGateway.jar):

4.3 – Downloading files unprompted

Users can download files through custom apps and programs. This can be archived by using the clipboard redirection:

  1. Make sure clipboard redirection is enabled, and copyFile=true in gateway.conf.
  2. Set fileUnprompted=xlsx,xls (Excel files in this case, change to your related file types)
  3. In the user's application, you need to provide a button or menu like "Download file", when the user clicks this button, their application needs to copy the file to the clipboard (remote computer's clipboard). Reference:
    https://stackoverflow.com/questions/25708895/how-to-copy-files-by-win32-api-functions-and-paste-by-ctrlv-in-my-desktop
  4. The user will then see this message in the browser:
    Unknown.png
  5. User clicks once again to download the file.

For this solution: