Saturday, October 8, 2022

Going where BeOS NetPositive hasn't gone before: NetPositive+

BeOS browser:
TLS apocalypse
Won't keep it off line.

(How do you pronounce BeOS?)

This is a real 133MHz BeBox running otherwise stock BeOS R5, surfing Hacker News and using a modified, bug-fixed NetPositive wired to offload encryption to an onboard copy of Crypto Ancienne (see my notes on the BeOS port). NetPositive is the only known browser on the PowerPC ports of BeOS — it's probably possible to compile Lynx 2.8.x with BeOS CodeWarrior, but I've only seen it built for Intel, and Mozilla and Opera were definitely Intel/BONE-only. With hacks for self-hosted TLS bolted on, NetPositive's not fast but it works, and supports up to TLS 1.2 currently due to BeOS stack limitations.

If you use another system to host the carl tool, it's faster and you get TLS 1.3, shown here talking to my local NetBSD/macppc proxy server running carl via inetd:

And here's the Haiku home page accessed on a Power Mac running R5.0.3, also with self-hosted crypto:
Sadly I got the kiss-off of death from Cloudflare trying to access OSnews (it does work with naked carl from the command line, so it must be objecting to the NetPositive user agent despite its long history of BeOS reporting), but you can see the connection was at least attempted:
Before we continue, something for the lawyers. This is an unofficial and unauthorized hack of NetPositive, currently the intellectual property of ACCESS Co. Ltd. through their 2005 purchase of PalmSource, who purchased the rights to BeOS after Be's demise in 2001. ACCESS has not authorized any release or update of BeOS or any BeOS system component. This modification contains copyrighted code and resources, is not for sale or rental, would be only be of significant interest to a relatively small group of people, and we're all weird anyway. Please don't sue weird people! We love all your products, probably!

Also, why no Intel? Simply because there's Haiku, which has BeOS compatibility and is better in every way, including multiple browser choices and some that are even vaguely current. This project is for the underloved PowerPC side of the house, because I'm a Power ISA bigot and this is how I roll. It will work on any PPC BeBox (if someone runs this on a 66MHz system I will be impressed) and of course on any Power Mac compatible with BeOS.

Anyway, let's talk about the changes. NetPositive+ (get it? Net++? get it??) is a reworked alteration of 3.0d3, the last NetPositive release. This was a beta version of the browser that added an ad filter and, more importantly, JavaScript. Unlike NetPositive's core layout engine which was entirely written at Be, the JavaScript interpreter was a third-party product called ScriptEase licensed from Nombas, Inc. Nombas ceased to, um, be around the same time as Be in 2001, but they actually sold the company to Openwave, which used it in products of their own.

(Tangent: does the name Nombas sound oddly familiar to you, especially if you're an astronomy geek? It should: it's the JavaScript engine in the James Webb Space Telescope. Which is also PowerPC! How's that for some weird nerdy coincidences!)

Unfortunately, the integration of ScriptEase into NetPositive was crashtastic (I'll politely refrain from assigning fault) and it doesn't work hardly at all with modern sites even when it doesn't blow up, so I stripped it out along with the ad filter since it had various problems not immediately worth solving; perhaps a quest for later. Since that essentially makes it equivalent with 2.2.2, the last non-beta release, I altered the resources to make it version "2.3."

The main modification was to mangle its proxy support to send HTTPS requests over HTTP, which is the core mechanic Crypto Ancienne uses in proxy mode. This turned out to be less complex than modifying Classilla to do the same, because unlike most early SSL browsers that use the CONNECT method to tunnel a socket through the proxy, what NetPositive actually does with HTTPS sites is connect to the proxy over SSL and make a regular proxy request. All I needed to do was force it to make the same connection on an unencrypted port. (Note that this short-circuits the internal SSL support somewhat, though since it's limited to SSLv3 this should be of little consequence with modern servers.)

Naturally this successful modification then unmasked other bugs in the browser. My first draft worked on many sites but a number of them would instead download the HTML source to disk with the MIME type of nosniff. This comes from a serious bug in how headers are parsed; the search for the string Content-type — among others — will actually match anywhere in a header, including X-Content-Type-Options: nosniff, which then overrides the actual MIME type. This is now fixed (I think).

With that patched, though, while more sites would load some would just sit and hang until some timeout was reached (Hacker News was one). After some fruitless mucking around in layout I eventually traced this to gaps in its HTTP protocol support, which was mostly but not quite completely RFC-compliant and wasn't sending correct headers (also fixed, I think). As a finishing touch for this go-around, I made a new about resource (and fixed the link to the plugins list page, which is invariably blank) and linked in some new code to support &#x...; entities, since this just looked nicer on most web pages.

Okay, okay, you have a BeBox (or a compatible Power Mac running BeOS) and you want to try it out. Here's the steps.

  • First, download the NetPositive+ binary from the Be-Power repository on the Floodgap gopher server and unzip it, and place it anywhere convenient. Its presence will not interfere with your existing NetPositive 2.2 or 3.0d3 installation. Yes, I know that there isn't a gopher client on BeOS ... yet! Just copy it over to your system (good old FTP is simplest).

  • Second, decide if you want to run carl on a separate host or run it locally. You should be warned that running it self-hosted is slower and currently glitchy. Not crash-your-machine glitchy, but it's already known that Crypto Ancienne pushes classic BeOS to its limits and you will get occasionally mangled pages or timeouts, especially on slower systems. Additionally, TLS 1.3 is not currently supported if you run local.

    • So let's first say you want to run it on a separate host for speed. In that case, clone and compile it from the Crypto Ancienne github on the desired host (for most systems this is as simple as cc -O3 -o carl carl.c or something similar, substitute gcc or clang as appropriate), then set up your local inetd or inetd-equivalent to run it with the -p (for proxy mode) option on a desired port (my convention is port 8765, though if you're still running Ultraseek, pick something else). In NetPositive+, go to the Preferences window, select the Connections tab, check "Enable proxies" and put the hostname and port 8765 into the fields. Both HTTP and HTTPS requests will go through this host. I strongly recommend that this host be on the same local network as your BeOS box: all requests and data go back and forth unencrypted between your BeOS machine and this one, and if you run carl listening on an externally routable interface, you've just created an open proxy!

      Alternatively, if you just want to play around without messing with inetd.conf, Jef Poskanzer's very useful micro_inetd will also run carl. The command line once you've built it is almost always something like ./micro_inetd 8765 carl -p (assuming that carl is in your path). This will serve the proxy until you kill it.

    • But then let's say you like living dangerously and want to run the full proof-of-concept locally, top to bottom and soup to nuts. I like the way you think! First, compile carl from Github using BeOS' provided Metrowerks mwcc (Fred Fish Geek Gadgets gcc support coming soon): cc -o carl carl.c (yes, without optimization), or download a pre-built binary from Be-Power. Next, since BONE was never supported on PowerPC, you'll need inetb, my micro_inetd clone for pre-BONE BeOS (read more about how I got around the BeOS' POSIX layer limitations), a PowerPC binary and source code for which you can also get on Be-Power. I put both carl and inetb into /boot/home/config/bin on the BeBox and Power Mac.

      Now, start the proxy (be sure your BeOS machine is not externally accessible, or edit inetb.c to make it only listen to localhost): inetb 8765 carl -pt (the -t option to disable timeouts is needed because you must compile carl without optimization to reduce its stack overhead, meaning transactions may take substantially longer). In NetPositive+, go to the Preferences window, select the Connections tab, check "Enable proxies" and put localhost and port 8765 into the fields. Both HTTP and HTTPS requests will go through carl. If you want to bounce your outgoing requests through an outbound SOCKS proxy, which I highly recommend for security, add it as an argument (e.g., inetb 8765 carl -pt socks5://socks5:1080/). Note that although carl allows SOCKS 5 as a URL scheme, all requests are made using SOCKS 4.

  • As your last step, be sure to make sure the browser's document encoding is set to UTF-8 for most sites: the default is ISO-8859-1, predictably spewing mojibake on many pages, and there really isn't any plumbing for dynamically selecting the character set (... yet). Then just enter any URL and go. Note that form submissions to sites will generate an "insecure" warning, because technically your connection to the proxy is indeed not encrypted. You decide if you want to turn this off.

An obvious question: why not simply link Crypto Ancienne into NetPositive+, since it has an OpenSSL compatibility mode from its upstream, and I can clearly link in new code? Three reasons: first, I doubt very much the antediluvian OpenSSL in NetPositive (I suppose I should be lucky it's not SSLeay) is ABI-compatible, and the OpenSSL mode is not well-tested. Second, if I find a site that doesn't work with Crypto Ancienne, and I do periodically, I don't have to labouriously reconstruct the browser with the changes. But the third and biggest reason is that carl really strains the classic BeOS' stack limits (again, read the previous article for what horrible things I had to do to get it working in even this state). There is no way I can run that within NetPositive+; all the additional overhead and stack pressure would make the browser unstable. By keeping it as a separate component accessible only over a TCP socket, if that instance of the proxy gets unsettled for some reason then you can just reload the page and try again.

Since I can now add code to the browser, though, there are more opportunities for improvement. First off, we should try to upgrade its cookie support so I can actually log in and post things from the BeBox. And rather than writing a standalone Gopher client for BeOS I think I'll just hack it into NetPositive and abuse its existing FTP protocol support for rendering menus so this way you can download stuff from Be-Power directly. No one's going to be hacking CSS into this and the JavaScript support should just be politely forgotten (regardless of how it good it is at managing devices in Earth orbit), but NetPositive+'s layout engine is pretty quick because it's simple, and it seems to me that simple should work well on these old machines. Post your experiences in the comments.

Using hacked browsers,
Making old machines brand new:


  1. Thank you for documenting this. Amazing work.

    I operate a special website which aims to be compatible with every browser in every configuration. Currently, compatibility drops off around Netscape 2.x, IE 3.x, and Opera 3.x, but I'm always looking to extend it. I've tested with many more obscure browsers, but not NetPositive (yet).

    Would it be possible if you try it out and send a few screenshots? I tried to find an email contact for you, but was unsuccessful.


Comments are subject to moderation. Be nice.