Age | Commit message (Collapse) | Author |
|
this change broke the fix from 49d7ca8d92e5667f3e5ece4c6acbc1064701e2f8
|
|
|
|
when we send a return message, we need to wait for the
message to exit before we clean up the state files.
|
|
Hjfs reports "file locked" whilst cwfs reports "file is locked".
This whole approach is a bit crappy, but this change will get
us (me) by for now.
|
|
Doing so means these procs hang around after acme exits.
|
|
9front has several tests scattered throughout the source,
as well as more tests in an external 'regress' repository.
Many of these tests are broken, because there is no easy
way to build and track all of them.
This pulls in several tests from different sources, deletes
the broken tests, tests with missing data, and adds a single
command that can be run from the root of the src directory
to test our system.
The hope is that as we develop new code, we add more tests,
and eventually start running the tests on every commit.
Please enter the commit message for your changes. Lines starting
|
|
when sending messages, we do not merge headers, so
splitting headers the way we did leads to invalid
messages getting sent; stop doing it.
|
|
|
|
From: header)
|
|
The RFC says that the message separator line consists of
> a timestamp indicating the UTC date and time when the message
> was originally received, conformant with the syntax of the
> traditional UNIX 'ctime' output sans timezone (note that the
> use of UTC precludes the need for a timezone indicator);
It also references http://qmail.org/man/man5/mbox.html as an
authoritative source, which says the date "always contains exactly 24
characters in asctime format".
Add this date format for compatibility with tools using the standard
mbox format, in particular git format-patch.
|
|
The readmessage loop clears errstr at start and expects it not to
change unless there is a read error. However, strtotm may use
multiple calls to tmparse while trying to determine the date format,
which may leave errstr non-empty on success. Clear it after chkunix
so that this doesn't get treated as a message read error.
This also fixes handling of naked From lines, which were previously
just warned about, but since the conversion to tmparse they
accidentally triggered a message read failure.
|
|
We have to ensure the size we compute for memmove(...) in `Expunge` is
properly bounded. For certain combinations of inputs we compute an
illegal size causing a suicide:
upas/fs: imap: fetchrsp: fetchrsp: bad idx 7
upas/fs: user: igor; note: sys: trap: fault read addr=0x0 pc=0x214f92
fs 531: suicide: sys: trap: fault read addr=0x0 pc=0x214f92
Stack trace including state of data-structures:
term% acid -l /sys/src/cmd/upas/fs/imap.acid 531
/proc/531/text:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid: lstk()
memmove(p2=0x8e5928,n=0xffffffffffffffe8)+0x42 /sys/src/libc/amd64/memmove.s:36
imap4resp0(imap=0x423c80,mb=0x0,m=0x0)+0x448 /sys/src/cmd/upas/fs/imap.c:522
unexp=0x58b00000000
p=0x425d17
ep=0x425d17
line=0x425d0b
n=0x425d100000058c
verb=0x425d10
op=0x2e6d6f63
imap4resp()+0x1b /sys/src/cmd/upas/fs/imap.c:556
imap4read(imap=0x423c80,mb=0x4239e0)+0x30 /sys/src/cmd/upas/fs/imap.c:928
s=0x425d29
f=0x425d29
n=0x58b0000058c
ll=0x5008a34b0
i=0x425d290000058b
m=0x171bd1f85150e2a6
imap4sync(mb=0x4239e0)+0x62 /sys/src/cmd/upas/fs/imap.c:1059
imap=0x423c80
err=0x0
syncmbox(mb=0x4239e0,doplumb=0x70616d6900000001)+0x5c /sys/src/cmd/upas/fs/mbox.c:76
a=0x58f
n=0x400bc800000000
d=0x0
y=0x0
next=0x171bd206499a9366
m=0x66939a4906d21b17
reader()+0xde /sys/src/cmd/upas/fs/fs.c:1488
t=0x204ca163404153
mb=0x692e6d68656f622f
io()+0x212 /sys/src/cmd/upas/fs/fs.c:1416
n=0x0
main(argc=0x0,argv=0x7fffffffef58)+0x31e /sys/src/cmd/upas/fs/fs.c:353
mboxfile=0x7fffffffef7a
nodflt=0x300000000
srvpost=0x0
v=0x7fffffffef38
_argc=0x6d
_args=0x40d7bd
p=0x400000003
maildir=0x0
mbox=0x0
srvfile=0x0
_main+0x40 /sys/src/libc/amd64/main9.s:15
acid: Imap(0x423c80)
mbox 0x0000000000428b90
freep 0x0000000000423c20
host 0x0000000000423c27
user 0x0000000000423c36
refreshtime 60
cap 0x00
flags 0x05
tag 872
validity 605040277
newvalidity 605040277
nmsg 1419
size 0
f 0x00000000008dd408
nuid 1420
muid 1420
Biobuf bin {
Biobufhdr {
icount -28
ocount 0
rdline 16
runesize 0
state 1
fid 10
flag 0
offset 280380
bsize 8192
bbuf 0x0000000000423d35
ebuf 0x0000000000425d35
gbuf 0x0000000000425cd1
errorf 0x0000000000000000
iof 0x0000000000228d17
aux 0x0000000000000000
}
b end+0x388
}
Biobuf bout {
Biobufhdr {
icount 0
ocount -8192
rdline 0
runesize 0
state 2
fid 10
flag 0
offset 33362
bsize 8192
bbuf 0x0000000000425d9d
ebuf 0x0000000000427d9d
gbuf 0x0000000000427d9d
errorf 0x0000000000000000
iof 0x0000000000228d3a
aux 0x0000000000000000
}
b 0x425d98
}
binit 1
fd 10
The root cause is an integer underflow where we subtract -1 from 0
using an unsigned type.
The above acid trace shows the following values for key local variables:
• nmsg ... 1419
• muid ... 1420
• n ... 1420
• idx ... 1419
The key section of code is /sys/src/cmd/upas/fs/imap.c:516,522
case Expunge:
if(n < 1 || n > imap->muid){
snprint(error, sizeof(error), "bad expunge %d (nmsg %d)", n, imap->nuid);
return error;
}
idx = n - 1;
memmove(&imap->f[idx], &imap->f[idx + 1], (imap->nmsg - idx - 1)*sizeof(imap->f[0]));
Plugging the above values into the call to memmove(...) demonstrates the
issue:
memmove(&imap->f[1419], &imap->f[1419 + 1], (1419 - 1419 - 1)*sizeof(imap->f[0]));
^^^^^^^^^^^^^^^
The third argument of memmove(...) is an unsigned size type causing
the size to be a value that is way too large (the stack trace shows
the size to be the unsigned value 0xffffffffffffffe8).
The `Expunge` case can be fixed by amending the bounds checking
condition before the memmove(...):
case Expunge:
if(n < 1 || n > imap->muid || (n - 1) >= imap->nmsg){
^^^^^^^^^^^^^^^^^^^^^
snprint(error, sizeof(error), "bad expunge %d (nmsg %d)", n, imap->nuid);
return error;
}
idx = n - 1;
memmove(&imap->f[idx], &imap->f[idx + 1], (imap->nmsg - idx - 1)*sizeof(imap->f[0]));
To add some additional context, this issue has been introduced in
revision:
term% git/export 84c4c81ceecfa8f51949787fc2dbe7b14164a353
Date: Mon, 02 Dec 2019 01:12:19 +0000
Subject: [PATCH] upas/fs imap fixes and improvements
do incremental imap fetches after startup, fixes validity handling,
record flags correctly when we aren't in the process of directly
updating a message, fixes off by one in flag parsing, fixes
mis-indexing messages in sync when we get an unsolicited fetch
response.
...
|
|
This change adds support for dkim signing to upas.
It has2 pieces:
1. Adding support for different asn1 formats to auth/rsa2asn1;
we can now generate SubjectPublicKeyInfo RSA keys, which
wrap the keys up with an algorithm identifier.
2. Adding a upas/dkim command which filters a message and signs
it using dkim.
To configure dkim, you need to generate a (small-ish) rsa key;
large keys do not fit into DNS text records:
# generate the private key and add it to factotum
ramfs -p
cd /tmp
auth/rsagen -b 2048 -t 'service=dkim role=sign hash=sha256 domain=orib.dev owner=*' > dkim.key
cat dkim.key > factotum.ctl
# extract the public key, encode it, and strip out the junk
pubkey=`{
<dkim.key auth/rsa2asn1 -f spki | \
auth/pemencode WHATEVER | \
grep -v 'WHATEVER' | \
ssam 'x/\n/d'
}
domain=example.org
# then add it to /lib/ndb.local
echo 'dom=dkim._domainkey.'$domain' soa=
ip=144.202.1.203
refresh=600 ttl=600
ns=ns.orib.dev
txt="k=rsa; v='$pubkey \
>> /lib/ndb/local
Then, finally, insert it into your outgoing mail pipeline. One
thing to be careful of is that upas will do some outgoing 'From:'
rewriting, so you may need to make sure that either '$upasname'
is set, or 'upas/dkim' is inserted after the rewrite stage.
A good place is in /mail/lib/qmail, in place of upas/vf:
% cat /mail/lib/qmail
rfork s
upas/dkim -d example.com | upas/qer /mail/queue mail $* || exit 'qer failed'
upas/runq -n 10 /mail/queue /mail/lib/remotemail </dev/null >/dev/null >[2=1] &
|
|
|
|
An attacker may use an infinite number of SPF referrals in his/her SPF
setting and can send an email to your mail server which would make
your SMTP server make a lot of DNS queries. By exploiting this
vulnerability, an attacker can block your SMTP queue, flood the
associated recursive resolver, or any DNS authoritative server.
According to RFC recommendations
(https://datatracker.ietf.org/doc/html/rfc7208#section-4.6), a few DNS
lookup limits exist that an SMTP server needs to maintain while
resolving an SPF record. That is, SPF implementations MUST limit the
total number of query-causing terms to 10 and the number of void
lookups to 2 to avoid unreasonable load on the DNS.
from:
Taejoong “Tijay” Chung (tijay@vt.edu)
Ishtiaq Ashiq (iashiq5@vt.edu)
|
|
|
|
Noticed while doing some debugging.
|
|
|
|
|
|
|
|
In showlist, call bwindata instead of bwinopen in order to use a
pre-existing fd to write to the data file. This existing fd will
properly honour any address set by a previous write to the addr file.
Specifically, the redraw function sets addr to "," before calling
showlist in order to overwrite the entire contents of the window.
|
|
They happen, and we break the cycle. There's nothing
the user can do, so there's no point in warning.
|
|
changeset: 8411:19f6a88ea241
branch: mbp-2011
user: Romano <unobe@cpan.org>
date: Sat Apr 17 14:35:21 2021 -0700
files: sys/src/cmd/upas/fs/imap.c
description:
When an imap fetch fails, it's helpful at times to know the underlying
cause. This provides more details by providing the underlying error
message.
|
|
Setting headers from Mail can cause conflicts
with the headers that upas/marshal adds when
sending attachments.
So, let's not set them.
|
|
We forgot to update the message count when deleting
messages in mail, meaning we could access trailing
messages that had been freed.
|
|
Mutating lists that are being iterated is needlessly error
prone, and we were removing the wrong message in some cases
if it the dummy got inserted in the right place.
Separating deletion into a redraw/relink and zap phase
simplifies the problem.
|
|
|
|
When deleting messages that came in just
the right order, we would end up stuck in
a loop deleting and reinserting a dummy
parent, rather than the messages we wanted
to remove.
|
|
|
|
Oops.
|
|
User is the upasname, and is unlikely to exist when we save
the message to the outbox. We should use the login name instead.
|
|
When the save folder did not exist, and we could not create
it, we would handle up to one Biobuf worth of message, and
then fail, due to a failed tee. The sequence of events leading
up to this was:
openfolder() -> error
tee(0, fd, -1) -> wait for read
write(0, data) ->
write(fd, data) -> ok
write(-1, data) -> error, tee terminates
write(0, attachment) -> error
This change prevents us from writing to a closed fd, and
therefore from erroring out when sending.
We also warn the user.
|
|
validateattachment has no business with the mime boundary; it is not
part of the attachment itself.
Also, it causes the boundary to be dropped in the message output from
upas/vf, effectively dropping the following attachment (though the
content is still present after the last boundary of the wrapped first
attachment part).
Consider the following sequence of events:
1. upas/vf is run on a message containing two attachments.
2. The first attachment does not have a known extension, so is saved
to a temporary file *including* the following mime boundary.
3. This file is opened as p->tmpbuf, which is used for subsequent
reads until switching back to stdin.
4. The attachment fails validateattachment, so upas/vf wraps it in a
multipart with a warning message.
5. problemchild() calls passbody(p, 0), which copies from p->tmpbuf
until it hits the outer boundary line, which it excludes, seeks
back one line, then returns the outer multipart.
6. problemchild() then writes its own boundary, and then copies one
line from *stdin* to stdout, expecting the outer boundary.
However, this boundary was already read from stdin in 2, so it ends
up reading the first line of the subsequent part instead.
To fix this, pass 0 to passbody() in save() to exclude it from the
attachment file and make it available in stdin when expected.
|
|
Reading nested subparts of messages into the root
message array allows deeply nested multipart trees
of messages to show correctly in the message view.
|
|
These messages aren't useful and were presumably left over from
someone debugging this code.
|
|
upas/vf was converted to use tmdate, but the formatter was never
installed. This caused it to send attachments to validateattachment
with header `From virusfilter %τ%`, which always failed since upas/fs
would just skip over the message.
|
|
Despite pervious efforts, mk clean still doesn't remove libcommon.a*
files from cmd/upas/common/. To fix this, let's tell cmd/mklib to do
the job instead.
|
|
Runq spawns a number of processes, and wait()s for them
in 2 different places. Because of the way that the exit
handling is done, the wait can get the wrong message.
It turns out that only one place in the code needs to
wait for the child, and in all other cases, it's just
muddling the problem.
This change adds the RFNOWAIT call to all the processes
we don't need to wait for, so that the places that do
need wait will always get the correct child.
|
|
When message flags change, Mail would clear all the flags and
recompute them. This would clobber internal flags like Ftodel.
So, don't do that.
|
|
|
|
Acme mail made it hard to do threading, so I wrote a new one.
|
|
With ntlm auth, we were trying to set 0 bytes of
the auth struct to its size. The args were clearly
swapped. Fix it.
While we're here, remove some dead code.
|
|
one slipped in to the last commit.
|
|
Turns out -a is useful in crontab, so bring
back a simplified version of it. This only
iterates through directories one at a time.
|
|
When running a mail queue, it's useful to run it with limited
parallelism. This helps mailing lists process messages in a
reasonable time.
At the same time, we can remove the load balancing from runq,
since the kinds of systems that this matters on no longer
exist, and running multiple queues at once can be better
done through xargs.
|
|
Global variables deserve more greppable names,
since I'm likely to know where they're used.
|
|
|
|
|
|
Fixes 3 issues in our upas mkfiles:
- mk/mkfile and send/mkfile were rebuilding
only the rfc822.tab.$O, even though the
header also needed to be rebuilt.
- CLEANFILES had a pattern that would not
get expanded.
- Third, ../upas/mkfile was being included
in the wrong place and making the wrong
rule default.
|
|
When consolidating the duplicated targets, the
one that actually got built ended up arbitrary.
Put in a 'default' target that runs 'mk all'.
|