EmailDiscussions.com  

Go Back   EmailDiscussions.com > Email Service Provider-specific Forums > FastMail Forum
Register FAQ Members List Calendar Today's Posts
Stay in touch wirelessly

FastMail Forum All posts relating to FastMail.FM should go here: suggestions, comments, requests for help, complaints, technical issues etc.

Reply
 
Thread Tools
Old 1 Mar 2023, 08:13 PM   #1
qwertz123456
Essential Contributor
 
Join Date: Jan 2008
Posts: 378
[ Help needed ] Creating sieve script where recipient & sender email address is ident

As the title say, does anyone know how to do this? Or is this even possible?

I know the code below won't work and is incorrect, that's basically what I'm trying to achieve, matching any email where sender address = receipant address

Code:
if address ["X-Mail-from", "From", "Sender"]  matches address ["To"]
{
  reject "Mailbox does not exist";
  stop;
}
qwertz123456 is offline   Reply With Quote

Old 2 Mar 2023, 02:33 AM   #2
JeremyNicoll
Cornerstone of the Community
 
Join Date: Dec 2017
Location: Scotland
Posts: 684
I think it might be possible. If you look at RFC 5229, eg at https://datatracker.ietf.org/doc/rfc5229/ that describes how variables can be set.

I think you could extract the sender address and save it in one variable, and the recipient address and save it in another variable, and then test whether the two variable are equal to each other.

Assuming you already have some Sieve logic that's generated from rules defined in the FM rules dialogues, you should take a careful look at what that generated code actually does. Amongst other things it sets variables early on and later uses them when deciding where to route emails to. To test if a variable contains a particular value the generated code has eg:

if string :is "${processimip_outcome}" "added"

so I would hope that

if string :is "${abc}" "${def}"

would test if those two vars had the same value. But I don't know if that works...


If I were you I'd start by trying to set the two necessary variables. To find out if that's working properly I would then "addheader" their values into emails so that once Sieve has finished processing them you can look at those headers to see if the extracted values are exactly what you expected. An addheader instruction that I've used in the past was:

if header :contains "Subject" "this is just a sieve test" {
addheader "X-JN-Breadcrumb" "Inserted at start of headers by my sieve code";
addheader :last "X-JN-Breadcrumb" "Appended at end of headers by sieve test 23";
stop;
}

And of course that only happened when I sent a test mail whose subject contained what you'd expect. Note that in this case two headers got added to the mail, one before the initial "Return-Path:" header, and one after all of the other headers. They start "X-JN-" because my initials are J and N.

You absolutely definitely need to experiment only with test messages so that if you get this wrong it doesn't affect real messages!

I suspect that if you had set vars named myone and mytwo then

addheader "X-JN-experiment" "Var one:${myone}: and var two:${mytwo}:" ;

or something like it should work; you need the var values bookended (by colons here) so that you can see that the vars do or don't have leading/trailing spaces etc.
JeremyNicoll is online now   Reply With Quote
Old 2 Mar 2023, 11:23 AM   #3
n5bb
Intergalactic Postmaster
 
Join Date: May 2004
Location: Irving, Texas
Posts: 9,068
Arrow Using ME_FROM_EQ_TO

If you are trying to find messages where the From header is the same address as the To header and the message was sent to one of your account aliases (or the primary address), I would use the X-Spam-Hits ME_FROM_EQ_TO tag. This seems to be present only when FROM == TO and the message was delivered to you in TO. Here is some sample Sieve which I just tested:
Code:
 if header :contains ["X-Spam-Hits"] "ME_FROM_EQ_TO" {
  fileinto "INBOX.Test";
  stop;
}
If I send from an address I control at Fastmail (an alias at my own domain or a Fastmail domain I control) to that same address, this Sieve fragment delivers a copy to the Test folder.

If I send an email from my Gmail account to my own Gmail address and place one of my Fastmail aliases in the CC field, this Sieve fragment does not get activated. If I send from a Fastmail address to my Gmail address and put my Fastmail address in CC or BCC, this Sieve fragment does not get activate. So I believe the From address has to be one of your Fastmail aliases and that same Fastmail alias has to be in the To field.

Bill
n5bb is offline   Reply With Quote
Old 2 Mar 2023, 06:49 PM   #4
qwertz123456
Essential Contributor
 
Join Date: Jan 2008
Posts: 378
Thanks so much for the feedback. I forgot to mention that I intend to use this against spammers where the form and to address are identical.
qwertz123456 is offline   Reply With Quote
Old 3 Mar 2023, 12:02 AM   #5
hadaso
Intergalactic Postmaster
 
Join Date: Oct 2002
Location: Holon, Israel.
Posts: 5,113
I see lots of non-spam mail that has the same address in the from and to fields. It's common practice when people send mail and don't list the recipients (bcc) that the mail is addressed to self.
hadaso is offline   Reply With Quote
Old 3 Mar 2023, 01:17 AM   #6
n5bb
Intergalactic Postmaster
 
Join Date: May 2004
Location: Irving, Texas
Posts: 9,068
I agree that it’s a bad idea to consider such email as spam with a high likelihood. I also receive a lot of email with the TO == FROM, often with the recipients in BCC. The Fastmail spam system currently uses a score of 0.01 for that X-Spam-Hits header. But you could combine this with other indicators if it helps you.

Bill
n5bb is offline   Reply With Quote
Old 3 Mar 2023, 10:29 PM   #7
qwertz123456
Essential Contributor
 
Join Date: Jan 2008
Posts: 378
I'm aware of the risks, that's why I'm still testing it and have it file to the folder discard. I'm seeing a few email that I DO want so I'll have to play around with it more. Still trying to refine it so I gain an upper hand over the spammers...for maybe a few months
qwertz123456 is offline   Reply With Quote
Old 8 Mar 2023, 05:57 AM   #8
hadaso
Intergalactic Postmaster
 
Join Date: Oct 2002
Location: Holon, Israel.
Posts: 5,113
I wanted to test ChatGPT's coding ability, so I used the OP's problem.

I submitted this query:
Quote:
Please code using the Sieve language an email filtering rule that rejects an email message with the same email address in the "From" and "To" headers.
This was the answer:
Quote:
In Sieve language, you can implement an email filtering rule using the require statement and if block. To reject an email message with the same email address in the "From" and "To" headers, you can use the following code:
Code:
require ["envelope", "variables"];

if envelope :matches "from" "*" {
  set "from_addr" "${1}";
}

if envelope :matches "to" "*" {
  set "to_addr" "${1}";
}

if header :matches "from" "${from_addr}" {
  if header :matches "to" "${to_addr}" {
    reject "Emails with the same From and To address are not allowed.";
  }
}
Explanation:
  • The require statement includes the necessary Sieve extensions to access the email envelope and variables.
  • The first if block extracts the email address from the "From" header and sets it as a variable named "from_addr".
  • The second if block extracts the email address from the "To" header and sets it as a variable named "to_addr".
  • The third if block checks if the "From" header matches the "from_addr" variable and if the "To" header matches the "to_addr" variable. If both match, it means that the email has the same email address in both headers.
  • The reject statement rejects the email message with a custom message.
Note: This filtering rule assumes that the email headers are in RFC 5322 format, and the email address is enclosed in angle brackets ("<" and ">"). If your email headers have a different format, you may need to modify the code accordingly.
The code provided by the AI agent looks nice and tidy, and probably the syntax is correct. I haven't tested it but I believe this script would reject almost all email. this is because it does not compare the "From" header with the "To" header, but rather compares the envelope-form with the "From" header and the envelope-to with the "To" header, and these are almost always identical. So it seems that the script doesn't do what it was supposed to do (compare the "From" and "To" headers.

I tested ChatGPT previously with some math and it coped with trivial math and provided wrong answers with a bit more complicated things. It's really very much like a very self confident clueless college student.

But within the script provided I think there's enough info to try and corrct it to do the right thing, but first I tried to convince ChatGPT to correct it:
Quote:
It seems that the code you wrote does not do what it was intended to do: it compares the envelope-from address with the address in the "From" header, and it compares the envelope-to address with the address in the "To" header. It should have compared the address in the "From" header with the address (or addresses) in the "To" header. Please rewrite the code to work with he last comparison I described.
Quote:
You are correct, my apologies for the mistake in the previous code. Here's the corrected Sieve code to reject an email message with the same email address in the "From" and "To" headers:
Code:
require ["envelope", "variables"];

if header :matches "to" "*" {
  set "to_addr" "${1}";
}

if header :matches "from" "${to_addr}" {
  reject "Emails with the same From and To address are not allowed.";
}
Explanation:
  • The require statement includes the necessary Sieve extensions to access the email envelope and variables.
  • The first if block extracts the email address from the "To" header and sets it as a variable named "to_addr".
  • The second if block checks if the "From" header matches the "to_addr" variable. If it matches, it means that the email has the same email address in both headers.
  • The reject statement rejects the email message with a custom message.
Note: This filtering rule assumes that the email headers are in RFC 5322 format, and the email address is enclosed in angle brackets ("<" and ">"). If your email headers have a different format, you may need to modify the code accordingly.
This time the code seems much better and I guess it will work most of the time. It might fail to reject if the headers are not formatted exactly the same (e.g. one has only the email address and the other some display name) or if the "To" header has multiple recipient addresses. It depends also on how the :matches comparator works. I think Sieve has ways to extract only the email address for comparisons (and also to extract the domain and the localpart).

I haven't tested if the code works. I don't believe one can trust code ChatGPT produces as is, but it can save a lot of coding time by providing soething to work with, instead of coding from scratch.

Last edited by hadaso : 14 Mar 2023 at 02:30 AM. Reason: Added part of the conversation that I forgot to paste in (my second request from ChatGPT)
hadaso is offline   Reply With Quote
Old 8 Mar 2023, 09:23 AM   #9
Grhm
Essential Contributor
 
Join Date: Mar 2007
Location: UK
Posts: 283
I'm astonished by the matter-of-fact way you report this.
I studied computer science for a brief time back in the early eighties.
The efforts back then to create artificial intelligence were reassuringly hopeless, and I acquired the comforting conviction that the quest for AI was merely an interesting intellectual game, which could never amount to anything.
But... now this.
I'm a rationalist and a scientist, but things like ChatGPT and Midjourney terrify me, not because of what they do, as such, but because I genuinely can't believe that it is possible for such things to exist.
It's no exaggeration to say that the fact of their existence presents a fundamental challenge to my whole conception of reality.
I'd prefer not to hear about them.
Grhm is offline   Reply With Quote
Old 8 Mar 2023, 11:02 AM   #10
Grhm
Essential Contributor
 
Join Date: Mar 2007
Location: UK
Posts: 283
(Quantum computing is another impossible thing that nevertheless works, and which I would rather not know about).
Grhm is offline   Reply With Quote
Old 8 Mar 2023, 05:15 PM   #11
BritTim
The "e" in e-mail
 
Join Date: May 2003
Location: mostly in Thailand
Posts: 3,125
Quote:
Originally Posted by Grhm View Post
It's no exaggeration to say that the fact of their existence presents a fundamental challenge to my whole conception of reality.
I'd prefer not to hear about them.
In my view, the most important issue in the whole of human history is whether we are rapidly approaching the singularity where technology outgrows human capabilities, human control, and even the ability of humans to understand what is happening. It is frightening, but trying to ignore it is the worst thing we could do. It is my belief that the way technology develops over the next 20 years will determine whether we will emerge into a future where all our major problems are mitigated, or one where our species is destroyed.
BritTim is offline   Reply With Quote
Old 11 Mar 2023, 12:54 AM   #12
JeremyNicoll
Cornerstone of the Community
 
Join Date: Dec 2017
Location: Scotland
Posts: 684
I experimented with extracting parts of a TO address using the ":matches" command. I inserted the following block of code at the start of the Sieve definition, immediately after the "requires" that FM generate but before any of their subsequent code:

if header :contains "Subject" "this is just a sieve test" {
if header :matches "to" "*<*>*" {
set "to_try2_entireto" "${0}";
set "to_try2_beforebr" "${1}";
set "to_try2_insidebr" "${2}";
set "to_try2_afterbra" "${3}";
addheader "X-JN-Extracted" "Entireto is ]${to_try2_entireto}[";
addheader "X-JN-Extracted" "Beforebr is ]${to_try2_beforebr}[";
addheader "X-JN-Extracted" "Insidebr is ]${to_try2_insidebr}[";
addheader "X-JN-Extracted" "Afterbra is ]${to_try2_afterbra}[";
}
addflag "\\Flagged";
stop;
}


Its purpose is to show me (via added) headers precisely what the parsing of a TO header does when one supplies a pattern: "*<*>*", ie it hopefully allows for email addresses that may or may not have an initial name part and the actual email address enclosed in angle brackets.

I sent several test mails (all with Subject containing "this is just a sieve test") to myself (from outwith FM).

First a test mail that contained:

To: jn.1234@example.com

which - of course - arrived at FM without getting any of the extra headers added, because the :matches test didn't match, because that header did not contain "<" and ">".


Then, a test mail with a single name & address value in its TO header:

To: "Jeremy Nicoll (testing)" <jn.1234@example.com>

which did gain four new headers:

X-JN-Extracted: Entireto is ]"Jeremy Nicoll (testing)" <jn.1234@example.com>[

X-JN-Extracted: Beforebr is ]"Jeremy Nicoll (testing)" [

X-JN-Extracted: Insidebr is ]jn.1234@example.com[

X-JN-Extracted: Afterbra is ][

(note that they are placed in the email in the opposite order to what I've shown here because the first addheader command puts a new header at the very top of the email, then the next one at the very top (so above the one that just got added), and so on. But it's easier to see the entire-to, before-bracket, inside-brackets, and afterbracket parts shown here in a left-to-right order.


So far so good, but consider what happens if there's more than one address in the TO:

To: "Jeremy Nicoll (testing)" <jn.1234@example.com>, "Jeremy
Nicoll (fwds)" <jn.another@domain.com>

That test mail gained these headers:

X-JN-Extracted: Entireto is ]"Jeremy Nicoll (testing)"
<jn.1234@example.com>,
"Jeremy Nicoll (fwds)" <jn.another@domain.com>[

X-JN-Extracted: Beforebr is ]"Jeremy Nicoll (testing)" [

X-JN-Extracted: Insidebr is ]jn.1234@example.com[

X-JN-Extracted: Afterbra is ], "Jeremy Nicoll (fwds)" <jn.another@domain.com>[


and notice how unhelpful the "after-bracket" value is.


I think to develop logic that could cope with an arbitrary number of addresses in a TO header, and cope with the three most likely forms (bare single address, name & one address, more than one address in various combinations of format) would be quite tricky.
JeremyNicoll is online now   Reply With Quote
Old 11 Mar 2023, 07:06 PM   #13
xyzzy
Essential Contributor
 
Join Date: May 2018
Posts: 486
I'm late to this thread but I am trying to understand just where this thread is "going". FWIW if it's only to do tests on the "to", I always use X-Original-Delivered-to as follows:

Code:
if address :matches "X-Original-Delivered-to" "*" {  # X-Original-Delivered-to = actual addr
  set "orig_x_delivered_to" "${1}";
} elsif address :matches "X-Delivered-to" "*" {      # if X-Original-Delivered-to is missing
  set "orig_x_delivered_to" "${1}";                  # use X-Delivered-to if it exists
}
if not string :is "$(orig_x_delivered_to)" "" {
  if string :regex "${1}" "([^+]+)\\+(.+)@(.+)" {    # rewrite plus address as subdomain addr
    set "x_delivered_to" "${2}@${1}.${3}";           # a+x.y@b.c rewritten as x.y@a.b.c
  } else {
    set "x_delivered_to" "${orig_x_delivered_to}";
  }
}
Here my x_delivered_to is X-Original-Delivered-to if it is there or X-Delivered-to if it isn't (not sure if both could be missing but I ignore that case entirely -- never seen that happen in my email at least).

The code rewrites plus addresses as subdomain addresses for convenience. Now in places where I need to test the "to" I test my x_delivered_to instead. And in the place I check for from/to being the same address (I too have such a spam check for that) I match X-Spam-Known-Sender for the string "From == To". I guess I could have used the X-Spam-Hits ME_FROM_EQ_TO but I didn't know about that at the time I originally wrote the spam test.

Last edited by xyzzy : 11 Mar 2023 at 07:13 PM.
xyzzy is offline   Reply With Quote
Old 14 Mar 2023, 01:58 AM   #14
JeremyNicoll
Cornerstone of the Community
 
Join Date: Dec 2017
Location: Scotland
Posts: 684
The thread might not be going anywhere, but I'm learning something so it is useful to me.

I'm puzzled by that regex though. Why is there: 'backslash backslash plus' in it?

I would have thought that that meant: a literal backslash (escaped by the first one) followed by plus (ie the one or more times operator), which is to say: one or more literal backslashes.

What I expected to see there was: 'backslash plus' meaning a single literal (escaped) plus sign.


Unless something in the process of turning your quoted code into HTML for this forum altered its contents? That's why I've spelled out what I'm asking...

Last edited by JeremyNicoll : 14 Mar 2023 at 02:08 AM. Reason: corrected an idiotic mistake!
JeremyNicoll is online now   Reply With Quote
Old 14 Mar 2023, 04:34 AM   #15
xyzzy
Essential Contributor
 
Join Date: May 2018
Posts: 486
Quote:
Originally Posted by JeremyNicoll View Post
I'm puzzled by that regex though. Why is there: 'backslash backslash plus' in it?

I would have thought that that meant: a literal backslash (escaped by the first one) followed by plus (ie the one or more times operator), which is to say: one or more literal backslashes.

What I expected to see there was: 'backslash plus' meaning a single literal (escaped) plus sign.
I'm testing for plus addressing (one or more things after the right-most '+' in the local part by this definition). I need the first backslash to make sure the second backslash makes it through to the regex parser so that the '+' appears as a literal '+' character to regex to keep regex from treating it as one of it's own control characters -- "one or more" in this case.

In general the first backslash is "consumed" by the Sieve string scanner which passes what follows to the command. For plus-addressing I need to check for an actual '+' in the local part. Thus it needs the first escape to make sure regex sees the second escape in its argument string to keep it from interpreting it as "one or more".

It's not unlike the , for example, to fileinto the trash, i.e., fileinto "\\junk". The first slash makes sure the string "\junk" makes it through to a fileinto command.

Here's a simple regex example:

Code:
require ["fileinto", "regex", "variables", "editheader"];

set "test" "a+b";

if string :regex "${test}" "a\\+b" {
  addheader "test"  "matched";
} else {
  addheader "test"  "NOT matched";
}
If I didn't double slash the '+' that regex would be trying to match one or more 'a's followed by a 'b'.

By the way, mentioning the "\\junk" case reminds me a small error in FM's own boiler-plate Sieve code when asking it to check for X-Spam-score against a min spam score with a fractional part (section 3, Sieve generated for spam protection). For example, say you want specify to Spam Protection that email should be considered as spam for scores greater than 5.6. The generated Sieve code for this will be:

Code:
if anyof(header :value "gt" :comparator "i;ascii-numeric" "X-Spam-score" "5", header :regex "X-Spam-score" "^5\.[6-9]$") {
  fileinto "\\Junk";
  stop;
}
Note they don't double escape the decimal point in the "^5\.[6-9]$". They should but I never bothered to ticket this "nit" since FM is internally consistent with it generating a properly formatted X-Spam-score so it doesn't matter that the '.' in this case is not specifying matching a period but any single character instead which, of course will always be a '.' anyhow.

Last edited by xyzzy : 14 Mar 2023 at 04:39 AM.
xyzzy is offline   Reply With Quote
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump


All times are GMT +9. The time now is 04:48 AM.

 

Copyright EmailDiscussions.com 1998-2022. All Rights Reserved. Privacy Policy