Skip to content

Add server-side checksums - #83

Open
christhomas wants to merge 1 commit into
secsy:masterfrom
antimatter-studios:cth/checksums-upstream
Open

Add server-side checksums#83
christhomas wants to merge 1 commit into
secsy:masterfrom
antimatter-studios:cth/checksums-upstream

Conversation

@christhomas

Copy link
Copy Markdown

Implements #17.

The answer in the thread at the time was to Stat the file and compare sizes, with the acknowledgement that two files can share a size and differ. This is the thing that settles it.

algos, _ := c.ChecksumAlgorithms()    // ["SHA-512" "SHA-256" "SHA-1" "MD5" "CRC32"]
sum, _ := c.Checksum("file.bin", "")  // strongest available, lowercase hex

@fbrettnich mentioned proftpd's mod_digest in the thread, which is exactly what this talks to.

Two commands, and servers are split between them

HASH is standards-track and reports which algorithm it used. The older XCRC, XMD5, XSHA1, XSHA256, XSHA512 and MD5 each compute one thing. Both are read from FEAT, so a caller does not have to know which the server implements — algorithms are named as HASH names them (SHA-256) either way.

Three things decided here rather than passed along

Results are lowercase hex, whichever command answered. proftpd's HASH replies lowercase and its XSHA256 uppercase. A caller comparing against hex.EncodeToString would be right half the time, for reasons nothing in their code would explain.

An empty algorithm means the strongest available, ordered by collision resistance rather than speed. A caller who wanted speed would say so; one who did not is comparing files, and a CRC32 that matches is much weaker evidence than a SHA-256 that does.

Replies are read from their last line. Servers may prefix a progress line — Computing SHA-256 digest — so the first line is not the answer.

Tested against a server that computes them

proftpd with mod_digest. The assertion is that the server's SHA-256 equals what the file's bytes hash to locally — the property the feature exists for, not merely that a string came back. Every algorithm the server advertises is also checked to be computable, since one advertised and then refused is worse than one never mentioned.

pure-ftpd supports none of this and is in the same test run, so the "server computes no checksums" path is covered by a real server rather than a stub.

Loading mod_digest in the test server is part of the container work in #73, so it isn't in this branch — the tests here skip cleanly against a server without checksum support, which is what master's test servers are.

Implements secsy#17.

Two commands exist for this and servers are split between them. HASH is
the standards-track one and reports which algorithm it used; the older
XCRC, XMD5, XSHA1, XSHA256, XSHA512 and MD5 each compute one thing. Both
are read from FEAT, so a caller does not have to know which the server
implements — algorithms are named as HASH names them ("SHA-256") either
way.

Three things this decides rather than pass along:

Results are lowercase hex, whichever command answered. Servers are
inconsistent — proftpd's HASH replies lowercase and its XSHA256
uppercase — and a caller comparing against hex.EncodeToString would be
right half the time for reasons nothing in their code would explain.

An empty algorithm means the strongest available, ordered by collision
resistance rather than speed. A caller who wanted speed would say so; a
caller who did not is comparing files, and a CRC32 that matches is much
weaker evidence than a SHA-256 that does.

Replies are read from their last line, because servers may prefix a
progress line ("Computing SHA-256 digest").

Tested against proftpd with mod_digest loaded: the assertion is that the
server's SHA-256 equals what the file's bytes hash to locally, not merely
that a string came back. pure-ftpd supports none of this and is in the
same test run, so the "server computes no checksums" path is covered by a
real server rather than a stub.
@christhomas christhomas mentioned this pull request Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant