In honor of the late Robert Redford, "Sneakers", in high def ANSI with full subtitles:

ssh sneakers@ansi.rya.nc

(needs a terminal with 24 bit color support)

@ryanc okay this is rad
@Viss Main reason for SSH: Compression. The raw data rate is more than DVD video, lol.
@ryanc this is a super cool thing. is it a giant pain in the ass to setup?

@Viss

It's a work in progress, but a bunch of the code and scripts are on GitHub:

https://github.com/ryancdotorg/ansi-player-rs

https://github.com/ryancdotorg/ansiani

By far the most pain in the ass part is the subtitles.

ssh rickroll@ansi.rya.nc also works, btw

GitHub - ryancdotorg/ansi-player-rs

Contribute to ryancdotorg/ansi-player-rs development by creating an account on GitHub.

GitHub
@Viss The SSH thing is using russh and wasn't too hard in comparison.
@ryanc are you familiar with asciinema?
@esoterra Yes. I suspect this would be a bit of a torture test for it.
@Viss @ryanc adjacent to this in concept, you can run vlc in text-only mode too

@r0k @Viss @ryanc oh yeah, we used to run Quake through `aalib`

https://youtu.be/0nRPoS2WDJA?si=EAR1Kx2DFre0Mu2j

Text mode Quake II (hq)

YouTube
@Viss @ryanc If I had an ssh client 0day, this is how I’d deploy it 🙊
@schrotthaufen @Viss @ryanc you'd burn a zero day on robert redford fans?

@joshdelman @Viss @ryanc On hackers who enjoy nerdy shit like watching a really good hacker movie in a terminal over ssh? Absolutely.

Edit: And the payload would probably be some “wasteful” shit like adding rickrollrc to their bashrc.

@schrotthaufen @joshdelman @Viss @ryanc harvest what you can out of their forwarded agent...
@grimmy @schrotthaufen @joshdelman @Viss It's trivial to verify that I am not doing that.
@ryanc @schrotthaufen @joshdelman @Viss sorry, I wasn't suggesting that you were but that you could do to the design of ssh and people lazily enabling agent forwarding for everything and not thinking about it when connecting to random servers.l which is uncommon but primed for typo squatters.
@schrotthaufen @joshdelman @Viss ssh rickroll@ansi.rya.nc also works

@ryanc @schrotthaufen @joshdelman @Viss

goatsecx@ansi.rya.nc ?

@gregr @ryanc @schrotthaufen @joshdelman i was lucky enough to have viss.goatse.cx a million years ago. turns out i was one degree of separation away from the guy who owned the domain, and i took his job over when i took a sysadmin job in downtown san diego.

what a tiny, tiny, gross, stretchy world

@Viss @gregr @ryanc @schrotthaufen @joshdelman oh those were the days. I recall Myrlin had access to that, I too had a vhost linked up in ipv6
@ryanc Sneakers has been on my mind so often the last month! and yet, this post is how I learned he died.
@ryanc thank you for this 🙏
@ryanc I wonder why neither PuTTY, nor plink work here (the connection hangs at "Initialised zlib (RFC1950) decompression"; if I use regular ssh inside pterm, it plays).
@jernej__s I'm not sure, unfortunately. Will have a go at debugging later. Windows terminal should work.

@ryanc Yeah, it does, but it's extremely slow (much slower on my 9950X3D with Nvidia graphics than pterm running inside Xvnc session on my server; I tried both the modern Terminal and classic Console Host, both are slow).

Maybe I should ping @simontatham re PuTTY/plink.

@jernej__s @simontatham uncompressed, it's something like 1.5MB/sec of utf-8 and escape sequences, so...

@ryanc @jernej__s @simontatham
Eats ~65% CPU of a Core2 T5500 and ~500KiB/s.

Very nice, thanks!

@jernej__s @ryanc I confirm the hang. From a PuTTY packet log it looks as if we've just enabled encryption and sent the first encrypted packet, which is SSH2_MSG_SERVICE_REQUEST("ssh-userauth") as usual. The server sends SSH2_MSG_EXT_INFO, which probably crossed with SERVICE_REQUEST in the network, and then doesn't send any further packets. It should send SSH2_MSG_SERVICE_ACCEPT in reply.

I have to guess that the compression is something to do with it. The server is _only_ offering compressed SSH connections, not uncompressed ones, so PuTTY is forced to enable zlib compression even if you didn't turn it on in the client configuration.

There are some subtleties about how you break up a zlib stream across SSH packets, so perhaps PuTTY and the server disagree on one of those? But I might have to debug both ends in detail to decide which end is technically wrong.

The SSH server announces itself as 'hoopsnake', which hasn't come to my attention before, but a web search quickly found https://github.com/boinkor-net/hoopsnake which I presume is the same thing.

GitHub - boinkor-net/hoopsnake: A not-very-featureful SSH server for initrd that listens on your tailscale network

A not-very-featureful SSH server for initrd that listens on your tailscale network - boinkor-net/hoopsnake

GitHub
@simontatham Right, I've got compression disabled, though even enabling it doesn't help.
@ryanc mentioned russh here.
Ryan Castellucci :nonbinary_flag: (@ryanc@infosec.exchange)

@Viss@mastodon.social The SSH thing is using `russh` and wasn't too hard in comparison.

Infosec Exchange

@jernej__s @ryanc that's odd – if that server is running russh, how come its protocol greeting says "SSH-2.0-hoopsnake"? (You can confirm that by just connecting to ansi.rya.nc port 22 with something raw like nc or telnet.) It looks to me from the russh source code as if russh would be more likely to say "SSH-2.0-russh_0.54.3" or some such.

I think my previous hypothesis about subtleties in zlib encoding was wrong. I tried padding the compressed packet with lots of extra no-op data to make sure the server wasn't still waiting for the last couple of bits, and it made no difference.

But then I switched PuTTY to use the "zlib@openssh.com" delayed compression mode in preference to standardised "zlib", and it suddenly sprang into life. So my theory is that this is an SSH server bug where it just mishandles plain "zlib", probably because it's mostly been tested against OpenSSH which (not surprisingly) prefers its own modified version, and any testing against PuTTY was done without forcing compression on.

Unfortunately PuTTY doesn't (yet) have a config option to change the relative order of zlib and zlib@openssh.com, so there's no workaround built in for the bug yet. For my own test just now I had to hack the PuTTY source.

But until someone proves otherwise to me, my theory is that it's a server-side bug, triggered by a difference of PuTTY's and OpenSSH's legitimate protocol choices.

@simontatham @jernej__s

It's russh, I set the version string to say hoopsnake because it's funny:

let preferred = Preferred {
kex: vec![
kex::CURVE25519,
kex::CURVE25519_PRE_RFC_8731,
kex::ECDH_SHA2_NISTP256,
].into(),
cipher: vec![
cipher::CHACHA20_POLY1305,
cipher::AES_256_GCM,
cipher::AES_128_CTR,
cipher::AES_256_CTR,
].into(),
mac: vec![
mac::HMAC_SHA256_ETM,
mac::HMAC_SHA512_ETM,
mac::NONE,
].into(),
compression: vec![
compression::ZLIB,
compression::ZLIB_LEGACY,
].into(),
..Default::default()
};

let keys = vec![
load_key(&cli.key, Ed25519).await.unwrap(),
load_key(&cli.key, Ecdsa { curve: NistP256 }).await.unwrap(),
];

let config = Config {
server_id: SshId::Standard(String::from("SSH-2.0-hoopsnake")),
auth_rejection_time: Duration::ZERO,
auth_rejection_time_initial: Some(Duration::ZERO),
inactivity_timeout: Some(Duration::from_secs(8000)),
nodelay: true,
keys,
preferred,
..Default::default()
};

It's a riff of "dropbear" and apparently nothing is original on the internet.

You are correct that it's configured to only offer zlib compression - this is to conserve bandwidth as the uncompressed stream is rather large.

@ryanc it may have seemed funny, but if @jernej__s hadn't pointed me to your toot mentioning russh, I would probably have actually wasted a lot of my time source-diving in hoopsnake to try to track down the problem!

I guess if you removed ZLIB_LEGACY from the config list on your side this would start working, because that seems to be where the problem is.

@simontatham @jernej__s If I remove ZLIB_LEGACY, OpenSSH chokes and dies. 😠

@simontatham @jernej__s I could probably patch russh to detect putty and use plain ZLIB, but perhaps russh's implementation is buggy?

Apologies for the confusion as to the service, I've added russh_0.54.3 to the version string.

@ryanc @jernej__s yes, I'm now fully convinced that russh's implementation is buggy, and I think I understand what the bug is. I think russh simply didn't realise that "zlib" and "zlib@openssh.com" are different things, and it's implementing them as if both of them had the semantics of zlib@openssh.com.

I've raised https://github.com/Eugeny/russh/issues/564.

"zlib" compression incorrectly treated the same as "zlib@openssh.com" · Issue #564 · Eugeny/russh

User-visible problem If I compile and run the echoserver example program, and then attempt to connect to it using PuTTY with compression enabled, the connection hangs during setup. PuTTY's packet l...

GitHub
@simontatham @jernej__s thanks for that - I'll have to adjust my config meanwhile

@ryanc @jernej__s waaait. I've misunderstood what's going on in russh:

#[cfg(feature = "flate2")]
pub const ZLIB: Name = Name("zlib");
#[cfg(feature = "flate2")]
pub const ZLIB_LEGACY: Name = Name("zlib@openssh.com");

I had expected that ZLIB_LEGACY meant "zlib", not "zlib@openssh.com"! That's a very strange choice of internal identifier, because I think OpenSSH thinks that "zlib" is the legacy one and "zlib@openssh.com" is the preferred one.

In that case, try leaving _just_ ZLIB_LEGACY, instead of just ZLIB.

@simontatham @jernej__s I've changed that and recompiled.
@ryanc @jernej__s looks good, thanks! Now ansi.rya.nc is offering only zlib@openssh.com, so PuTTY negotiates that instead of zlib, and the movie starts playing happily.
@simontatham @ryanc Great live-debugging thread! 😉
@ryanc @jernej__s WSL2 on Windows 10 works nice and fast, if that helps.
@ryanc This is impressive, congrats.
@ryanc We need hackers <3
@f4grx Doable.

@f4grx

Wanna volunteer for subtitle formatting?

6.7G /sata/ryanc/ansi/hackers
8.6G /sata/ryanc/ansi/the_matrix
4.1G /sata/ryanc/ansi/wargames
@ryanc hmm what does the task look like?
@f4grx Quality control of the DVD subtitle OCR, positioning, and formatting. I have scripts that mostly automate this, but it needs a manual cleanup pass. Sneakers took me an afternoon, maybe?
@f4grx I have a python script that overlays the subtitles on a reference grid, etc
@ryanc very nice work. 👍
@ryanc I appreciate how the text in the credits never quite resolves itself into readable words. :)
@adamshostack I've actually considered putting letters there, but good to know folks like the vibe.

@ryanc I mean, it's sorta a perfect extension.

(Sorta perfect? WTF adam? 🤷 )