Use of the API without .NET, JAVA, or gacmd. A proof-of-concept in Powershell.
Post any question you may have in regards to GoAnywhere MFT and let our talented support staff and other users assist you.
If you need a quicker response, please create a support ticket via the customer portal my.goanywhere.com or contact our support team by email at [email protected].
If you need a quicker response, please create a support ticket via the customer portal my.goanywhere.com or contact our support team by email at [email protected].
1 post
Page 1 of 1
Here's a Powershell script that doesn't drive gacmd, use the .NET api or the Java api. I wiresharked the web calls gacmd was making. Powershell pretends to be that client to the server. The good news is this is sessionless; one web call gives one result. The data in motion security is totally dependent upon the fact that this web call should happen over a secure connection, ie: https. Going through a reverse proxy should work just fine.
Now, I didn't completely reverse engineer gacmd. I just wanted to show that it can be done and encourage the GoAnywhere devs to release the web call details, maybe give us a wsdl or a wadl (and for god sake please provide support for json bodies or something more reasonable). I only support three commands. Hack this up and add more. While your at it here are some improvements you could throw in:
Now, I didn't completely reverse engineer gacmd. I just wanted to show that it can be done and encourage the GoAnywhere devs to release the web call details, maybe give us a wsdl or a wadl (and for god sake please provide support for json bodies or something more reasonable). I only support three commands. Hack this up and add more. While your at it here are some improvements you could throw in:
- * ParameterSets for each command
* Parameter descriptors, maybe take input from the pipeline, that kind of thing
* Better exception handling
* Better output format. I'm just dumping xml. I'm lazy.
* More commands supported (lookin at you for that wsdl, devs)
* Some kind of GPL license up in there. I don't care just take it.
Code: Select all
[CmdletBinding()]
param(
[string]$url = [ your server url here, including the port ex: https://mft.mycompany.com:8000 ],
[string]$user = [ the account name use to manage web users ],
[string]$password [ the account password you use to manage web users ],
[string]$command,
[string]$webUserTemplate,
[string]$webUserName,
[string]$webUserPassword,
[string]$webUserFirstName,
[string]$webUserLastName,
[string]$webUserDescription,
[string]$webUserEmail,
[switch]$generatePassword,
[switch]$forcePasswordChange,
[switch]$emailPassword
)
function Create-MultiPartBody{
param(
[object]$parts,
[string]$boundary
)
$body = ''
foreach($part in $Parts.GetEnumerator()){
if($part.Name -eq 'commandAction'){
$disposition = "form-data; name=`"file`"; filename=`"$($part.Name)`""
$type = 'application/octet-stream; charset=ISO-8859-1'
$encoding = 'binary'
}
else{
$disposition = "form-data; name=`"$($part.Name)`""
$type = 'text/plain; charset=UTF-8'
$encoding = '8bit'
}
$bodySegment = @"
--$($boundary)
Content-Disposition: $($disposition)
Content-Type: $($type)
Content-Transfer-Encoding: $($encoding)
$($part.Value)
"@
$body += $bodySegment
}
$body += "--$($boundary)--`n"
$body.Replace("`n","`r`n")
return $body
}
function Create-CommandXml{
param(
[object]$command
)
[xml]$doc = ''
$rootNode = $doc.CreateElement('command')
[void]$doc.AppendChild($rootNode)
$command.GetEnumerator() | ?{$_.Value -ne $null} | %{
$parameter = $doc.CreateElement($_.Name)
if($_.Value -is [boolean] -or $_.Value -is [switch]){
$value = $_.Value.ToString().ToLower()
}else{
$value = $_.Value
}
$parameter.InnerText = $value
[void]$rootNode.AppendChild($parameter)
}
return $doc.OuterXml.Trim()
}
function Send-WebRequest{
param(
[string]$url,
[object]$contentParts
)
$apiURL = "$($url)/goanywhere/servlets/commandCenter"
Write-Verbose "URL: `n$($apiURL)"
$randomString = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes([System.Guid]::NewGuid().ToString()))
$boundary = $randomString.Substring($randomString.Length-39)
$userAgent = 'Jakarta Commons-HttpClient/3.1'
$headers = [ordered]@{
'Transfer-Encoding' = 'chunked';
'Content-Type' = "multipart/form-data; boundary=$($boundary)";
}
$body = Create-MultiPartBody $contentParts $boundary
Write-Verbose "Body: `n$($body)"
try{
$response = Invoke-WebRequest `
-Uri $apiURL `
-DisableKeepAlive `
-UserAgent $userAgent `
-Headers $headers `
-Method POST `
-Body $body
}
catch{
Write-Verbose $_.Exception.Message
}
return $response
}
$commandActions = @{
deleteWebUser = [ordered]@{
userName = $webUserName;
}
addWebUser = [ordered]@{
webUserTemplate = $webUserTemplate;
userName = $webUserName;
userPassword = $webUserPassword;
firstName = $webUserFirstName;
lastName = $webUserLastName;
description = $webUserDescription;
email = $webUserEmail;
}
resetWebUserPassword = [ordered]@{
userName = $webUserName;
generatePassword = $generatePassword;
userPassword = $webUserPassword;
forcePasswordChange = $forcePasswordChange;
displayPassword = $true;
emailPassword = $emailPassword;
}
}
$contentParts = [ordered]@{
command = $command
user = $user;
password = $password;
passwordIsEncrypted = 'false';
commandAction = Create-CommandXml $commandActions.$Command
}
$response = Send-WebRequest $url $contentParts
$response.Content
#.\Set-MFTWebUser.ps1 -webUserName 'TestUser' -command 'addWebUser' -webUserDescription 'Delete this user' -webUserEmail '[email protected]'
#.\Set-MFTWebUser.ps1 -webUserName 'TestUser' -command 'resetWebUserPassword' -generatePassword -emailPassword
#.\Set-MFTWebUser.ps1 -webUserName 'TestUser' -command 'deleteWebUser'
1 post
Page 1 of 1