cURL to AWS S3 using AppleScript - amazon-s3

I'm using AppleScript and shell to curl files from my local system to an AWS S3 bucket. I'm able to accomplish this calling a bash script from AppleScript, but when I try to use strictly AppleScript I get a "SignatureDoesNotMatch" error from AWS.
Anybody see what might be wrong?
There is an existing thread on this where the OP encountered the same problem then finally gave up on this method and used PHP.
AppleScript do shell script cURL command for Amazon s3
My code:
--File info
set filePath to "/Volumes/MyFolder"
set fileName to "001.jpg"
--AWS Info
set awsRegion to "s3-us-west-1"
set bucketName to "mybucketname"
set awsPath to "mysubfolder"
set s3key to "myawskey"
set s3secret to "myawssecretkey"
--Build cannonical request
set acl to "x-amz-acl:public-read"
set contentType to "application/octet-stream"
set storageType to "x-amz-storage-class:STANDARD"
--set theDate to do shell script "date '+%a, %d %b %Y %T %z'"
set theDate to do shell script "date -R"
set connonicalString to "PUT\\n\\n" & contentType & "\\n" & theDate & "\\n" & acl & "\\n" & storageType & "\\n/" & bucketName & "/" & awsPath & "/" & fileName
set signatureCommand to "echo -en " & connonicalString & " | openssl sha1 -hmac " & s3secret & " -binary | base64"
set signature to do shell script signatureCommand
--Build the curl command
set curlCommand to "curl -s -X PUT"
set sourcePath to " -T " & filePath & "/" & fileName
set header01 to " -H 'Host: " & bucketName & "." & awsRegion & ".amazonaws.com'"
set header02 to " -H 'Date: " & theDate & "'"
set header03 to " -H 'Content-Type: " & contentType & "'"
set header04 to " -H '" & storageType & "'"
set header05 to " -H '" & acl & "'"
set header06 to " -H 'Authorization: AWS " & s3key & ":" & signature & "'"
set targetPath to " https://" & bucketName & "." & awsRegion & ".amazonaws.com/" & awsPath & "/" & fileName
set shellCommand to curlCommand & sourcePath & header01 & header02 & header03 & header04 & header05 & header06 & targetPath
--Run the script
do shell script shellCommand
Here is the error:
SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your key and signing method....

The problem you cite is due to the shell being used by applescript: it's /bin/sh
but your terminal emulator is probably using BASH (/bin/bash).
Therein, the echo used in /bin/sh seems not to accept switches!
i.e., "-en " got rolled into what becomes applescript variable |connonicalString|
Either substitute for echo -en with printf %s (no trailing space!) or use heredoc syntax for variable signatureCommand for its use in
do shell script signatureCommand
set signatureCommand to "/bin/bash <<EOF
echo -en " & connonicalString & " | openssl sha1 -hmac " & s3secret & " -binary | base64
EOF"
Compare this output done in a terminal window running BASH:
Last login: Tue Mar 24 12:17:22 on ttys003
mylocal:~ myself$ echo -en PUT\n\napplication/octet-stream\nTue, 24 Mar 2020 16:07:09 -0400\nx-amz-acl:public-read\nx-amz-storage-class:STANDARD\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64
CpUNJTkp6i1ocERz7PQ+Q/m5rYI=
With this output done in a terminal window running /bin/sh:
mylocal:~ myself$ /bin/sh
mylocal:~ myself$ echo -en PUT\n\napplication/octet-stream\nTue, 24 Mar 2020 16:07:09 -0400\nx-amz-acl:public-read\nx-amz-storage-class:STANDARD\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64
Wy1tNXiDmDsdlm/sBDDYCoc0kik=
Then observe what is the output in Script Editor using its default /bin/sh:
tell current application
do shell script "date -R"
--> "Tue, 24 Mar 2020 16:07:09 -0400"
do shell script "echo -en PUT\\n\\napplication/octet-stream\\nTue, 24 Mar 2020 16:07:09 -0400\\nx-amz-acl:public-read\\nx-amz-storage-class:STANDARD\\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64"
--> "Wy1tNXiDmDsdlm/sBDDYCoc0kik="
end tell
Result:
"Wy1tNXiDmDsdlm/sBDDYCoc0kik="
and then forcing it to use /bin/bash:
tell current application
do shell script "date -R"
--> "Tue, 24 Mar 2020 16:46:47 -0400"
do shell script "/bin/bash <<EOF
echo -en PUT\\n\\napplication/octet-stream\\nTue, 24 Mar 2020 16:07:09 -0400\\nx-amz-acl:public-read\\nx-amz-storage-class:STANDARD\\n/mybucketname/mysubfolder/001.jpg | openssl sha1 -hmac myawssecretkey -binary | base64
EOF"
--> "CpUNJTkp6i1ocERz7PQ+Q/m5rYI="
end tell
Result:
"CpUNJTkp6i1ocERz7PQ+Q/m5rYI="

Related

How to execute two commands sequentially

Private Sub btnUnHide_Click(sender As Object, e As EventArgs) Handles btnUnHide.Click
Dim path As String
fdbUnHide.ShowDialog()
path = fdbUnHide.SelectedPath
RunCommandCom(path)
End Sub
Shared Sub RunCommandCom(path As String)
Dim unhide As String = "attrib -r -s -h /s /d"
Try
Shell("cmd.exe /C cd " & path)
Shell("cmd.exe /C" & unhide)
End Sub
I also tried using "&" but didn't work
Shell("cmd.exe /C cd " & path "& " & unhide)
Can anybody help me with this?
NOTE: This answer addresses the problem asked in the question, but it is certainly not the best way of un-hiding a folder and its files.
THE BEST and recommended approach is described in Ctznkane525's answer.
The problem with your current code is that you are missing a space before the ampersand (&).
This:
"cmd.exe /C cd " & path & "& " & unhide
essentially becomes:
"cmd.exe /C cd C:\your\path& attrib -r -s -h /s /d"
...making & part of the path. You need to add a space before it:
"cmd.exe /C cd " & path & " & " & unhide
Though be aware that Shell() is an outdated function from the VB6 era and shouldn't be used. When "executing commads" (or more correctly: starting processes) you should use the Process.Start() method:
Process.Start("cmd.exe", "/C cd " & path & " & " & unhide)
Here is how you unhide a folder in .net and the files
Dim t As New System.IO.FileInfo(path)
t.Attributes = t.Attributes And Not FileAttributes.Hidden
For Each fn As String in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
t = New System.IO.FileInfo(fn)
t.Attributes = t.Attributes And Not FileAttributes.Hidden
Next
The attributes are a bitwise flag. You'll want to import system.io at the top.

VBA and Putty's pscp.exe when username includes # characters

I have some VBA code which is using Putty's pscp.exe file for logging on Unix server. I am using Windows 7.
The problem is that the username includes a # character. I am not able to login if I use the following VBA code.
So, how should I replace Username = "user#example.xxx" to be able to login?
Dim Host As String
Host = "grid1.example.xxx"
Dim Username As String
Username = "user#example.xxx"
Dim Password As String
Password = "Password2012"
Dim Command As String
Command = "pscp.exe -sftp -l " & Username & " -pw " & Password
Shell Command, vbNormalFocus
Worked for me as below:
Dim Host
Host = "grid1.example.xxx"
Dim Username
Username = "username#host"
Dim Password
Password = "Password"
Dim Command
Command = "pscp.exe -l " & Username & " -pw " & Password & " cmd.txt username#host:cmd.txt"
Set oShell = CreateObject ("WScript.Shell")
oShell.run "cmd /k " & Command
Sorry, don't know how to format correctly in the comments section, so posting here. Try to run it in a .bat file instead.
I do think, however, the username should not include the hostname, and rather get concatenated in the target %Hostname%.
#echo off
set Username="username#hostname"
set Password=Password
set Hostname=hostname
rem or maybe like this
rem set Username=username
rem set Hostname=username#hostname
pscp32.exe -sftp -l %Username% -pw %Password% cmd.txt %Hostname%:cmd.txt
if errorlevel 2 goto Err2
if errorlevel 1 goto Err1
echo success!
goto :EOF
:Err2
echo error 2
goto :EOF
:Err1
echo error 1
goto :EOF

Running and saving command output using VBA

I am trying to run shell commands from VBA and get output into a csv file. Below is the code I am using:
Dim wsh as Object
Set wsh = VBA.CreateObject("WScript.Shell")
plink_path="C:\plink.exe"
key_path="putty key path"
pass_query="select * from test"
command1 = Replace(plink_path & " hadoop#11.11.11.11 -i " & key_path & " mysql -uuser -ppass -e 'use radar;" & pass_query & "'", Chr(10), " ")
wsh.Run command1 & ">E:/anurag.csv", 0, True
But I am not able to view output file in the E drive. When I run the above command manually from a cmd prompt I do get an output in the E drive.
Two thoughts:
Try E:\anurag.csv instead of E:/anurag.csv
Use cmd to invoke plink, since cmd usually processes the redirections. Replace the wsh.Run line with:
command1 = command1 & ">E:\anurag.csv"
command1 = "cmd /c """ & command1 & """"
wsh.Run command1, 0, True
The first line completes the command you wanted to execute and the second wraps it in a cmd /c call.
If this doesn't work, try changing /c above to /c /s per this answer.
YMMV - not tested

Excel VBA Shell command with spaces in file path

Public Sub openEntryFiles()
Dim filePath, shellCommand, agingsEntry, invenEntry As String
filePath = Range("CustomerPath").Value2 & "\files\"
agingsEntry = "agings\entry_EP.bat"
invenEntry = "inven\entry_EP.bat"
shellCommand = """%ProgramFiles(x86)%\TextPad 5\TextPad.exe"" -r -q -u """ & filePath & agingsEntry & """ -u """ & filePath & invenEntry & """"
Debug.Print shellCommand
Shell shellCommand, 0
End Sub
I am trying to write a subroutine that will run a shell command with spaces in the file path. I have done lots of research about using multiple quotes, but I still get a file not found error whenever I run the code. The debug print that is outputted to the Immediate window reads:
"%ProgramFiles(x86)%\TextPad 5\TextPad.exe" -r -q -u "\\ablsgaat002\aclwin\Clients\*****\files\agings\entry_EP.bat" -u "\\ablsgaat002\aclwin\Clients\*****\files\inven\entry_EP.bat"
Copying that string into a shell window works great, however, running it from the Shell command in VBA doesn't work. What am I doing wrong?
Use Environ function to get Special Folders
pathSpecial = Environ("ProgramFiles(x86)")
shellCommand = """" & pathSpecial & "\TextPad 5\TextPad.exe"" -r -q -u """ & filePath & agingsEntry & """ -u """ & filePath & invenEntry & """"

Argument issue when using vb.net shell ()

I was trying to use shell function in vb.net to run a program and then write/export the result else where , it works on win8 but not XP !! The command line prints this error
'C:\Documents' is not recognized as an internal or external command,
operable program or batch file.
Press any key to continue . . .
Dim save as String="C:\exported.txt"
Dim command As String = tempPath & "app.exe -f " & IO.Path.GetTempPath & " -o " & save & " & pause"
shell("cmd /c " & command, AppWinStyle.NormalFocus, True)
Process.Start(IO.Path.Combine(tempPath, "app.exe"), "-f """ & IO.Path.GetTempPath & """ -o """ & Save() & """ & pause")
You hace a folder in the command with a space in it (probably the documents and Settings folder). cmd.exe has no way of telling whether the space is in the file name or the end of the file name, unless you put the file name in "" - like "C:\doxuments and Settings..."
Dim command As String = tempPath & "app.exe -f \"" & IO.Path.GetTempPath & "\" -o \"" & save & "\" & pause"
(\" is intended to escape a " so that it translates to embedding a " in the string. I'm not sure what the VB syntax is.)
EDIT:
I think #Roy van der Velde below has the 'escaping correct. The final part not checked is tempPath. See my comment on the question.