How to close IMAP APPEND command from a openssl connection - macos

I would like to know how to close an APPEND command from the Unix Terminal. My goal is to create a Draft message on the Gmail IMAP server from the Mac Terminal or with JavaME. I've used the follow commands so far:
openssl s_client -crlf -connect imap.gmail.com:993
...
A1 LOGIN myaccount#gmail.com mypassword
...
A2 SELECT "[Gmail]/Drafts"
...
A3 APPEND "[Gmail]/Drafts" (\Seen) {310}
+ go ahead
Date: Fri, 29 Apr 2011 10:00:00 -0800 (PST)
...
Content-Type: TEXT-PLAIN; CHARSET=US-ASCII
Message Body
I tried to send a CRLF (\r\n) by using a socket connection and the Control+V, return, return in the Terminal.

{310} is the exactly number of message characters, including the carriage return and line feed, it worked fine.

Related

How can I verify an HTTP HMAC Signature in Bash?

I'm needing to verify an HTTP HMAC signature for a program I use (Drone CI, trying to create an extension), but nothing I'm trying is getting the results to match.
Specifically, the HTTP request looks like this:
POST / HTTP/1.1
Host: 127.0.0.1
User-Agent: Go-http-client/1.1
Content-Length: 50
Accept: application/vnd.drone.validate.v1+json
Accept-Encoding: identity
Content-Type: application/json
Date: Wed, 09 Jun 2021 01:25:07 GMT
Digest: SHA-256=digest
Signature: keyId="hmac-key",algorithm="hmac-sha256",signature="signature",headers="accept accept-encoding content-type date digest"
{"data":"data"}
I've tried messing around with sha256sum, hmac256, and openssl, swapping the values of Digest and signature, but none of them are making anything match.
Update:
I've tried the following code, but it still doesn't seem to be working:
MESSAGE='{"data":"data"}'
SECRET="secret" # This isn't any value in the request, is it?
echo -n "${MESSAGE}" | openssl dgst -sha256 -hmac "${SECRET}" | base64 -w 0
Update 2:
The HMAC examples on Wikipedia are working just fine for me. Is there something I might be messing up from the HTTP request?
If it's worth anything, the request signing is apparently based on draft-cavage-http-signatures-10.
Update 3:
I've attempted to create the signature with the following format, still no dice though:
{"data":"data"}
accept: application/vnd.drone.validate.v1+json
accept-encoding: identity
content-type: application/json
date: Wed, 09 Jun 2021 01:25:07 GMT
digest: SHA-256=digest
Assuming the above text is stored under the variable ${hmac_data}, the following was used to attempt (but failed) to reach the value of signature:
echo -n "${hmac_data}" | openssl dgst -sha256 -hmac "${key}" | awk '{print $2}' | base64 -w 0
Update 4:
After a crud ton of messing around, Kiskae's answer got me to a solution.
In addition to what he said, I found that Drone base64 encodes the binary version of the string, rather than the ASCII one.
So, the new version of the above command (when using with Drone CI) would be the following:
${MESSAGE} is equal to the following:
accept: application/vnd.drone.validate.v1+json
accept-encoding: identity
content-type: application/json
date: Wed, 09 Jun 2021 01:25:07 GMT
digest: SHA-256=digest
And the command:
echo -n "${MESSAGE}" | openssl dgst -sha256 -hmac "${SECRET}" -binary | base64 -w 0
They appear to be using an implementation of the http signatures draft.
The linked document explains the way the signature needs to be calculated and how to verify it. But this is probably why your example doesn't work:
2.1.3. headers
OPTIONAL. The headers parameter is used to specify the list of
HTTP headers included when generating the signature for the message.
Basically the signature doesn't include just the message, probably to prevent replay attacks. Since you just hash the message it is working as intended.

AMP update-cache resulting in 404 or 410 error from origin

I've been trying to update the AMP cached pages on my website for a couple of days now to no avail.
While the documentation for updating the cache exists, it was probably written by a Google engineer, and as a result, isn't the easiest read.
https://developers.google.com/amp/cache/update-cache
I've followed the directions to the best of my ability.
I've created a private-key and public-key. Created a signature.bin and verified it using the procedure in Google's own documentation.
~$ openssl dgst -sha256 -signature signature.bin -verify
public-key.pem url.txt
Verified OK
The public-key.pem has been renamed to apikey.pub and uploaded to the following directory:
https://irecover.ca/.well-known/amphtml/apikey.pub
To validate that there has been no issue in the copying, I checked the signature using the following:
$ openssl dgst -sha256 -signature signature.bin -verify <(curl https://irecover.ca/.well-known/amphtml/apikey.pub) url.txt
% Total % Received % Xferd Average Speed Time Time Time
Current
Dload Upload Total Spent Left Speed
100 450 100 450 0 0 2653 0 --:--:-- --:--:--
--:--:-- 2662
Verified OK
Now I convert the signature file to base64 and replace the / with _ and the + with -
cat signature.bin | base64 > signature.b64
sed 's///_/g' signature.b64 > signature.b64a
sed 's/+/-/g' signature.b64a > signature.b64b
sed 's/=//g' signature.b64b > signature.b64c
cat signature.b64c | tr -d '\n' > signature.b64
I have made a script that makes the update-cache url for me. It also creates a timestamp right that moment and uses it for the amp_ts variable (So the amp_ts is never out by more than 1 second). I then append that to the end of the query which is about to be cURL'd by the script I have made, so it looks like so:
https://irecover-ca.cdn.ampproject.org/update-cache/c/s/irecover.ca/article?amp_action=flush&amp_ts=1581446499&amp_url_signature=KDaKbX0AbVbllwkTpDMFPOsFCRNw2sbk6Vd552bbG3u5QrecEmQ1SoMzmMR7iSXinO7LfM2bRCgJ1aD4y2cCayzrQuICrGz6b_PH7gKpo6tqETz06WmVeiP89xh_pBOu-pyN5rRHf0Pbu8oRkD2lRqgnGrLXDfIrFTTMRmHlO0bsa8GknyXL8RNXxk9ZQaufXAz-UJpoKaZBvT6hJWREAzxoZ-rGnDPVaC3nlBCu3yPorFcTbbr0CBz2svbfGgAYLQl54lLQmUpxI8661AEe1rdOLqAyLIUb4ZiSbO65-PmIkdZWVPFHMdbpSv4GMNdvodleCWBfMAcG2C09v-LR6g
However, this always results in the same error code from google.
Invalid public key due to ingestion error: 404 or 410 error from origin
Does anyone have any idea what I'm doing wrong?
A couple of things to check for apikey.pub accessibility:
The /.well-known/amphtml/apikey.pub file is accessible to both mobile and desktop user agents (e.g no redirect for non-mobile as the AMP cache client may redirect)
The public key is not excluded in robots.txt e.g:
User-agent: *
Allow: /.well-known/amphtml/apikey.pub
The public key response has the expected headers (e.g content-type: text/plain):
curl -I https://amp.example.com/.well-known/amphtml/apikey.pub
HTTP/2 200
date: Sun, 26 Jul 2020 23:48:55 GMT
content-type: text/plain
vary: Accept-Encoding
etag: W/"1c3-173478a8840"
last-modified: Sun, 26 Jul 2020 23:48:55 GMT
With those things in place, I get an "OK" success response from the update/cache endpoint

Unknown characters within subject line of mail app in unix terminal

I've set up the mail app and created a shell script to FTP to a website server and then send an email to the admin. Last night it was working perfectly. I made changes to it this morning and it started sending two of the same email with different ASCII characters within the subject line.
#Send an email confirming update
cat /Users/rmdlp/Documents/Scripts/message.txt | mail -s “Website Update” myemail#myemail.ca
Here is a snippet of the email subject I receive:
Everything else works fine. The "message.txt" file is within the body of the message and it gets to my email OK.
Also in the sender's list this string is being added:
I also receive a "You have mail in /var/mail/$USER", which I did not receive before. I looked at that file and this is a portion of what it outputs:
Diagnostic-Code: X-Postfix; unknown user: "update???"
--9490A103F482.1450820767/Roys-MBP.lan
Content-Description: Undelivered Message
Content-Type: message/rfc822
Return-Path: <rmdlp#Roys-MBP.lan>
Received: by Roys-MBP.lan (Postfix, from userid 501)
id 9490A103F482; Tue, 22 Dec 2015 16:46:05 -0500 (EST)
To: rmdlp#live.ca, Update”#Roys-MBP.lan
Subject: “Website
Message-Id: <20151222214605.9490A103F482#Roys-MBP.lan>
Date: Tue, 22 Dec 2015 16:46:05 -0500 (EST)
From: rmdlp#Roys-MBP.lan (Roy Perez)
The command mail -s “Website Update” is not doing what you think it does. “ is U+201C, LEFT DOUBLE QUOTATION MARK, which is not the same thing as ". Unlike ", “ is not treated specially by the shell, and so the command gets split up at the whitespace in Website Update, resulting in a subject of “Website and an extra recipient of Update”. This extra recipient is interpreted as Update”#<YOUR HOSTNAME>, but because there is no such user, the email to it gets bounced back and ends up in your mailbox. All the "unknown characters" along the way are due to encoding issues.
This is why you use plain text editors to write code, not word processors.

Mail sending with shell Scipt is not working

I need to send a mail regarding deployment of an application using shell script.
For this I have just created a shell script and tested with
#!/bin/bash
TO_ADDRESS="to.person#domain.com"
FROM_ADDRESS="from.me#domain.com"
SUBJECT="Test mail"
BODY="hai friend, this mail is automated from shell script for Release automation."
echo ${BODY}| mail -s ${SUBJECT} ${TO_ADDRESS} -- -r ${FROM_ADDRESS}
But while running this script, it is printing like:
You have new mail in /var/spool/mail/jaykay
And a file named jaykay is created in /var/spool/mail/
Why this is happening?
How can I send a mail using shell script?
And the output file looks like
From jaykay Wed Aug 20 04:08:53 2014
Return-Path: <jaykay>
Received: (from jaykay#localhost)
by e7021.com (8.14.4/8.14.4/Submit) id s7K98rdu004168;
Wed, 20 Aug 2014 04:08:53 -0500
From: Jini K Johny <jaykay>
Message-Id: <201408200908.s7K98rdu004168#e7021.com>
Date: Wed, 20 Aug 2014 04:08:53 -0500
To: to.person#domain.com, -r, --, from.me#domain.com
Subject: Test mail
User-Agent: Heirloom mailx 12.4 7/29/08
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
hai friend, this mail is automated from shell script for Release automation.
Your fundamental problem is that you must use proper quoting. This is basically a duplicate of a question which gets asked here every day.
Without quotes, the second token in $SUBJECT is interpreted as the address to send to.
An email is submitted for delivery to mail (the second word in "Test mail").
The address is undeliverable, so you get a bounce message.
The bounce message is delivered to your inbox.
Your shell notifies you that your inbox has a new message.
Additionally, it seems that your version of mail does not understand the -- option, so it gets taken as just one more address to send to. (You would get a bounce message from that, I suppose.) Because the -r option is also interpreted as just another address to send to, you get one copy (like a Bcc:) of the outgoing message in the mailbox you tried to specify in the $FROM_ADDRESS.
The fix, of course, is easy:
#!/bin/bash
TO_ADDRESS="to.person#domain.com"
FROM_ADDRESS="from.me#domain.com"
SUBJECT="Test mail"
BODY="hai friend, this mail is automated from shell script for Release automation."
echo "${BODY}" | mail -s "${SUBJECT}" "${TO_ADDRESS}" # -- -r "${FROM_ADDRESS}"
(The curlies aren't really necessary here, but I kept them since you had them in your code.)
E.g. this recent answer has guidance for when and how exactly you need to quote.
The mail program is really a rather thin wrapper; you could do something like this instead;
/usr/lib/sendmail -oi -t -f "$FROM_ADDRESS" <<____HERE
From: My Name <$FROM_ADDRESS>
To: Your Name <$TO_ADDRESS>
Subject: $SUBJECT
$BODY
____HERE
... where the path to /usr/lib/sendmail is likely to be something else on many systems.
(For bonus k00lness points, add X-Mailer: Look, I can put anything I like here!)
I'm guessing here that you meant sendmail -f "$FROM_ADDRESS" which sets the envelope sender address (not -r which I cannot find documented anywhere).

Mute HTTP headers with openssl s_client

I have a one line bash command which gets me an HTML site over an SSL encrypted HTTPS connection:
echo "GET / HTTP/1.1\nHost: www.example.com\n\n" | openssl s_client -connect www.example.com:443 -quiet 2> /dev/null
The site is being loaded but with HTTP headers like:
HTTP/1.1 200 OK
Date: Fri, 01 Feb 2013 13:15:59 GMT
Server: Apache/2.2.20 (Ubuntu)
and more like this. With 2> /dev/null I can hide the output of wrong SSL certificates and more.
I do not want to take another script because curl does not what I want to do.
It is not possible due to the nature of openssl s_client which gives you the direct and plain output from a service which runs behind the connecting port (443 in my example from the question where I want to get / on a webserver with SSL).
telnet would also give you the plain output from the HTTP protocol and curl would show me the HTML site without headers and with HTTPS but does not allow self written commands to the web server.
You may use expect command to do the interaction with openssl. I'm not sure it will work but it worth a try.

Resources