/ static / rss.xml
rss.xml
  1  <?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  2    <channel>
  3      <title>deftly.net - All posts</title>
  4      <link>https://deftly.net/</link>
  5      <description>Personal blog of Aaron Bieber</description>
  6      <copyright>This work is copyright © Aaron Bieber</copyright>
  7      <managingEditor>aaron@bolddaemon.com (Aaron Bieber)</managingEditor>
  8      <pubDate>Tue, 17 Feb 2026 12:01:00 -0700</pubDate>
  9      <item>
 10        <title>Reticulum and You</title>
 11        <link>https://deftly.net/posts/2026-02-17-reticulum-and-you.html</link>
 12        <description>&lt;p&gt;&lt;a href=&#34;https://reticulum.network/&#34;&gt;Reticulum&lt;/a&gt; is a complete network stack built from&#xA;the ground up with security and autonomy in mind. It allows users to build their&#xA;own network, own their identity and connectivity.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Putting that in the context of the current internet:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;You would own your own IP address and be able to create as many new addresses&#xA;as you wanted.&lt;/li&gt;&#xA;&lt;li&gt;Routing to your address is handled by the network, not third party entities.&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;One day you are at home, you announce your presence. Now you are known to&#xA;the network, people can view pages you serve, you can be reached via LXMF.&lt;/li&gt;&#xA;&lt;li&gt;The next day you head to a coffee shop with the same device, you&#xA;announce. Again you can be reached.&lt;/li&gt;&#xA;&lt;/ul&gt;&lt;/li&gt;&#xA;&lt;li&gt;Serving a blog or files can be done from any device.&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;No futzing with ports.&lt;/li&gt;&#xA;&lt;li&gt;No futzing with a server.&lt;/li&gt;&#xA;&lt;li&gt;Only you decide when people can or can not access your node.&lt;/li&gt;&#xA;&lt;/ul&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;To fully experience Reticulum we will need some goals:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Get up and running with chat.&lt;/li&gt;&#xA;&lt;li&gt;Browse a few nodes.&lt;/li&gt;&#xA;&lt;li&gt;Stand up our own node. Serving pages on a real reticulum network.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;h2&gt;Use What You Have&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;A lot of people I have talked to assume you need a LoRa device to get going with&#xA;Reticulum. Happily for us, LoRa is just another medium Reticulum can use. Others&#xA;include Ethernet and WiFi.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Reticulum&amp;rsquo;s reference implementation is built using&#xA; &lt;a href=&#34;https://www.python.org/&#34;&gt;Python&lt;/a&gt;, a very portable programming language. This&#xA; means it will run anywhere Python runs.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Windows, Linux, macOS, Android and even iOS are all capable of running&#xA; Reticulum in some form. But for the best experience, I recommend using a&#xA; Desktop OS.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;Installing NomadNet&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Reticulum has a number of components, but we will be using&#xA;&lt;a href=&#34;https://github.com/markqvist/NomadNet&#34;&gt;Nomadnet&lt;/a&gt;. NomadNet lets one browse&#xA;other nodes, chat with peers and serve content to others that are on the&#xA;network.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you don&amp;rsquo;t have it already, you will need to install Python and pip&#xA;(instructions for this are outside of the scope of this post).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Once they are installed we can install &lt;code&gt;nomadnet&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;pip install nomadnet&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;If you are playing along with multiple computers on the same wireless or&#xA;ethernet network and don&amp;rsquo;t want to connect to the larger Reticulum network, you&#xA;can skip the &amp;ldquo;Configuring NomadNet&amp;rdquo; section.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;Configuring NomadNet&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Once &lt;code&gt;nomadnet&lt;/code&gt; is installed we can create default configurations by running it&#xA;once:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;nomadnet&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Once the UI is visible, you can exit by hitting &lt;code&gt;Control+Q&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There will be two new directories in your &lt;code&gt;~/&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;~/.nomadnet&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;~/.reticulum&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The config file &lt;code&gt;~/.reticulum/config&lt;/code&gt; is used to specify how Reticulum talks to&#xA;other nodes. It does this via&#xA;&lt;a href=&#34;https://reticulum.network/manual/interfaces.html&#34;&gt;Interfaces&lt;/a&gt;. By default there&#xA;is only one interface defined: &lt;code&gt;AutoInterface&lt;/code&gt;. This will allow devices on the&#xA;local network to communicate with each other out of the box, but it won&amp;rsquo;t&#xA;connect you to the greater Reticulum Network.&lt;/p&gt;&#xA;&#xA;&lt;h4&gt;Bootstrapping&lt;/h4&gt;&#xA;&#xA;&lt;p&gt;Using your favorite editor, open &lt;code&gt;~/.reticulum/config&lt;/code&gt;. We are going to make two&#xA;changes:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Enable Interface Discovery&lt;/li&gt;&#xA;&lt;li&gt;Add an initial bootstrap interface&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;p&gt;Under the &lt;code&gt;[reticulum]&lt;/code&gt; section add:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;discover_interfaces = Yes&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;In the &lt;code&gt;[interfaces]&lt;/code&gt; section add:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;[[SUAH TCP]]&#xA;type = TCPClientInterface&#xA;enabled = True&#xA;target_host = suah.dev&#xA;target_port = 4343&#xA;bootstrap_only = True&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;Once these pieces are in place your Reticulum instance will use the configured&#xA;interface to &amp;ldquo;bootstrap&amp;rdquo; connectivity to the greater network. The server&#xA;&lt;code&gt;suah.dev&lt;/code&gt; is configured to share it&amp;rsquo;s interfaces and also to discover new&#xA;ones. It will then inform your instance about new ways to connect.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To view auto-discovered interfaces you can run &lt;code&gt;rnstatus&lt;/code&gt; with the &lt;code&gt;-d&lt;/code&gt; flag. It&#xA;will take some time for the info to populate, but you can watch as info pours in&#xA;with the &lt;code&gt;-m&lt;/code&gt; flag.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;rnstatus -d&#xA;&#xA;Name                      Type         Status       Last Heard   Value    Location&#xA;-----------------------------------------------------------------------------------------&#xA;rns.moscow-i2p            I2P          ✓ Available  1h ago       33       -&#xA;Slivovica                 Backbone     ✓ Available  6h ago       29       -&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;Chatting (LXMF)&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Reticulum has a number of ways to send messages but the canonical method is via&#xA;Lightweight Extensible Message Format (LXMF).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;But before we get to using LXMF we need to discuss a bit of Reticulum&#xA;terminology: Announcements.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Announcements in reticulum are how a device becomes know to the network. Once&#xA;you announce and the announce is propagated across the network, other nodes will&#xA;be able to route traffic to and from you.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To find people to chat with, you will need to run &lt;code&gt;nomadnet&lt;/code&gt; and go to the&#xA;&lt;code&gt;Network&lt;/code&gt; tab. From here you can switch to a mode that shows Announcements. Do&#xA;this by hitting &lt;code&gt;Control+L&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;By default NomadNet sends out an announcement on startup.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;At the top of the &lt;code&gt;Network&lt;/code&gt; page you will see &lt;code&gt;Nodes&lt;/code&gt;, &lt;code&gt;Peers&lt;/code&gt; and &lt;code&gt;Propagation&#xA;Nodes&lt;/code&gt;. Peers are people you can chat with. You could send an unvetted rando a&#xA;message but it&amp;rsquo;s not likely you will get a reply. So instead send one to me:&#xA;&lt;code&gt;745a11b819e01a722cd59ddf74c4b2bf&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you skipped the &amp;ldquo;Configuring NomadNet&amp;rdquo; section, check to see if you see an&#xA;announcement on either of the machines you are using. If not, hit the &lt;code&gt;Announce&#xA;Now&lt;/code&gt; button. If so, select one and hit the &lt;code&gt;Converse&lt;/code&gt; button!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Browsing&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Under the &lt;code&gt;Network&lt;/code&gt; tab (in show announcements mode) you will also see the&#xA;&lt;code&gt;Nodes&lt;/code&gt; sub-tab. This lists nodes that are serving browseable pages.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Selecting one brings up a dialog with a few options: &lt;code&gt;Connect&lt;/code&gt;, &lt;code&gt;Msg Op&lt;/code&gt; and&#xA;&lt;code&gt;Save&lt;/code&gt;. As you can guess, &lt;code&gt;Connect&lt;/code&gt; will load a given page.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A few pages that might be of interest:&lt;/p&gt;&#xA;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Name&lt;/th&gt;&#xA;&lt;th&gt;Description&lt;/th&gt;&#xA;&lt;th&gt;Link&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Waystone&lt;/td&gt;&#xA;&lt;td&gt;Search engine&lt;/td&gt;&#xA;&lt;td&gt;f3a6a73294416a6d9e75706bb9167c6c&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;OpenBSD.app&lt;/td&gt;&#xA;&lt;td&gt;OpenBSD package search&lt;/td&gt;&#xA;&lt;td&gt;0cc65124b72a5fdec6dcc14241bb8108&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;RMAP.WORLD&lt;/td&gt;&#xA;&lt;td&gt;Global map of Reticulum instances&lt;/td&gt;&#xA;&lt;td&gt;a4a5e861626ce97c9aa544d9ecdf6d22&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;To load a page, you will need to copy the Link field above and paste it into the&#xA;dialog that opens in NomadNet when you hit &lt;code&gt;Control+U&lt;/code&gt; (Note the handy keyboard&#xA;shortcut guide at the bottom of the screen).&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Standing Up Your Own Node&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Remember I said there would be two new entries in your &lt;code&gt;~/&lt;/code&gt;? Well now we need to&#xA;modify the NomadNet config file (&lt;code&gt;~/.nomadnet/config&lt;/code&gt;) to enable page&#xA;hosting. Quit NomadNet via &lt;code&gt;Control+Q&lt;/code&gt; and bust out your editor.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This option is under the &lt;code&gt;[node]&lt;/code&gt; section.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You should see a line:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;enable_node = no&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Change it to:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;enable_node = yes&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;You can also specify a &lt;code&gt;node_name&lt;/code&gt; to give people an idea about the content you&#xA;are hosting.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;Create your first page&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Time for that trusty editor again. Open up&#xA;&lt;code&gt;~/.nomadnetwork/storage/pages/index.mu&lt;/code&gt;. &lt;code&gt;.mu&lt;/code&gt; files are written in &amp;ldquo;Micron&amp;rdquo; a&#xA;mark up language created specifically for Reticulum. There is a page in NomadNet&#xA;that explains all of Micron, so I won&amp;rsquo;t go into details here. We will just add&#xA;some text, save it and fire up NomadNet again.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Congrats! You now have a reachable node on the Reticulum network!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Going Further&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;There is plenty of information available to you directly inside NomadNet. The&#xA;&lt;code&gt;Guide&lt;/code&gt; tab covers much more that I touched on here. Be sure to check it out!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The &lt;a href=&#34;https://reticulum.network/manual/index.html&#34;&gt;Reticulum Network Stack&#xA;Manual&lt;/a&gt; is another extremely good&#xA;source of information!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I hope this brief intro was helpful!&lt;/p&gt;&#xA;</description>
 13        <author>Aaron Bieber</author>
 14        <pubDate>Tue, 17 Feb 2026 12:01:00 -0700</pubDate>
 15      </item>
 16      <item>
 17        <title>The Proclaimer®</title>
 18        <link>https://deftly.net/posts/2025-06-24-the-proclaimer.html</link>
 19        <description>&lt;p&gt;Recently I went to a thrift store and found an interesting device. It&amp;rsquo;s called&#xA;the &amp;ldquo;Proclaimer®&amp;rdquo; from a company called &amp;ldquo;Faith Comes by Hearing&amp;rdquo;. The device&#xA;stood out to me because it has:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A solar panel&lt;/li&gt;&#xA;&lt;li&gt;Dynamo&lt;/li&gt;&#xA;&lt;li&gt;USB-C&lt;/li&gt;&#xA;&lt;li&gt;µSD card&lt;/li&gt;&#xA;&lt;li&gt;Audio controls&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;It took me a bit to realize what it was. Especially because when I turned it on&#xA;I heard a language that was very strange to me. Turns out it&amp;rsquo;s a Bible audio&#xA;device. This model has the bible in Ndau &amp;amp;#x2013; a language spoken in Zimbabwe.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I pulled out the µSD card to see what the files where. My hope was that they&#xA;were just MP3, but it turns out they are an encrypted audio file with the&#xA;extension &amp;ldquo;.smp&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I am very impressed by the effort put into a &amp;ldquo;Missionary in a box&amp;rdquo; device like&#xA;this.&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Components&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;Chips&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;ATJ2157 FP51AMQ 36K:&lt;/strong&gt; Audio processor&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;cFeon Q32C-104HIP X20Q101 2248HLB:&lt;/strong&gt; Flash storage?&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;XA5002 1 7042 HBRDHA:&lt;/strong&gt; Audio amp&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Unknown:&lt;/strong&gt; Near the power control components&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Unknown:&lt;/strong&gt; Near the power switch on the crontrol interface side of the PCB&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;Dynamo&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Gears are exposed to the inside of the case, and grease seems to spatter about a&#xA;bit.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Solar panel&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;6.2V output in direct sun light.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Speaker&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;Big&lt;/em&gt; old school speaker. 4Ω 2W.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Battery&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;3.2V 2400mAh LiFePO4 (Mottcell)&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Notes&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;&lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2025-06-17 Tue]&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Thanks to a friend, the files can be &amp;ldquo;decrypted&amp;rdquo; using 1 byte &lt;code&gt;xor&lt;/code&gt; with &lt;code&gt;0x57&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;orgf219b4b&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2025-06-14 Sat]&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;USB-C seems to only be for power.&lt;/li&gt;&#xA;&lt;li&gt;There are &amp;ldquo;RX&amp;rdquo; / &amp;ldquo;TX&amp;rdquo; pads above the ATJ2157.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;org32d7b76&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Links&lt;/h1&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/ZapDissaster/smp2mp3/&#34;&gt;smp2mp3&lt;/a&gt;:&lt;/strong&gt; potential tool to encrypt / decrypt the files. It seems I would&#xA;need to extract the private key from the device.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/ilyakurdyukov/actions_flash&#34;&gt;actions_flash&lt;/a&gt;:&lt;/strong&gt; a tool for dumping the firmware from ATJ chips.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/oyooyo/audiocube&#34;&gt;audiocube&lt;/a&gt;:&lt;/strong&gt; a python tool for encrypting / decrypting .smp files.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
 20        <author>Aaron Bieber</author>
 21        <pubDate>Tue, 24 Jun 2025 18:18:00 -0600</pubDate>
 22      </item>
 23      <item>
 24        <title>Updating a Rust port on OpenBSD</title>
 25        <link>https://deftly.net/posts/2023-09-05-cargo-updates.html</link>
 26        <description>&lt;h1&gt;Updating a Rust port&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;OpenBSD rust ports have always been a bit tricky for me to update. Remembering the steps is a pain&#xA;and there isn&amp;rsquo;t a clear &amp;ldquo;path&amp;rdquo; in the docs.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Recently someone asked me for some guidance on how to do an update.. and while writing out the steps&#xA;I got frustrated and finally put things into a script.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here is a error-check-less approach to updating a rust port:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;#!/bin/sh&#xA;&#xA;set -eu&#xA;&#xA;PORT=&amp;quot;$(make show=PKGNAME)&amp;quot;&#xA;&#xA;mv -v crates.inc crates.old&#xA;touch crates.inc&#xA;make makesum&#xA;make modcargo-gen-crates &amp;gt; /tmp/${PORT}.crates.inc&#xA;grep ^MODCARGO /tmp/${PORT}.crates.inc &amp;gt; crates.inc&#xA;make clean&#xA;make makesum&#xA;make modcargo-gen-crates-licenses &amp;gt; /tmp/${PORT}.license.inc&#xA;grep ^MODCARGO /tmp/${PORT}.license.inc &amp;gt; crates.inc&#xA;rm crates.old&#xA;make clean&#xA;make &amp;amp;&amp;amp; make package&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
 27        <author>Aaron Bieber</author>
 28        <pubDate>Sat, 09 Sep 2023 07:43:38 -0600</pubDate>
 29      </item>
 30      <item>
 31        <title>Unlocking SSH FIDO keys on device connect.</title>
 32        <link>https://deftly.net/posts/2020-07-31-ssh-askpass-prompt-for-fido.html</link>
 33        <description>&lt;h1&gt;The problem&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;As a lazy type, I often find it trying to type &amp;ldquo;ssh-add -K&amp;rdquo; over and over. I&#xA;even felt depleted typing it here!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Fortunately for me, OpenBSD makes it trivial to resolve this issue. All we need&#xA;is:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://man.openbsd.org/hotplugd&#34;&gt;hotplugd&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://man.openbsd.org/pkill&#34;&gt;pkill&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Some shell foo.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;The adder&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This script will run our &amp;hellip;hnnn&lt;code&gt;ssh-add -K&lt;/code&gt;.. command:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#!/bin/sh&#xA;&#xA;trap &#39;ssh-add -K&#39; USR1&#xA;&#xA;while true; do&#xA;&#x9;sleep 1;&#xA;done&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Notice the &lt;code&gt;trap&lt;/code&gt; line there? More on that later! This script should be called&#xA;via &lt;code&gt;/usr/local/bin/fido &amp;amp;&lt;/code&gt; from &lt;code&gt;~/.xsession&lt;/code&gt; or similar. The important thing&#xA;is that it runs &lt;em&gt;after&lt;/em&gt; you log in.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;The watcher&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;hotplugd&lt;/code&gt; (in OpenBSD base) does things when stuff happens. That&amp;rsquo;s just what we&#xA;need!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This script (&lt;code&gt;/etc/hotplugd/attach&lt;/code&gt;) will be called every time we attach a&#xA;device:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#!/bin/sh&#xA;&#xA;DEVCLASS=$1&#xA;DEVNAME=$2&#xA;&#xA;case &amp;quot;$DEVNAME&amp;quot; in&#xA;&#x9;fido0)&#xA;&#x9;&#x9;pkill -USR1 -xf &amp;quot;/bin/sh /usr/local/bin/fido&amp;quot;&#xA;&#x9;;;&#xA;esac&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Notice that &lt;code&gt;pkill&lt;/code&gt; command with &lt;code&gt;USR1&lt;/code&gt;? That&amp;rsquo;s the magic that hits our &lt;code&gt;trap&lt;/code&gt;&#xA;line in the adder script!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Now enable / start up hotplugd:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# rcctl enable hotplugd&#xA;# rcctl start hotplugd&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;That&amp;rsquo;s it!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;If you have all these bits in place, you should see &lt;code&gt;ssh-askpass&lt;/code&gt; pop up when&#xA;you connect a FIDO key to your machine!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here is a video of it in action:&lt;/p&gt;&#xA;&#xA;&lt;video width=&#34;620&#34; controls&gt;&#xA;  &lt;source src=&#34;/fido-add.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;  &lt;p&gt;Your browser doesn&#39;t support HTML5 video. Here is&#xA;     a &lt;a href=&#34;myVideo.mp4&#34;&gt;link to the video&lt;/a&gt; instead.&lt;/p&gt;&#xA;&lt;/video&gt;&#xA;&#xA;&lt;p&gt;Thanks to kn@ for the &lt;code&gt;USR1&lt;/code&gt; suggestion! It really helped me be more lazy!&lt;/p&gt;&#xA;</description>
 34        <author>Aaron Bieber</author>
 35        <pubDate>Fri, 31 Jul 2020 17:43:38 -0600</pubDate>
 36      </item>
 37      <item>
 38        <title>OpenSSH - Configuring FIDO2 Resident Keys</title>
 39        <link>https://deftly.net/posts/2020-06-04-openssh-fido2-resident-keys.html</link>
 40        <description>&lt;h1&gt;Table of Contents&lt;/h1&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#orgeb6aa34&#34;&gt;The Setup&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#org3b8793a&#34;&gt;Creating keys&lt;/a&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#orgbc1a8c9&#34;&gt;Generating the non-resident handle&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#org05f4053&#34;&gt;Generating the resident handle&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#org2df8b52&#34;&gt;Using the token&lt;/a&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#org4f9e2ec&#34;&gt;Resident&lt;/a&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#orgd43612b&#34;&gt;Transient usage with ssh-add&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#org42b60c7&#34;&gt;Permanent usage with ssh-agent&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;#org819b5f5&#34;&gt;Non-resident&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;orgeb6aa34&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;The Setup&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;If you haven&amp;rsquo;t heard, OpenSSH recently (&lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2020-02-14 Fri]&lt;/span&gt;&lt;/span&gt;) &lt;a href=&#34;https://www.openssh.com/txt/release-8.2&#34;&gt;gained support for&#xA;FIDO2/U2F hardware authenticators&lt;/a&gt; like the YubiKey 5!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This allows one to log into remote hosts with the touch of a button and it&#xA;makes me feel like I am living in the future!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Some of these hardware tokens even support multiple slots, allowing one to&#xA;have multiple keys!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;On top of all that, the tokens can do &amp;ldquo;resident&amp;rdquo; and &amp;ldquo;non-resident&amp;rdquo;&#xA;keys. &amp;ldquo;Resident&amp;rdquo; means that the key is effectively retrievable from the&#xA;token (it doesn&amp;rsquo;t actually get the key - it&amp;rsquo;s a handle that lets one use the&#xA;hardware key on the device).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This got me thinking about how I could use a single token (with two keys) to&#xA;access the various machines I use.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In my use case, I have two types of machines I want to connect to:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;greater security:&lt;/strong&gt; machines I want to grant access to from a very select&#xA;number of devices.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;greater&lt;/code&gt; key will require me to copy the &amp;ldquo;key handle&amp;rdquo; to the machines I&#xA;want to use it from.&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;lesser security:&lt;/strong&gt; machines I want to access from devices that may not be as&#xA;secure.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;lesser&lt;/code&gt; key will be &amp;ldquo;resident&amp;rdquo; to the YubiKey. This means it can be&#xA;downloaded from the YubiKey itself. Because of this, it should be trusted a&#xA;bit less.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;org3b8793a&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Creating keys&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;When creating FIDO keys (really they are key handles) one needs to explicitly&#xA;tell the tool being used that it needs to pick the next slot. Otherwise&#xA;generating the second key will clobber the first!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;orgbc1a8c9&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Generating the non-resident handle&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;greater&lt;/code&gt; will require me to send the &lt;code&gt;~/.ssh/ed25519_sk_greater&lt;/code&gt; handle to the&#xA;various hosts I want to use it from.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We will be using &lt;code&gt;ssh-keygen&lt;/code&gt; to create our resident key.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ssh-keygen -t ed25519-sk -Oapplication=ssh:greater -f ~/.ssh/ed25519_sk_greater&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;org05f4053&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Generating the resident handle&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Because resident keys allow for the handle to be downloaded from the token,&#xA;I have changed the PIN on my token. The PIN is the only defense against a&#xA;stolen key. &lt;strong&gt;Note&lt;/strong&gt;: the PIN can be a full passphrase!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Again via &lt;code&gt;ssh-keygen&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ssh-keygen -t ed25519-sk -Oresident -Oapplication=ssh:lesser -f ~/.ssh/ed25519_sk_lesser&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;org2df8b52&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Using the token&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;org4f9e2ec&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Resident&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The resident key can be used by adding it to &lt;code&gt;ssh-agent&lt;/code&gt; or by downloading&#xA;the handle / public key using &lt;code&gt;ssh-keygen&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;orgd43612b&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;Transient usage with ssh-add&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ssh-add -K&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This will prompt for the PIN (which should be set as it&amp;rsquo;s the only defense&#xA;against a stolen key!)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;No handle files will be placed on the machine you run this on. Handy for&#xA;machines you want to ssh from but don&amp;rsquo;t fully trust.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;org42b60c7&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;Permanent usage with ssh-agent&lt;/h3&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ssh-keygen -K&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This will also prompt for the PIN, however, it will create the private key&#xA;handle and corresponding public key and place them in &lt;code&gt;$CWD&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a id=&#34;org819b5f5&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Non-resident&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The non-resident key will only work from hosts that have the handle (in our case&#xA;&lt;code&gt;~/.ssh/ed25519_sk_greater&lt;/code&gt;). As such, the handle must be copied to the machines&#xA;you want to allow access from.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Once the handle is in place, you can specify it&amp;rsquo;s usage in &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Host secretsauce&#xA;    IdentityFile ~/.ssh/ed25519_sk_greater&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
 41        <author>Aaron Bieber</author>
 42        <pubDate>Thu, 04 Jun 2020 17:43:38 -0600</pubDate>
 43      </item>
 44      <item>
 45        <title>Websockets with OpenBSD&#39;s relayd</title>
 46        <link>https://deftly.net/posts/2019-10-23-websockets-with-relayd.html</link>
 47        <description>&lt;h1&gt;The need&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;I am in the process of replacing all my NGINX instances with &lt;a href=&#34;https://man.openbsd.org/httpd&#34;&gt;httpd&lt;/a&gt;/&lt;a href=&#34;https://man.openbsd.org/relayd&#34;&gt;relayd&lt;/a&gt;.&#xA;So far this has been going pretty smoothly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I did, however, run into an issue with websockets in Safari on iOS and&#xA;macOS which made me think they weren&amp;rsquo;t working at all! Further testing proved&#xA;they were working fine in other browsers, so .. more digging needs to be done!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;The configs&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;I tested this in a VM running on OpenBSD. It&amp;rsquo;s &amp;lsquo;external&amp;rsquo; IP is 10.10.10.15.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This config also works with TLS but for simplicity, this example will be plain&#xA;text.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;relayd.conf&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ext_addr=&amp;quot;10.10.10.15&amp;quot;&#xA;&#xA;log connection errors&#xA;&#xA;table &amp;lt;websocketd&amp;gt; { 127.0.0.1 }&#xA;&#xA;http protocol ws {&#xA;&#x9;match request header append &amp;quot;X-Forwarded-For&amp;quot; value &amp;quot;$REMOTE_ADDR&amp;quot;&#xA;&#x9;match request header append &amp;quot;X-Forwarded-By&amp;quot; \&#xA;&#x9;&#x9;value &amp;quot;$SERVER_ADDR:$SERVER_PORT&amp;quot;&#xA;&#x9;match request header &amp;quot;Host&amp;quot; value &amp;quot;10.10.10.15&amp;quot; forward to &amp;lt;websocketd&amp;gt;&#xA;&#xA;&#x9;http websockets&#xA;}&#xA;&#xA;relay ws {&#xA;&#x9;listen on $ext_addr port 8000&#xA;&#x9;protocol ws&#xA;&#x9;forward to &amp;lt;websocketd&amp;gt; port 9999&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Here we are setting up a &amp;ldquo;websocket&amp;rdquo; listener on port &lt;code&gt;8000&lt;/code&gt; and forwarding&#xA;it to port &lt;code&gt;9999&lt;/code&gt; on &lt;code&gt;127.0.0.1&lt;/code&gt; where we will be running &lt;a href=&#34;http://websocketd.com/&#34;&gt;websocketd&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The key directive is &lt;code&gt;http websockets&lt;/code&gt; in the &lt;code&gt;http&lt;/code&gt; block. Without this the&#xA;proper headers won&amp;rsquo;t be set and the connection will not work.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;httpd.conf&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# $OpenBSD: httpd.conf,v 1.20 2018/06/13 15:08:24 reyk Exp $&#xA;&#xA;server &amp;quot;10.10.10.15&amp;quot; {&#xA;&#x9;listen on * port 80&#xA;&#x9;location &amp;quot;/*&amp;quot; {&#xA;&#x9;&#x9;directory auto index&#xA;&#x9;}&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Pretty simple. We are just going to serve the html file below.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;/var/www/htdocs/index.html&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;This html blurb simply creates a websocket and pumps the data it receives into&#xA;a div that we can see.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;&#xA;&amp;lt;html&amp;gt;&#xA;&amp;lt;head&amp;gt;&#xA;&amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;&#xA;&amp;lt;title&amp;gt;ws test&amp;lt;/title&amp;gt;&#xA;&amp;lt;/head&amp;gt;&#xA;&amp;lt;body&amp;gt;&#xA;  &amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#xA;&amp;lt;/body&amp;gt;&#xA;&amp;lt;script&amp;gt;&#xA;let ws = new WebSocket(&amp;quot;ws://10.10.10.15:8000/weechat&amp;quot;);&#xA;let d = document.getElementById(&#39;output&#39;);&#xA;ws.onopen = function() {&#xA;  ws.send(&amp;quot;hi&amp;quot;);&#xA;};&#xA;&#xA;ws.onmessage = function (e) { &#xA;  d.innerText = d.innerText + &amp;quot; &amp;quot; + e.data;&#xA;};&#xA;&#xA;ws.onclose = function() { &#xA;  d.innerText += (&#39; done.&#39;); &#xA;};&#xA;&amp;lt;/script&amp;gt;&#xA;&amp;lt;/html&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;websocketd&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Now we use &lt;code&gt;websocketd&lt;/code&gt; to serve up some sweet sweet websocket action!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#!/bin/sh&#xA;&#xA;echo &#39;hi&#39;&#xA;&#xA;for i in $(jot 5); do&#xA;&#x9;echo $i;&#xA;&#x9;sleep 1;&#xA;done&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Use &lt;code&gt;websocketd&lt;/code&gt; to run the above script:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;websocketd --port 9999 --address 127.0.0.1 ./above_script.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Now point your browser at &lt;a href=&#34;http://10.10.10.15/&#34;&gt;http://10.10.10.15/&lt;/a&gt;! You will&#xA;see &amp;ldquo;hi&amp;rdquo; and every second for five seconds you will see a count appended to&#xA;&lt;code&gt;&amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;The issues&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;The error I saw on Safari on iOS and macOS is:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;&#39;Connection&#39; header value is not &#39;Upgrade&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Which is strange, bucaese I can see that it is infact set to &amp;lsquo;Upgrade&amp;rsquo; in a&#xA;tcpdump.&lt;/p&gt;&#xA;</description>
 48        <author>Aaron Bieber</author>
 49        <pubDate>Wed, 23 Oct 2019 09:00:00 -0600</pubDate>
 50      </item>
 51      <item>
 52        <title>OpenBSD on the Lenovo A485</title>
 53        <link>https://deftly.net/posts/2018-10-15-openbsd-on-lenovo-a485.html</link>
 54        <description>&lt;p&gt;I am going to attempt to do a jcs@ style review of the Lenovo A485. I&#xA;have stolen his format, slacked on detail.. and generally not done as&#xA;good of a job reviewing as he has. Please check out his work at &lt;a href=&#34;https://jcs.org&#34;&gt;jcs.org&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Hardware&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/images/147.jpg&#34; alt=&#34;Entire laptop&#34; /&gt;&#xA;&lt;img src=&#34;/images/144.jpg&#34; alt=&#34;Screen and keyboard top&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In typical Lenovo fashion, the A485 has three point eight gajillion&#xA;configuration options one can select from during &amp;ldquo;Customization&amp;rdquo;. You&#xA;can even get it with a built in SmartCard™ reader!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can select SATA SSD or NVMe SSD, anywhere from 4GB to 32GB of&#xA;Memory, AMD Ryzen™ 3, 5 or 7!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since this is going to be my main machine for as many years as I can&#xA;possibly squeeze out of it, I opted for &amp;ldquo;all the things!&amp;rdquo;!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The display options leave a little to be desired. Max resolution is&#xA;1920x1080. Not &lt;em&gt;bad&lt;/em&gt; but not &lt;em&gt;great&lt;/em&gt; either.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Installing OpenBSD&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Put install media into laptop.&lt;/li&gt;&#xA;&lt;li&gt;Politely ask Henry on stand on the &amp;ldquo;enter&amp;rdquo; key.&lt;/li&gt;&#xA;&lt;li&gt;\o/&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;Support Summary&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;OpenBSD-current&lt;/em&gt; as of &lt;em&gt;2018-10-15&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Component&lt;/th&gt;&#xA;&lt;th align=&#34;center&#34;&gt;Works?&lt;/th&gt;&#xA;&lt;th&gt;Notes&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Accelerated graphics&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;No&lt;/td&gt;&#xA;&lt;td&gt;The Radeon™ Vega 6 integrated GPU isn&amp;rsquo;t supported currently. X11 is usable via the &lt;a href=&#34;https://man.openbsd.org/efifb&#34;&gt;efifb&lt;/a&gt; driver which does an impressive job and displays things at the native resolution (1920x1080)! I am able to watch youtube videos without issue.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;AC adapter&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;Yes&lt;/td&gt;&#xA;&lt;td&gt;USB-C connector. Has a satisfying click when connecting.. flops about wildly while connected. Attaches as &lt;a href=&#34;https://man.openbsd.org/acpiac&#34;&gt;acpiac&lt;/a&gt;.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Audio&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;Yes-ish&lt;/td&gt;&#xA;&lt;td&gt;Audio works as expected though there is a known bug with &lt;a href=&#34;https://man.openbsd.org/azalia&#34;&gt;azalia&lt;/a&gt; on Ryzen that causes it to stop working after a period of time.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Battery status&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;Yes&lt;/td&gt;&#xA;&lt;td&gt;Status is visible in &lt;code&gt;apm&lt;/code&gt; and &lt;code&gt;hw.sensors&lt;/code&gt;. Attaches as &lt;a href=&#34;https://man.openbsd.org/acpibat&#34;&gt;acpibat&lt;/a&gt;.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Bluetooth&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;No&lt;/td&gt;&#xA;&lt;td&gt;No support in OpenBSD. BT can be disabled in the bios.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Cameras&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;No&lt;/td&gt;&#xA;&lt;td&gt;When attempting to use the camera via &lt;code&gt;/dev/video&lt;/code&gt;, the &amp;ldquo;activity&amp;rdquo; light turns on, but it seems the video device isn&amp;rsquo;t compatible. Awesome side note, there is a built-in slider to cover the camera lens!&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Ethernet&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;Yes&lt;/td&gt;&#xA;&lt;td&gt;Weirdly, there are two ethernet devices, &lt;code&gt;re0&lt;/code&gt; and &lt;code&gt;re1&lt;/code&gt;. &lt;code&gt;re1&lt;/code&gt; is the physical ethernet port on the laptop. I can only assume that &lt;code&gt;re0&lt;/code&gt; is the would-be-dock-ethernet?&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Hibernation&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;Maybe&lt;/td&gt;&#xA;&lt;td&gt;This could be because I didn&amp;rsquo;t create a swap partition that was 32GB.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;MicroSD slot&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;Yes&lt;/td&gt;&#xA;&lt;td&gt;Inserted cards show up fine.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Suspend/Resume&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;No&lt;/td&gt;&#xA;&lt;td&gt;Technically the machine suspends / resumes, but X11 never comes back.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Volume buttons&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;Yes&lt;/td&gt;&#xA;&lt;td&gt;Via &lt;a href=&#34;https://man.openbsd.org/acpithinkpad&#34;&gt;acpithinkpad&lt;/a&gt;.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Wireless&lt;/td&gt;&#xA;&lt;td align=&#34;center&#34;&gt;No&lt;/td&gt;&#xA;&lt;td&gt;The machine comes with a Realtek RTL8822BE, which isn&amp;rsquo;t supported currently. I was able to replace this with an Intel Dual Band Wireless-AC 8265.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Here are some photos of the built-in camera cover I mention in the&#xA;Summary above.&#xA;&lt;img src=&#34;/images/142.jpg&#34; alt=&#34;Camera covered&#34; /&gt;&#xA;&lt;img src=&#34;/images/143.jpg&#34; alt=&#34;Camera open&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/images/145.jpg&#34; alt=&#34;Picture of the AC / dock ports&#34; /&gt;&#xA;&lt;img src=&#34;/images/146.jpg&#34; alt=&#34;Picture of the opposite side&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;dmesg&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;OpenBSD 6.4 (GENERIC.MP) #0: Thu Oct 11 14:54:13 MDT 2018&#xA;    qbit@ren.tapenet.org:/sys/arch/amd64/compile/GENERIC.MP&#xA;real mem = 33139396608 (31604MB)&#xA;avail mem = 32125767680 (30637MB)&#xA;mpath0 at root&#xA;scsibus0 at mpath0: 256 targets&#xA;mainbus0 at root&#xA;bios0 at mainbus0: SMBIOS rev. 3.1 @ 0x68607000 (62 entries)&#xA;bios0: vendor LENOVO version &amp;quot;R0WET34W (1.02 )&amp;quot; date 07/05/2018&#xA;bios0: LENOVO 20MUCTO1WW&#xA;acpi0 at bios0: rev 2&#xA;acpi0: BGRT checksum error&#xA;acpi0: sleep states S0 S3 S4 S5&#xA;acpi0: tables DSDT FACP SSDT SSDT CRAT CDIT SSDT TPM2 UEFI MSDM BATB HPET APIC MCFG SBST VFCT IVRS FPDT SSDT SSDT SSDT UEFI SSDT BGRT&#xA;acpi0: wakeup devices GPP0(S3) GPP1(S3) GPP2(S3) GPP3(S3) GPP4(S3) L850(S3) GPP5(S3) GPP6(S3) GP17(S3) XHC0(S3) XHC1(S3) GP18(S3) LID_(S3) SLPB(S3)&#xA;acpitimer0 at acpi0: 3579545 Hz, 32 bits&#xA;acpihpet0 at acpi0: 14318180 Hz&#xA;acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat&#xA;cpu0 at mainbus0: apid 0 (boot processor)&#xA;cpu0: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2196.29 MHz, 17-11-00&#xA;cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu0: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu0: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu0: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu0: smt 0, core 0, package 0&#xA;mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges&#xA;cpu0: apic clock running at 24MHz&#xA;cpu0: mwait min=64, max=64, C-substates=1.1, IBE&#xA;cpu1 at mainbus0: apid 1 (application processor)&#xA;cpu1: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2195.85 MHz, 17-11-00&#xA;cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu1: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu1: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu1: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu1: smt 1, core 0, package 0&#xA;cpu2 at mainbus0: apid 2 (application processor)&#xA;cpu2: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2195.85 MHz, 17-11-00&#xA;cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu2: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu2: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu2: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu2: smt 0, core 1, package 0&#xA;cpu3 at mainbus0: apid 3 (application processor)&#xA;cpu3: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2195.85 MHz, 17-11-00&#xA;cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu3: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu3: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu3: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu3: smt 1, core 1, package 0&#xA;cpu4 at mainbus0: apid 4 (application processor)&#xA;cpu4: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2195.85 MHz, 17-11-00&#xA;cpu4: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu4: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu4: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu4: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu4: smt 0, core 2, package 0&#xA;cpu5 at mainbus0: apid 5 (application processor)&#xA;cpu5: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2195.85 MHz, 17-11-00&#xA;cpu5: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu5: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu5: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu5: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu5: smt 1, core 2, package 0&#xA;cpu6 at mainbus0: apid 6 (application processor)&#xA;cpu6: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2195.85 MHz, 17-11-00&#xA;cpu6: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu6: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu6: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu6: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu6: smt 0, core 3, package 0&#xA;cpu7 at mainbus0: apid 7 (application processor)&#xA;cpu7: AMD Ryzen 7 PRO 2700U w/ Radeon Vega Mobile Gfx, 2195.85 MHz, 17-11-00&#xA;cpu7: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,RDSEED,ADX,SMAP,CLFLUSHOPT,SHA,IBPB,XSAVEOPT,XSAVEC,XGETBV1,XSAVES&#xA;cpu7: 64KB 64b/line 4-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache, 4MB 64b/line 16-way L3 cache&#xA;cpu7: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu7: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative&#xA;cpu7: smt 1, core 3, package 0&#xA;ioapic0 at mainbus0: apid 32 pa 0xfec00000, version 21, 24 pins, can&#39;t remap&#xA;ioapic1 at mainbus0: apid 33 pa 0xfec01000, version 21, 32 pins, can&#39;t remap&#xA;acpimcfg0 at acpi0&#xA;acpimcfg0: addr 0xf8000000, bus 0-63&#xA;acpiprt0 at acpi0: bus 0 (PCI0)&#xA;acpiprt1 at acpi0: bus 1 (GPP0)&#xA;acpiprt2 at acpi0: bus 2 (GPP1)&#xA;acpiprt3 at acpi0: bus 3 (GPP2)&#xA;acpiprt4 at acpi0: bus 4 (GPP3)&#xA;acpiprt5 at acpi0: bus -1 (GPP4)&#xA;acpiprt6 at acpi0: bus 5 (GPP5)&#xA;acpiprt7 at acpi0: bus -1 (GPP6)&#xA;acpiprt8 at acpi0: bus 6 (GP17)&#xA;acpiprt9 at acpi0: bus 7 (GP18)&#xA;acpiec0 at acpi0&#xA;acpicpu0 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpicpu1 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpicpu2 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpicpu3 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpicpu4 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpicpu5 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpicpu6 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpicpu7 at acpi0: C2(0@400 io@0x414), C1(0@1 mwait), PSS&#xA;acpipwrres0 at acpi0: PUBS, resource for XHC0&#xA;acpipwrres1 at acpi0: P0ST, resource for SATA&#xA;acpipwrres2 at acpi0: P3ST, resource for SATA&#xA;acpibtn0 at acpi0: PWRB&#xA;acpicmos0 at acpi0&#xA;acpibat0 at acpi0: BAT0 model &amp;quot;01AV489&amp;quot; serial  3225 type LiP oem &amp;quot;LGC&amp;quot;&#xA;acpibat1 at acpi0: BAT1 model &amp;quot;01AV452&amp;quot; serial  1401 type LiP oem &amp;quot;SMP&amp;quot;&#xA;acpiac0 at acpi0: AC unit online&#xA;acpithinkpad0 at acpi0&#xA;&amp;quot;SMB0001&amp;quot; at acpi0 not configured&#xA;acpibtn1 at acpi0: LID_&#xA;acpibtn2 at acpi0: SLPB&#xA;&amp;quot;PNP0C14&amp;quot; at acpi0 not configured&#xA;&amp;quot;PNP0C14&amp;quot; at acpi0 not configured&#xA;&amp;quot;PNP0C14&amp;quot; at acpi0 not configured&#xA;&amp;quot;STM7304&amp;quot; at acpi0 not configured&#xA;&amp;quot;USBC000&amp;quot; at acpi0 not configured&#xA;acpivideo0 at acpi0: VGA_&#xA;cpu0: 2196 MHz: speeds: 2200 1700 1600 MHz&#xA;pci0 at mainbus0 bus 0&#xA;pchb0 at pci0 dev 0 function 0 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15d0 rev 0x00&#xA;vendor &amp;quot;AMD&amp;quot;, unknown product 0x15d1 (class system subclass IOMMU, rev 0x00) at pci0 dev 0 function 2 not configured&#xA;pchb1 at pci0 dev 1 function 0 &amp;quot;AMD AMD64 17h PCIE&amp;quot; rev 0x00&#xA;ppb0 at pci0 dev 1 function 1 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15d3 rev 0x00: msi&#xA;pci1 at ppb0 bus 1&#xA;rtsx0 at pci1 dev 0 function 0 &amp;quot;Realtek RTS522A Card Reader&amp;quot; rev 0x01: msi&#xA;sdmmc0 at rtsx0: 4-bit, dma&#xA;ppb1 at pci0 dev 1 function 2 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15d3 rev 0x00: msi&#xA;pci2 at ppb1 bus 2&#xA;iwm0 at pci2 dev 0 function 0 &amp;quot;Intel Dual Band Wireless-AC 8265&amp;quot; rev 0x78, msi&#xA;ppb2 at pci0 dev 1 function 3 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15d3 rev 0x00: msi&#xA;pci3 at ppb2 bus 3&#xA;nvme0 at pci3 dev 0 function 0 &amp;quot;Samsung SM981/PM981 NVMe&amp;quot; rev 0x00: msi, NVMe 1.2&#xA;nvme0: SAMSUNG MZVLB512HAJQ-000L7, firmware 4L2QEXA7, serial S3TNNX0K825659&#xA;scsibus1 at nvme0: 1 targets&#xA;sd0 at scsibus1 targ 0 lun 0: &amp;lt;NVMe, SAMSUNG MZVLB512, 4L2Q&amp;gt; SCSI4 0/direct fixed&#xA;sd0: 488386MB, 512 bytes/sector, 1000215216 sectors&#xA;ppb3 at pci0 dev 1 function 4 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15d3 rev 0x00: msi&#xA;pci4 at ppb3 bus 4&#xA;re0 at pci4 dev 0 function 0 &amp;quot;Realtek 8168&amp;quot; rev 0x0e: RTL8168EP/8111EP (0x5000), msi, address 8c:16:45:c9:32:ae&#xA;rgephy0 at re0 phy 7: RTL8251 PHY, rev. 0&#xA;vendor &amp;quot;Realtek&amp;quot;, unknown product 0x816a (class communications subclass serial, rev 0x0e) at pci4 dev 0 function 1 not configured&#xA;vendor &amp;quot;Realtek&amp;quot;, unknown product 0x816b (class communications subclass serial, rev 0x0e) at pci4 dev 0 function 2 not configured&#xA;vendor &amp;quot;Realtek&amp;quot;, unknown product 0x816c (class serial bus subclass IPMI, rev 0x0e) at pci4 dev 0 function 3 not configured&#xA;ehci0 at pci4 dev 0 function 4 vendor &amp;quot;Realtek&amp;quot;, unknown product 0x816d rev 0x0e: apic 33 int 15&#xA;ehci0: pre-2.0 USB rev&#xA;ppb4 at pci0 dev 1 function 6 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15d3 rev 0x00: msi&#xA;pci5 at ppb4 bus 5&#xA;re1 at pci5 dev 0 function 0 &amp;quot;Realtek 8168&amp;quot; rev 0x10: RTL8168GU/8111GU (0x5080), msi, address 8c:16:45:c9:32:ad&#xA;rgephy1 at re1 phy 7: RTL8251 PHY, rev. 0&#xA;pchb2 at pci0 dev 8 function 0 &amp;quot;AMD AMD64 17h PCIE&amp;quot; rev 0x00&#xA;ppb5 at pci0 dev 8 function 1 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15db rev 0x00&#xA;pci6 at ppb5 bus 6&#xA;vendor &amp;quot;ATI&amp;quot;, unknown product 0x15dd (class display subclass VGA, rev 0xd0) at pci6 dev 0 function 0 not configured&#xA;azalia0 at pci6 dev 0 function 1 vendor &amp;quot;ATI&amp;quot;, unknown product 0x15de rev 0x00: msi&#xA;azalia0: no supported codecs&#xA;vendor &amp;quot;AMD&amp;quot;, unknown product 0x15df (class crypto subclass miscellaneous, rev 0x00) at pci6 dev 0 function 2 not configured&#xA;xhci0 at pci6 dev 0 function 3 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15e0 rev 0x00: msi, xHCI 1.16&#xA;usb0 at xhci0: USB revision 3.0&#xA;uhub0 at usb0 configuration 1 interface 0 &amp;quot;AMD xHCI root hub&amp;quot; rev 3.00/1.00 addr 1&#xA;xhci1 at pci6 dev 0 function 4 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15e1 rev 0x00: msi, xHCI 1.16&#xA;usb1 at xhci1: USB revision 3.0&#xA;uhub1 at usb1 configuration 1 interface 0 &amp;quot;AMD xHCI root hub&amp;quot; rev 3.00/1.00 addr 1&#xA;azalia1 at pci6 dev 0 function 6 &amp;quot;AMD Raven Ridge HD Audio&amp;quot; rev 0x00: apic 33 int 30&#xA;azalia1: codecs: Realtek/0x0257&#xA;audio0 at azalia1&#xA;ppb6 at pci0 dev 8 function 2 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15dc rev 0x00&#xA;pci7 at ppb6 bus 7&#xA;ahci0 at pci7 dev 0 function 0 &amp;quot;AMD Carrizo AHCI&amp;quot; rev 0x61: msi, AHCI 1.3.1&#xA;scsibus2 at ahci0: 32 targets&#xA;&amp;quot;AMD Carrizo SMBus&amp;quot; rev 0x61 at pci0 dev 20 function 0 not configured&#xA;pcib0 at pci0 dev 20 function 3 &amp;quot;AMD Carrizo LPC&amp;quot; rev 0x51&#xA;pchb3 at pci0 dev 24 function 0 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15e8 rev 0x00&#xA;pchb4 at pci0 dev 24 function 1 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15e9 rev 0x00&#xA;pchb5 at pci0 dev 24 function 2 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15ea rev 0x00&#xA;pchb6 at pci0 dev 24 function 3 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15eb rev 0x00&#xA;pchb7 at pci0 dev 24 function 4 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15ec rev 0x00&#xA;pchb8 at pci0 dev 24 function 5 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15ed rev 0x00&#xA;pchb9 at pci0 dev 24 function 6 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15ee rev 0x00&#xA;pchb10 at pci0 dev 24 function 7 vendor &amp;quot;AMD&amp;quot;, unknown product 0x15ef rev 0x00&#xA;isa0 at pcib0&#xA;isadma0 at isa0&#xA;pckbc0 at isa0 port 0x60/5 irq 1 irq 12&#xA;pckbd0 at pckbc0 (kbd slot)&#xA;wskbd0 at pckbd0: console keyboard&#xA;pms0 at pckbc0 (aux slot)&#xA;wsmouse0 at pms0 mux 0&#xA;wsmouse1 at pms0 mux 0&#xA;pms0: Synaptics clickpad, firmware 8.16, 0x1e2b1 0x940300&#xA;pcppi0 at isa0 port 0x61&#xA;spkr0 at pcppi0&#xA;vmm0 at mainbus0: SVM/RVI&#xA;efifb0 at mainbus0: 1920x1080, 32bpp&#xA;wsdisplay0 at efifb0 mux 1: console (std, vt100 emulation), using wskbd0&#xA;wsdisplay0: screen 1-5 added (std, vt100 emulation)&#xA;uhub2 at uhub1 port 1 configuration 1 interface 0 &amp;quot;Genesys Logic USB2.0 Hub&amp;quot; rev 2.00/60.52 addr 2&#xA;ugen0 at uhub2 port 1 &amp;quot;vendor 0x06cb product 0x009a&amp;quot; rev 2.00/1.64 addr 3&#xA;ugen1 at uhub2 port 3 &amp;quot;Generic EMV Smartcard Reader&amp;quot; rev 2.01/1.20 addr 4&#xA;uhub3 at uhub1 port 2 configuration 1 interface 0 &amp;quot;Genesys Logic USB2.0 Hub&amp;quot; rev 2.00/60.52 addr 5&#xA;uvideo0 at uhub3 port 3 configuration 1 interface 0 &amp;quot;Chicony Electronics Co.,Ltd. Integrated Camera&amp;quot; rev 2.01/0.27 addr 6&#xA;video0 at uvideo0&#xA;vscsi0 at root&#xA;scsibus3 at vscsi0: 256 targets&#xA;softraid0 at root&#xA;scsibus4 at softraid0: 256 targets&#xA;sd1 at scsibus4 targ 1 lun 0: &amp;lt;OPENBSD, SR CRYPTO, 006&amp;gt; SCSI2 0/direct fixed&#xA;sd1: 488385MB, 512 bytes/sector, 1000213601 sectors&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
 55        <author>Aaron Bieber</author>
 56        <pubDate>Mon, 15 Oct 2018 09:00:00 -0600</pubDate>
 57      </item>
 58      <item>
 59        <title>Test packages for Node on OpenBSD</title>
 60        <link>https://deftly.net/posts/2018-node-pre-release.html</link>
 61        <description>&lt;h1&gt;Test builds for node&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;In an attempt to get a wider range of testing for &lt;code&gt;lang/node&lt;/code&gt;, I have decided&#xA;to make test builds available here on &lt;a href=&#34;https://deftly.net/pub/OpenBSD&#34;&gt;deftly.net&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you want to test node, but don&amp;rsquo;t want to build the package yourself, you&#xA;can simply run the following to upgrade your current install:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;env PKG_PATH=https://deftly.net/pub/OpenBSD/snapshots/packages/$(machine) pkg_add -u node&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;All the packages pushed here will be signed via &lt;a href=&#34;https://man.openbsd.org/signify&#34;&gt;signify(1)&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To make use of the signing, you will have to copy the below pub key to&#xA;&lt;code&gt;/etc/signify/abieber-pkg.pub&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;untrusted comment: signify public key&#xA;RWRaFou/737fpovRq3OP3lZnz/97lbq2wYXFFk90nYUaW8xbc2HTd2xj&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
 62        <author>Aaron Bieber</author>
 63        <pubDate>Thu, 30 Aug 2018 09:00:00 -0600</pubDate>
 64      </item>
 65      <item>
 66        <title>Passing off the Complexity</title>
 67        <link>https://deftly.net/posts/2017-12-29-passing-off-the-hard-parts.html</link>
 68        <description>&lt;h1&gt;The Password Dilemma&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;For quite some time I was a user of KeePass. Life was great I had a&#xA;client that worked on every platform (OpenBSD via &lt;code&gt;mono&lt;/code&gt;, Android and&#xA;iOS via 3rd party apps). Every now and then I would manually copy the&#xA;file from my &amp;ldquo;main&amp;rdquo; machine to all the others.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;After a while the syncing process became tedious. I attempted to find&#xA;things that would aid in the process.. Tools like &lt;code&gt;syncthing&lt;/code&gt;,&#xA;&lt;code&gt;unison&lt;/code&gt;, dropbox.. etc. They all had issues. With &lt;code&gt;syncthing&lt;/code&gt; the&#xA;synchronizing was unreliable. Most of the time it couldn&amp;rsquo;t find other&#xA;hosts on my network.. and when it finally did I would end up needing&#xA;to tell it how to resolve conflicts. Dropbox didn&amp;rsquo;t have a native&#xA;client for OpenBSD - not to mention putting your password database&#xA;online is a terrifying proposition (my main issue with LastPass)!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Out of all the management methods I tried - LastPass was the most&#xA;&amp;ldquo;complete&amp;rdquo;:&lt;/p&gt;&#xA;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Name&lt;/th&gt;&#xA;&lt;th&gt;Syncing&lt;/th&gt;&#xA;&lt;th&gt;Browser&lt;/th&gt;&#xA;&lt;th&gt;OpenBSD&lt;/th&gt;&#xA;&lt;th&gt;iOS/Android&lt;/th&gt;&#xA;&lt;th&gt;My Trust&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;LastPass&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✗&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;KeePass&lt;/td&gt;&#xA;&lt;td&gt;✗&lt;/td&gt;&#xA;&lt;td&gt;✗&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Password-Gorilla&lt;/td&gt;&#xA;&lt;td&gt;✗&lt;/td&gt;&#xA;&lt;td&gt;✗&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&#xA;&lt;h1&gt;Enter pass&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;pass&lt;/code&gt; is touted as &amp;ldquo;the standard Unix password manager&amp;rdquo;. It works&#xA;by keeping your passwords in individual PGP encrypted files. For&#xA;example, the entry &lt;code&gt;Web/google.com&lt;/code&gt; would hold my &amp;ldquo;google.com&amp;rdquo;&#xA;password. An entry can contain more than just your passwords (I&#xA;have &lt;code&gt;username: ....&lt;/code&gt; set on the 2nd line.), the first line&#xA;is always expected to be the password.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Out of the box, pass supports syncing via git, multiple recipients&#xA;(meaning it can encrypt a password file for multiple people),&#xA;random password generation and copying to clipboard with&#xA;auto-clear!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It doesn&amp;rsquo;t, however, work out of the box on iOS/Android or my&#xA;browser. Fortunately for me - pass has a fantastic ecosystem&#xA;with a multitude of 3rd party browser extensions, iOS/Android apps.. best&#xA;all, they are open source! There are even full replacements for&#xA;pass itself! One such replacements is &lt;a href=&#34;https://github.com/justwatchcom/gopass&#34;&gt;gopass&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;gopass&lt;/code&gt; extends pass a bit further, it&amp;rsquo;s written in Go,&#xA;seamlessly supports multiple &amp;ldquo;stores&amp;rdquo; (allowing me to have an&#xA;extra level of privledge separation for sensitive passwords),&#xA;is pledge()&amp;rsquo;d, AND can run on every OS I use!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For browsers, I have settled on &lt;a href=&#34;https://github.com/dannyvankooten/browserpass&#34;&gt;browserpass&lt;/a&gt;. It&amp;rsquo;s also written&#xA;in Go, pledge()&amp;rsquo;d, works on all my systems* (OpenBSD, Windows,&#xA;macos), has auto-fill and easy to grok source code!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For iOS/Android there are &lt;a href=&#34;https://github.com/mssun/passforios&#34;&gt;passforios&lt;/a&gt; and &lt;a href=&#34;https://github.com/zeapo/Android-Password-Store&#34;&gt;Android-Password-Store&lt;/a&gt;. All of which support&#xA;syncing via git!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Couple all this together and I get:&lt;/p&gt;&#xA;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Name&lt;/th&gt;&#xA;&lt;th&gt;Syncing&lt;/th&gt;&#xA;&lt;th&gt;Browser&lt;/th&gt;&#xA;&lt;th&gt;OpenBSD&lt;/th&gt;&#xA;&lt;th&gt;iOS/Android&lt;/th&gt;&#xA;&lt;th&gt;My Trust&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;gopass/browserpass/mobile app&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;td&gt;✓&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&#xA;&lt;h1&gt;A few hurdles&lt;/h1&gt;&#xA;&#xA;&lt;h2&gt;Key management&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;PGP key management was an initial hurdle for me. Having to copy keys&#xA;from one computer to another put me back in the same situation I had&#xA;with KeePass.. syncing.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My solution to this problem is to store my PGP keys on a SmartCard&#xA;(Yubikey 4 in this case). This lets me &amp;ldquo;transfer&amp;rdquo; my PGP key between my&#xA;main computers without issue. It also has the added advantage of&#xA;giving me an ssh key I can use on less trusted machines!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For me, the Yubikey is ideal because of the form factor, however,&#xA;there are other alternatives such as NitroKey.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Remote access&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Because pass and friends sync by way of git, you must expose your git&#xA;repo to be able to use the sync mechanism. I didn&amp;rsquo;t want to expose my&#xA;main repo to the world (even though it is only available via ssh), so&#xA;it is only accessible via my home network.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I have an ssh key per device, and use the &lt;code&gt;command=&lt;/code&gt; option in&#xA;&lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; to force git-only ssh access to less trusted&#xA;devices.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For example, my phone is less trusted than my OpenBSD laptop, so I&#xA;have an entry like this:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;command=&amp;quot;git-shell -c \&amp;quot;$SSH_ORIGINAL_COMMAND\&amp;quot;&amp;quot;,no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa ........ dumbdevice&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This limits the device &lt;code&gt;dumbdevice&lt;/code&gt; to only executing &lt;code&gt;git-shell&lt;/code&gt;!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Conclusion&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;All things considered, this setup takes a little bit to configure&#xA;initially (with keys and git repos.. etc), but its advantages&#xA;out weigh that hurdle for me:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;It&amp;rsquo;s very simple. No databases, no extra exposed services.. etc.&lt;/li&gt;&#xA;&lt;li&gt;It uses existing tools to manage / sync my passwords. I trust ssh way&#xA;more than I trust a web server!&lt;/li&gt;&#xA;&lt;li&gt;The ecosystem is very active.&lt;/li&gt;&#xA;&lt;li&gt;If need be, I can operate entirely without the &amp;ldquo;pass&amp;rdquo; tools via&#xA;something like:&#xA;&lt;code&gt;gpg -d ~/.password-store/Web/google.com | head -n1 | xclip&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;* Currently there is a bug in Firefox on OpenBSD that prevents&#xA;native extensions from functioning.. I hope to get this fixed&#xA;soon! Chromium works fine, however.&lt;/p&gt;&#xA;</description>
 69        <author>Aaron Bieber</author>
 70        <pubDate>Fri, 29 Dec 2017 08:00:00 -0700</pubDate>
 71      </item>
 72      <item>
 73        <title>Using cabal on OpenBSD</title>
 74        <link>https://deftly.net/posts/2017-10-12-using-cabal-on-openbsd.html</link>
 75        <description>&lt;p&gt;Since &lt;a href=&#34;https://undeadly.org/cgi?action=article&amp;amp;sid=20160527203200&#34;&gt;W^X became&#xA;mandatory&lt;/a&gt;&#xA;in OpenBSD, W^X&amp;rsquo;d binaries are only allowed to be executed from&#xA;designated locations (mount points). If you used the auto partition&#xA;layout during install, your &lt;code&gt;/usr/local/&lt;/code&gt; will be mounted with&#xA;&lt;code&gt;wxallowed&lt;/code&gt;. For example, here is the entry for my current machine:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/dev/sd2g on /usr/local type ffs (local, nodev, wxallowed, softdep)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;This is a great feature, but if you build applications outside of the&#xA;&lt;code&gt;wxallowed&lt;/code&gt; partition, you are going to run into some issues,&#xA;especially in the case of &lt;code&gt;cabal&lt;/code&gt; (python as well).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here is an example of what you would see when attempting to do &lt;code&gt;cabal&#xA;install pandoc&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;qbit@slip[1]:~λ cabal update&#xA;Config file path source is default config file.&#xA;Config file /home/qbit/.cabal/config not found.&#xA;Writing default configuration to /home/qbit/.cabal/config&#xA;Downloading the latest package list from hackage.haskell.org&#xA;qbit@slip[0]:~λ cabal install pandoc&#xA;Resolving dependencies...&#xA;.....&#xA;cabal: user error (Error: some packages failed to install:&#xA;JuicyPixels-3.2.8.3 failed during the configure step. The exception was:&#xA;/home/qbit/.cabal/setup-exe-cache/setup-Simple-Cabal-1.22.5.0-x86_64-openbsd-ghc-7.10.3: runProcess: runInteractiveProcess: exec: permission denied (Permission denied)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The error isn&amp;rsquo;t actually what it says. The untrained eye would assume&#xA;permissions issue. A quick check of &lt;code&gt;dmesg&lt;/code&gt; reveals what is really&#xA;happening:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/home/qbit/.cabal/setup-exe-cache/setup-Simple-Cabal-1.22.5.0-x86_64-openbsd-ghc-7.10.3(22924): W^X binary outside wxallowed mountpoint&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;OpenBSD is killing the above binary because it is violating W^X and&#xA;hasn&amp;rsquo;t been safely kept in its &lt;code&gt;/usr/local&lt;/code&gt; corral!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We could solve this problem quickly by marking our &lt;code&gt;/home&lt;/code&gt; as&#xA;&lt;code&gt;wxallowed&lt;/code&gt;, however, this would be heavy handed and reckless (we&#xA;don&amp;rsquo;t want to allow other potentially unsafe binaries to&#xA;execute.. just the cabal stuff).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Instead, we will build all our cabal stuff in &lt;code&gt;/usr/local&lt;/code&gt; by using&#xA;a symlink!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;doas mkdir -p /usr/local/{cabal,cabal/build} # make our cabal and build dirs&#xA;doas chown -R user:wheel /usr/local/cabal    # set perms&#xA;rm -rf ~/.cabal                              # kill the old non-working cabal&#xA;ln -s /usr/local/cabal ~/.cabal              # link it!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;We are almost there! Some cabal packages build outside of&#xA;&lt;code&gt;~/.cabal&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cabal install hakyll&#xA;.....&#xA;Building foundation-0.0.14...                                                   Preprocessing library foundation-0.0.14...&#xA;hsc2hs: dist/build/Foundation/System/Bindings/Posix_hsc_make: runProcess: runInteractiveProcess: exec: permission denied (Permission denied)&#xA;Downloading time-locale-compat-0.1.1.3...&#xA;.....&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Fortunately, all of the packages I have come across that do this all&#xA;respect the &lt;code&gt;TMPDIR&lt;/code&gt; environment variable!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;alias cabal=&#39;env TMPDIR=/usr/local/cabal/build/ cabal&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;With this alias, you should be able to cabal without issue (so far&#xA;pandoc, shellcheck and hakyll have all built fine)!&lt;/p&gt;&#xA;&#xA;&lt;hr /&gt;&#xA;&#xA;&lt;h2&gt;TL;DR&lt;/h2&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# This assumes /usr/local/ is mounted as wxallowed.&#xA;#&#xA;doas mkdir -p /usr/local/{cabal,cabal/build}&#xA;doas chown -R user:wheel /usr/local/cabal&#xA;rm -rf ~/.cabal&#xA;ln -s /usr/local/cabal ~/.cabal&#xA;alias cabal=&#39;env TMPDIR=/usr/local/cabal/build/ cabal&#39;&#xA;cabal install pandoc&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
 76        <author>Aaron Bieber</author>
 77        <pubDate>Tue, 12 Sep 2017 16:35:00 -0600</pubDate>
 78      </item>
 79      <item>
 80        <title>Measuring the weight of an electron</title>
 81        <link>https://deftly.net/posts/2017-06-01-measuring-the-weight-of-an-electron.html</link>
 82        <description>&lt;p&gt;I am going to &amp;ldquo;&lt;strong&gt;Measure the weight of an electron&lt;/strong&gt;&amp;rdquo;! By &amp;ldquo;weight&amp;rdquo;, I&#xA;mean what it takes to make&#xA;&lt;a href=&#34;https://github.com/electron/electron&#34;&gt;Electron&lt;/a&gt; work on OpenBSD.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;This is a long rant. A rant intended to document lunacy,&#xA; hopefully aid others in the future and make myself feel better about&#xA; something I think is crazy. It may seem like I am making an enemy of electron,&#xA; but keep in mind that isn&amp;rsquo;t my intention! The enemy here, is complexity!&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My friend Henry, a canary, is coming along for the ride!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Getting the tools&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;At first glance Electron seems like a pretty solid app, it has decent&#xA;&lt;a href=&#34;https://github.com/electron/electron/tree/master/docs&#34;&gt;docs&lt;/a&gt;, it&amp;rsquo;s&#xA;consolidated in a single repository, has a lot of&#xA;&lt;a href=&#34;https://github.com/electron/electron/stargazers&#34;&gt;visibility&lt;/a&gt;, porting&#xA;it shouldn&amp;rsquo;t be a big deal, right?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;First things first, clone that repo!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;git clone git@github.com:electron/electron.git&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;If you want to follow along, we will be using the &lt;a href=&#34;https://github.com/electron/electron/blob/master/docs/development/build-instructions-linux.md&#34;&gt;build instructions&#xA;for&#xA;linux&lt;/a&gt;&#xA;doc.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Reading through the doc, right off the bat there are a few interesting&#xA;things:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;At least 25GB disk space&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Huh, OK, some how this ~47M repository is going to blow up to 25G? &lt;strong&gt;&lt;em&gt;I&#xA;glance at Henry, he gives me the &amp;ldquo;what?&amp;rdquo; look. We carry on.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Clang 3.4 or later.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;This one isn&amp;rsquo;t odd until we have more context. &lt;em&gt;More on this one later.&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Continuing along with the build, I know I have two versions of &lt;code&gt;clang&lt;/code&gt;&#xA;installed on OpenBSD, one from ports and one in base. Hopefully I will&#xA;be able to tell the build to use one of these versions.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Indeed Electron has that&#xA;&lt;a href=&#34;https://github.com/electron/electron/blob/master/docs/development/build-instructions-linux.md#using-system-clang-instead-of-downloaded-clang-binaries&#34;&gt;ability&lt;/a&gt;!&#xA;Their example is even using the same prefix OpenBSD&amp;rsquo;s clang port!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;So, we run the bootstrap:&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;./script/bootstrap.py -v --clang_dir /usr/local&#xA;Traceback (most recent call last):&#xA;  File &amp;quot;./script/bootstrap.py&amp;quot;, line 10, in &amp;lt;module&amp;gt;&#xA;    from lib.config import BASE_URL, PLATFORM,  enable_verbose_mode, \&#xA;  File &amp;quot;/home/qbit/dev/electron_wut/script/lib/config.py&amp;quot;, line 17, in &amp;lt;module&amp;gt;&#xA;    }[sys.platform]&#xA;KeyError: &#39;openbsd6&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Dang. Looks like we need to tell bootstrap about OpenBSD. Easy enough:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;diff --git a/script/lib/config.py b/script/lib/config.py&#xA;index 58f467b5b..646af08f7 100644&#xA;--- a/script/lib/config.py&#xA;+++ b/script/lib/config.py&#xA;@@ -14,6 +14,7 @@ PLATFORM = {&#xA;   &#39;darwin&#39;: &#39;darwin&#39;,&#xA;   &#39;linux2&#39;: &#39;linux&#39;,&#xA;   &#39;win32&#39;: &#39;win32&#39;,&#xA;+  &#39;openbsd6&#39;: &#39;openbsd&#39;,&#xA; }[sys.platform]&#xA;&#xA; verbose_mode = False&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;We re-run the bootstrap, things seem to be going well.. &lt;strong&gt;&lt;em&gt;Then the&#xA; Henry squeaks: &amp;ldquo;whoa!!&amp;rdquo;&lt;/em&gt;&lt;/strong&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Synchronizing submodule url for &#39;vendor/requests&#39;&#xA;git submodule update --init --recursive&#xA;Cloning into &#39;/home/qbit/dev/electron_wut/vendor/boto&#39;...&#xA;error: object c1eddff4ee3f62b6039f1083651b9118883e7f07: badTimezone: invalid author/committer line - bad time zone&#xA;fatal: Error in object&#xA;fatal: index-pack failed&#xA;fatal: clone of &#39;https://github.com/boto/boto.git&#39; into submodule path &#39;/home/qbit/dev/electron_wut/vendor/boto&#39; failed&#xA;Failed to clone &#39;vendor/boto&#39;. Retry scheduled&#xA;Cloning into &#39;/home/qbit/dev/electron_wut/vendor/breakpad&#39;...&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;We just failed to clone the &lt;code&gt;boto&lt;/code&gt; repo, but the build is still&#xA;going.. does this mean it was an optional dependency and isn&amp;rsquo;t needed&#xA;for the build?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Henry doesn&amp;rsquo;t look happy, none the less, he assures me it&amp;rsquo;s OK to go&#xA; on. What a trooper!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Cloning into &#39;/home/qbit/dev/electron_wut/vendor/requests&#39;...&#xA;error: object 5e6ecdad9f69b1ff789a17733b8edc6fd7091bd8: badTimezone: invalid author/committer line - bad time zone&#xA;fatal: Error in object&#xA;fatal: index-pack failed&#xA;fatal: clone of &#39;https://github.com/kennethreitz/requests&#39; into submodule path &#39;/home/qbit/dev/electron_wut/vendor/requests&#39; failed&#xA;Failed to clone &#39;vendor/requests&#39;. Retry scheduled&#xA;Cloning into &#39;/home/qbit/dev/electron_wut/vendor/boto&#39;...&#xA;error: object c1eddff4ee3f62b6039f1083651b9118883e7f07: badTimezone: invalid author/committer line - bad time zone&#xA;fatal: Error in object&#xA;fatal: index-pack failed&#xA;fatal: clone of &#39;https://github.com/boto/boto.git&#39; into submodule path &#39;/home/qbit/dev/electron_wut/vendor/boto&#39; failed&#xA;Failed to clone &#39;vendor/boto&#39; a second time, aborting&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Wait. Another repository failed to clone? At least this time the build&#xA;failed after trying to clone &lt;code&gt;boto&lt;/code&gt;.. again. I am guessing it tried&#xA;twice because something might have changed between now and the last&#xA;clone? &lt;strong&gt;&lt;em&gt;Off in the distance we catch a familiar tune, it almost sounds&#xA;like Gnarls Barkley&amp;rsquo;s song Crazy, can&amp;rsquo;t tell for sure.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As it turns out, if you are using&#xA;&lt;a href=&#34;https://git-scm.com/docs/git-fsck&#34;&gt;git-fsck&lt;/a&gt;, you are unable to&#xA;clone &lt;a href=&#34;https://github.com/boto/boto/issues/3507&#34;&gt;boto&lt;/a&gt; and&#xA;&lt;a href=&#34;https://github.com/requests/requests/issues/3805&#34;&gt;requests&lt;/a&gt;. Obviously&#xA;the proper fix for his is to not care about the validity of the git&#xA;objects!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So we die a little inside and comment out &lt;code&gt;fsckobjects&lt;/code&gt; in our&#xA;&lt;code&gt;~/.gitconfig&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;&lt;em&gt;I look at Henry, he assures me it&amp;rsquo;s safe to go on.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We re-run bootstrap&amp;hellip; thousands of lines fly past.. &amp;ldquo;&lt;code&gt;npm&#xA;verb... something something&lt;/code&gt;&amp;rdquo;. I can only think npm is puking this&#xA;info for it&amp;rsquo;s on benefit. It definitely isn&amp;rsquo;t for ours!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Bah, another error:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;subprocess.CalledProcessError: Command &#39;[&#39;/usr/local/bin/python&#39;, &#39;/home/qbit/dev/electron_wut/vendor/libchromiumcontent/script/download&#39;, &#39;-s&#39;, &#39;-f&#39;, &#39;-c&#39;, &#39;94c58176db175d72d88621afe8223b4175eecba5&#39;, &#39;--target_arch&#39;, &#39;x64&#39;, &#39;https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent&#39;, &#39;/home/qbit/dev/electron_wut/vendor/download/libchromiumcontent&#39;]&#39; returned non-zero exit status 1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Looks like it&amp;rsquo;s trying to download a pre-built &lt;code&gt;libchromiumcontent&lt;/code&gt;,&#xA;we reference the doc again, finding the &lt;code&gt;--build_libchromiumcontent&lt;/code&gt;&#xA;option. Re-run!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This time we are faced with &lt;code&gt;.&lt;/code&gt;&amp;rsquo;s, I have no idea what is happening:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;/usr/local/bin/python /home/qbit/dev/electron_wut/vendor/libchromiumcontent/script/update -t x64 --defines  make_clang_dir=/usr/local clang_use_chrome_plugins=0&#xA;.......&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Looking in &lt;code&gt;top&lt;/code&gt;, we can see a python process with a WAIT of &lt;code&gt;netio&lt;/code&gt;,&#xA;maybe it&amp;rsquo;s downloading something? Looking in the &lt;code&gt;electron_wut&lt;/code&gt;&#xA;directory reveals a growing file named&#xA;&lt;code&gt;chromium-58.0.3029.110.tar.xz&lt;/code&gt;. We let it finish downloading.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Out of curiosity we look at &lt;code&gt;vendor/libchromiumcontent/script/update&lt;/code&gt;,&#xA;it seems its purpose is to download / extract chromium clang and node,&#xA;good thing we already specified &lt;code&gt;--clang_dir&lt;/code&gt; or it might try to build&#xA;clang again!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;544 dots and 45 minutes later, we have an error! The&#xA;&lt;code&gt;chromium-58.0.3029.110.tar.xz&lt;/code&gt; file is mysteriously not there&#xA;anymore.. Interesting.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Scrolling up in the terminal points us to something disheartening:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Extracting...&#xA;Updating Clang to 296320-1...&#xA;Creating directory /home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/third_party/llvm-build&#xA;Traceback (most recent call last):&#xA;File &amp;quot;/home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/tools/clang/scripts/update.py&amp;quot;, line 902, in &amp;lt;module&amp;gt;&#xA;    sys.exit(main())&#xA;    File &amp;quot;/home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/tools/clang/scripts/update.py&amp;quot;, line 898, in main return UpdateClang(args)&#xA;    File &amp;quot;/home/qbit/dev/electron_wut/vendor/libchromiumcontent/src/tools/clang/scripts/update.py&amp;quot;, line 420, in UpdateClangi assert sys.platform.startswith(&#39;linux&#39;)&#xA;AssertionError&#xA;None&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Wut. &amp;ldquo;&lt;strong&gt;Updating Clang&amp;hellip;&lt;/strong&gt;&amp;rdquo;. Didn&amp;rsquo;t I explicitly say &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; to&#xA;build clang?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;At this point we have to shift projects, no longer are we working on&#xA;Electron.. It&amp;rsquo;s &lt;code&gt;libchromiumcontent&lt;/code&gt; that needs our attention.&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Fixing sub-tools&lt;/h1&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;git clone git@github.com:electron/libchromiumcontent.git&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Following the&#xA;&lt;a href=&#34;https://github.com/electron/libchromiumcontent&#34;&gt;instructions&lt;/a&gt; on this&#xA;repo, we run &lt;code&gt;script/bootstrap&lt;/code&gt;.. it seems to complete without issue!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;On to the next steps:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;script/update -t x64&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Ahh, our old friends the dots! This is the second time waiting 45+&#xA;minutes for a 500+ MB file to download. We are fairly confident it&#xA;will fail, delete the file out from under itself and hinder the&#xA;process even further, so we add an explicit exit to the &lt;code&gt;update&lt;/code&gt;&#xA;script. This way we can copy the file somewhere safe!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;diff --git a/script/update b/script/update&#xA;index 234e4b3..b2639bf 100755&#xA;--- a/script/update&#xA;+++ b/script/update&#xA;@@ -107,6 +107,7 @@ def download_source_tarball(version):&#xA;         sys.stderr.flush()&#xA;         t.write(chunk)&#xA;&#xA;+  sys.exit()&#xA;   sys.stderr.write(&#39;\nExtracting...\n&#39;)&#xA;   sys.stderr.flush()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;544 dots and 43 minutes later&amp;hellip;. &lt;code&gt;chromium-58.0.3029.110.tar.xz&lt;/code&gt; is&#xA;safe!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Fool me once&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;mkdir safe_space&#xA;cp chromium-58.0.3029.110.tar.xz safe_space/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;We remove the &lt;code&gt;sys.exit()&lt;/code&gt; and re-run! Wut.. dots again!? Lets look&#xA;deeper into this &lt;code&gt;update&lt;/code&gt; script:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;if not args.no_download:&#xA;  version = chromium_version()&#xA;  if not is_source_tarball_updated(version):&#xA;    download_source_tarball(version)&#xA;else:&#xA;  print &amp;quot;Skipping Chromium Source Tarball Download&amp;quot;&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Ok, lets try that.. We copy the tar.xz out of its safe_space&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Skipping Chromium Source Tarball Download&#xA;Traceback (most recent call last):&#xA;  File &amp;quot;/home/qbit/dev/libchromiumcontent/vendor/python-patch/patch.py&amp;quot;, line 1136, in &amp;lt;module&amp;gt;&#xA;    patch.apply(options.strip, root=options.directory) or sys.exit(-1)&#xA;  File &amp;quot;/home/qbit/dev/libchromiumcontent/vendor/python-patch/patch.py&amp;quot;, line 778, in apply&#xA;    os.chdir(root)&#xA;OSError: [Errno 2] No such file or directory: &#39;/home/qbit/dev/libchromiumcontent/src/.&#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Sigh. The above (or similar) was repeated about 50 times&amp;hellip; The trend&#xA;here seems to be: &lt;strong&gt;Ignore errors! They are stupid and meaningless&#xA;anyway!&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since &lt;code&gt;def download_source_tarball&lt;/code&gt; should actually be &lt;code&gt;def&#xA;download_source_tarball_then_extract&lt;/code&gt;, we do that part for&#xA;it&amp;hellip; and pat ourselves on the back for having a &lt;code&gt;safe_space&lt;/code&gt;!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;&lt;em&gt;As chromium extracts, Henry and I can&amp;rsquo;t shake the feeling that&#xA; everything until now was just the tip of the iceberg&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We remove the call to &lt;code&gt;update_clang&lt;/code&gt;, because.. well.. we have two&#xA;copies of it already and the Electron doc said everything would be fine&#xA;if we had &amp;gt;= clang 3.4!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Re-run..&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;already patched  third_party/WebKit/Source/core/paint/ThemePainterMac.mm&#xA;already patched  third_party/WebKit/Source/platform/mac/KillRingMac.mm&#xA;qbit@slip[1]:libchromiumcontent[master *%=]λ&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;That &lt;code&gt;[1]&lt;/code&gt; in my PS1 means that the update script exited with the&#xA;return code &lt;code&gt;1&lt;/code&gt;&amp;hellip; but there is no indication of why..&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Henry&amp;rsquo;s lovely yellow plumage seems to be becoming a darker shade of&#xA; yellow.. How much more of this can we take?!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If we have learned anything so far, it has to be &amp;ldquo;errors don&amp;rsquo;t matter!&amp;rdquo;.&#xA;This one, however, warrants further investigation!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;We dig deeper into script/update&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;update_gn()&lt;/code&gt;.. pulls down a binary &lt;code&gt;gn&lt;/code&gt;.. which, interestingly, can&#xA;be generated with the code we have right below our feet&amp;hellip; but for&#xA;some reason, they have this component already built. There is no&#xA;pre-built version for OpenBSD.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;At this point, Henry and I are getting pretty irritated.. it&amp;rsquo;s time to&#xA;bring in some big guns! We are going to leverage the countless hours&#xA;of work that have already been put into properly building these&#xA;components! (novel, right?!)&lt;/p&gt;&#xA;&#xA;&lt;p&gt;We quickly move to &lt;code&gt;/usr/ports/www/chromium&lt;/code&gt;, low and behold, it&amp;rsquo;s the&#xA;&lt;em&gt;exact&lt;/em&gt; version that &lt;code&gt;libchromiumcontent&lt;/code&gt; is trying to build! We&#xA;review the &lt;code&gt;Makefile&lt;/code&gt; to find this gem: &lt;code&gt;2. bootstrap gn, the tool to&#xA;generate ninja files&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Running &lt;code&gt;make configure&lt;/code&gt; quickly gets us a usable &lt;code&gt;gn&lt;/code&gt; binary, we make&#xA;the appropriate directories under src/buildtools, copy &lt;code&gt;gn&lt;/code&gt; in, modify&#xA;our &lt;code&gt;script/update&lt;/code&gt; file:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;diff --git a/script/update b/script/update&#xA;index 234e4b3..b5c4afc 100755&#xA;--- a/script/update&#xA;+++ b/script/update&#xA;@@ -52,9 +52,9 @@ def main():&#xA;&#xA;   return (apply_patches() or&#xA;           copy_chromiumcontent_files() or&#xA;-          update_clang() or&#xA;-          update_gn() or&#xA;-          update_node() or&#xA;+          #update_clang() or&#xA;+          #update_gn() or&#xA;+          #update_node() or&#xA;           run_gn(target_arch, args.defines))&#xA;&#xA;&#xA;@@ -248,6 +248,8 @@ def run_gn(target_arch, defines):&#xA;     gn = os.path.join(SRC_DIR, &#39;buildtools&#39;, &#39;linux64&#39;, &#39;gn&#39;)&#xA;   elif sys.platform == &#39;darwin&#39;:&#xA;     gn = os.path.join(SRC_DIR, &#39;buildtools&#39;, &#39;mac&#39;, &#39;gn&#39;)&#xA;+  elif sys.platform == &#39;openbsd6&#39;:&#xA;+    gn = os.path.join(SRC_DIR, &#39;buildtools&#39;, &#39;openbsd&#39;, &#39;gn&#39;)&#xA;&#xA;   env = os.environ.copy()&#xA;   if sys.platform in [&#39;win32&#39;, &#39;cygwin&#39;]:&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Re-run!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;ERROR at //build/config/sysroot.gni:95:5: Assertion failed.&#xA;    assert(&#xA;    ^-----&#xA;Missing sysroot (//build/linux/debian_wheezy_amd64-sysroot). To fix, run: build/linux/sysroot_scripts/install-sysroot.py --arch=amd64&#xA;See //build/config/sysroot.gni:96:9:&#xA;        exec_script(&amp;quot;//build/dir_exists.py&amp;quot;,&#xA;        ^-----------------------------------&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Wheezy?! Where is that getting set?! &lt;strong&gt;&lt;em&gt;We stop and ponder.. how the&#xA;hell did we get here? What could have possibly warranted abandoning&#xA;makefiles and shell scripts in favor of this monstrosity!?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Just for fun..  lets try to run the second step (after all, the first&#xA;step only produced a &lt;code&gt;1&lt;/code&gt;, right!?)&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;script/build -t x64&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;FML:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;qbit@slip[1]:libchromiumcontent[master *%=]λ script/build -t x64&#xA;Unsupported OS OpenBSD&#xA;No prebuilt ninja binary was found for this system.&#xA;Try building your own binary by doing:&#xA;  cd ~&#xA;  git clone https://github.com/martine/ninja.git -b v1.7.2&#xA;  cd ninja &amp;amp;&amp;amp; ./configure.py --bootstrap&#xA;Then add ~/ninja/ to your PATH.&#xA;Traceback (most recent call last):&#xA;  File &amp;quot;script/build&amp;quot;, line 57, in &amp;lt;module&amp;gt;&#xA;    sys.exit(main())&#xA;  File &amp;quot;script/build&amp;quot;, line 43, in main&#xA;    subprocess.check_call([NINJA, &#39;-C&#39;, os.path.relpath(out_dir), target], env=env)&#xA;  File &amp;quot;/usr/local/lib/python2.7/subprocess.py&amp;quot;, line 186, in check_call&#xA;    raise CalledProcessError(retcode, cmd)&#xA;subprocess.CalledProcessError: Command &#39;[&#39;/home/qbit/dev/libchromiumcontent/vendor/depot_tools/ninja&#39;, &#39;-C&#39;, &#39;src/out-x64/static_library&#39;, &#39;chromiumcontent:chromiumcontent&#39;]&#39; returned non-zero exit status 1&#xA;qbit@slip[1]:libchromiumcontent[master *%=]λ which ninja&#xA;/usr/local/bin/ninja&#xA;qbit@slip[0]:libchromiumcontent[master *%=]λ&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Clearly we are dealing with a beast that is too smart for its own&#xA;good.&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Fixing sub-sub-tools&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Since &lt;code&gt;depot_tools&lt;/code&gt; is a Google project, it&amp;rsquo;s easier to edit the files&#xA;in the &lt;code&gt;vendor&lt;/code&gt; directory and pretend nothing ever happened.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;diff --git a/ninja b/ninja&#xA;index 282cc276..e22cbb9a 100755&#xA;--- a/ninja&#xA;+++ b/ninja&#xA;@@ -37,7 +37,5 @@ case &amp;quot;$OS&amp;quot; in&#xA;   Darwin)    exec &amp;quot;${THIS_DIR}/ninja-mac&amp;quot; &amp;quot;$@&amp;quot;;;&#xA;   CYGWIN*)   exec cmd.exe /c $(cygpath -t windows $0).exe &amp;quot;$@&amp;quot;;;&#xA;   MINGW*)    cmd.exe //c $0.exe &amp;quot;$@&amp;quot;;;&#xA;-  *)         echo &amp;quot;Unsupported OS ${OS}&amp;quot;&#xA;-             print_help&#xA;-             exit 1;;&#xA;+  *)         exec &amp;quot;/usr/local/bin/ninja&amp;quot; &amp;quot;$@&amp;quot;;;&#xA; esac&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Sigh. So many assumptions, lets continue the trend!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;cd ../../&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Re-run &lt;code&gt;script/build -t x64&lt;/code&gt;&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;No luck. At this point we are faced with a complex web of python&#xA;scripts that execute &lt;code&gt;gn&lt;/code&gt; on GN files to produce ninja files&amp;hellip; which&#xA;then build the various components and somewhere in that cluster,&#xA;something doesn&amp;rsquo;t know about OpenBSD&amp;hellip;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;&lt;em&gt;I look at Henry, he is looking a photo of his wife and kids. They&#xA;   are sitting on a telephone wire, the morning sun illuminating their&#xA;   beautiful faces. Henry looks back at me and says &amp;ldquo;It&amp;rsquo;s not worth&#xA;   it.&amp;rdquo;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;&lt;em&gt;We slam the laptop shut and go outside.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
 83        <author>Aaron Bieber</author>
 84        <pubDate>Thu, 01 Jun 2017 08:18:00 -0600</pubDate>
 85      </item>
 86      <item>
 87        <title>Tab completion in OpenBSD&#39;s ksh</title>
 88        <link>https://deftly.net/posts/2017-05-01-openbsd-ksh-tab-complete.html</link>
 89        <description>&lt;h1&gt;OpenBSD&amp;rsquo;s ksh&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;..is the little shell that could. In ~20k lines of code, it has many&#xA;of the same features as more popular shells like zsh and bash. Plus it&#xA;has the added bonus of being &lt;a href=&#34;http://man.openbsd.org/pledge&#34;&gt;pledge(2)&amp;rsquo;d&lt;/a&gt;!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;One of the features OpenBSD&amp;rsquo;s ksh shares with its more popular&#xA;friends is user definable completions! Something that sets it apart,&#xA;however, is the simplicity of these completions. From the man page:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;Custom completions may be configured by creating an array named&#xA;‘complete_command’, optionally suffixed with an argument number&#xA;to complete only for a single argument.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;For example, here is a completion for&#xA;&lt;a href=&#34;http://man.openbsd.org/vmctl&#34;&gt;vmctl(8)&lt;/a&gt; with expansion of defined VM&#xA;names:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;# vmctl&#xA;set -A complete_vmctl -- console load reload start stop reset status&#xA;set -A complete_vmctl_2 -- $(vmctl status | awk &#39;!/NAME/{print $NF}&#39;)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Hats off to Nicholas Marriott nicm@ for implementing it and to&#xA;brynet@ for pointing it out to me! I was close to switching to&#xA;&lt;a href=&#34;https://fishshell.org&#34;&gt;fish&lt;/a&gt; in an attempt to save my wrists.. but&#xA;the ~180k lines of extra (yeah, on top of the 20k!) code in fish was&#xA;kinda scaring me!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For anyone interested, here is a quick comparison of CLOC for a few&#xA;popular shells:&lt;/p&gt;&#xA;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th align=&#34;left&#34;&gt;Shell&lt;/th&gt;&#xA;&lt;th align=&#34;left&#34;&gt;Version&lt;/th&gt;&#xA;&lt;th align=&#34;right&#34;&gt;Total Lines (cloc)&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td align=&#34;left&#34;&gt;ksh&lt;/td&gt;&#xA;&lt;td align=&#34;left&#34;&gt;Mon May  1 07:17:54 UTC 2017&lt;/td&gt;&#xA;&lt;td align=&#34;right&#34;&gt;19680&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td align=&#34;left&#34;&gt;zsh&lt;/td&gt;&#xA;&lt;td align=&#34;left&#34;&gt;5.3.1&lt;/td&gt;&#xA;&lt;td align=&#34;right&#34;&gt;127246&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td align=&#34;left&#34;&gt;fish&lt;/td&gt;&#xA;&lt;td align=&#34;left&#34;&gt;2.5.0&lt;/td&gt;&#xA;&lt;td align=&#34;right&#34;&gt;207597&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&#xA;&lt;tr&gt;&#xA;&lt;td align=&#34;left&#34;&gt;bash&lt;/td&gt;&#xA;&lt;td align=&#34;left&#34;&gt;4.4&lt;/td&gt;&#xA;&lt;td align=&#34;right&#34;&gt;351043&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;I understand LOC isn&amp;rsquo;t a good measure of quality, but it sure does&#xA;mean you have a lot more reading to find that quality!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A full list of my completions can be found &lt;a href=&#34;https://github.com/qbit/dotfiles/blob/master/common/dot_ksh_completions&#34;&gt;here&lt;/a&gt;!&lt;/p&gt;&#xA;</description>
 90        <author>Aaron Bieber</author>
 91        <pubDate>Mon, 01 May 2017 18:18:00 -0600</pubDate>
 92      </item>
 93      <item>
 94        <title>SSH Fingerprint Verification via Tor</title>
 95        <link>https://deftly.net/posts/2017-02-27-ssh-fp-verification-using-tor.html</link>
 96        <description>&lt;h1&gt;The Problem&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;OpenSSH (really, are there any other implementations?) requires &lt;a href=&#34;https://en.wikipedia.org/wiki/Trust_on_first_use&#34;&gt;Trust&#xA;on First Use&lt;/a&gt; for&#xA;fingerprint verification.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Verification can be especially problematic when using remote services&#xA;like VPS or colocation.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;How can you trust that the initial connection isn&amp;rsquo;t being &lt;a href=&#34;https://en.wikipedia.org/wiki/Man-in-the-middle_attack&#34;&gt;Man In The&#xA;Middle&amp;rsquo;d&lt;/a&gt;?&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;My Solution&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;.. for remote hosts, is to use Tor as supplemental&#xA;verification. Fortunately OpenSSH makes this very easy as connections&#xA;can be proxied (&lt;code&gt;ProxyCommand&lt;/code&gt;) via arbitrary commands (&lt;code&gt;socat&lt;/code&gt; in&#xA;this case).&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#!/bin/sh&#xA;&#xA;# To make use of this, you need:&#xA;# - Tor installed / running&#xA;# - socat installed&#xA;# - Line 1 of your ~/.ssh/config should have: &#39;Include ~/.ssh/torify&#39;&#xA;&#xA;if [ $# -lt 1 ];then&#xA;        echo &amp;quot;Please specify hostname to check!&amp;quot;&#xA;        exit 1;&#xA;fi&#xA;&#xA;TFILE=~/.ssh/torify&#xA;HOST=$1&#xA;&#xA;CONF=$(cat &amp;lt;&amp;lt;&#39;EOF&#39;&#xA;Host *&#xA;        ProxyCommand socat STDIO SOCKS4A:localhost:%h:%p,socksport=9050&#xA;EOF&#xA;);&#xA;&#xA;echo &amp;quot;$CONF&amp;quot; &amp;gt; &amp;quot;${TFILE}&amp;quot;&#xA;IP=$(tor-resolve &amp;quot;${HOST}&amp;quot;)&#xA;for i in 1 2 3 4 5; do&#xA;        ssh &amp;quot;${IP}&amp;quot; &amp;amp; sleep 3; kill $!&#xA;done&#xA;&#xA;echo &amp;quot;&amp;quot; &amp;gt; &amp;quot;${TFILE}&amp;quot;&#xA;ssh &amp;quot;$HOST&amp;quot; &amp;amp; sleep 3; kill $!&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;&lt;em&gt;Latest version of this script can be pulled from&#xA;&lt;a href=&#34;https://github.com/qbit/dotfiles/blob/master/bin/verify_ssh_fp&#34;&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The above script makes five cut-short ssh connections (waiting 3&#xA;seconds before cutting the connection by killing the ssh pid) to an IP&#xA;address that is resolved using Tor. It then makes a single non-Tor&amp;rsquo;d&#xA;cut-short connection to print the fingerprint as seen from your&#xA;default outbound connection.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If all six of the output fingerprints match, it&amp;rsquo;s a bit more safe to&#xA;assume that your connection to the remote host isn&amp;rsquo;t being tampered&#xA;with!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Obviously, this solution isn&amp;rsquo;t 100%. Your Tor connection could be&#xA;compromised.. Snakes could be on planes&amp;hellip; etc. So use it at your own risk.&lt;/p&gt;&#xA;</description>
 97        <author>Aaron Bieber</author>
 98        <pubDate>Mon, 27 Feb 2017 09:30:00 -0700</pubDate>
 99      </item>
100      <item>
101        <title>Why I Run OpenBSD</title>
102        <link>https://deftly.net/posts/2016-05-31-why-i-run-openbsd.html</link>
103        <description>&lt;p&gt;This post is about my journey down the OS rabbit hole and how it&#xA;landed me in OpenBSD land as a happy and productive user.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It contains information that is highly opinionated, wildly&#xA;inaccurate, mostly speculation. It is, after all, on the internet!&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;UPI&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;One thing I learned during my travels between OSs: consistency is&#xA;everything.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Most operating systems seem to, at least, keep a consistent interface&#xA;between themselves and binaries / applications. They do this by keeping&#xA;consistent APIs (Application Programming Interfaces) and ABIs&#xA;(Application Binary Interfaces). If you take a binary from a really old&#xA;version of Linux and run or build it on a brand-spanking new install of&#xA;Linux, it will likely &lt;em&gt;Just Work™&lt;/em&gt;. This is great for applications&#xA;and developers of applications. Vendors can build binaries for&#xA;distribution and worry less about their product working when it gets&#xA;out in the wild (sure this binary built in 2016 will run on RedHat&#xA;AS2.1!!).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With all this catering to applications and developers, one would think&#xA;that a similar level of attention would be applied to the &lt;em&gt;users&lt;/em&gt; of&#xA;the applications and systems: User Program Interfaces (UPI) as I like to&#xA;call them!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A good example of a poor UPI is (was?) &lt;code&gt;ifconfig(8)&lt;/code&gt; on Linux. From a&#xA;user&amp;rsquo;s perspective, &lt;code&gt;ifconfig&lt;/code&gt;, a command to &amp;ldquo;configure network&#xA;interface parameters&amp;rdquo; should work on&amp;hellip; well, network interfaces!&#xA;This includes wireless, hard-wired, cell based&amp;hellip; etc.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;On Linux, however, this is no longer the case (at least for some devices).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This inconsistency seems to have come to be when Linux started getting&#xA;wireless support. For some reason someone (vendors, maybe?) decided&#xA;that &lt;code&gt;ifconfig&lt;/code&gt; wasn&amp;rsquo;t a good place to let users interact with their&#xA;wireless device. Maybe they felt their device was special? Maybe there&#xA;were technical reasons? The bottom line is, someone decided to create&#xA;a new utility to manage a wireless device&amp;hellip; and then another one came&#xA;along&amp;hellip; pretty soon there was &lt;code&gt;iwconfig(8)&lt;/code&gt;, &lt;code&gt;iw(8)&lt;/code&gt;, &lt;code&gt;ifconfig(8)&lt;/code&gt;,&#xA;some funky thing that let windows drivers interface with Linux..  and&#xA;one called &lt;code&gt;ip(8)&lt;/code&gt; I am sure there are others I am forgetting, but I&#xA;prefer to forget. I have moved onto greener pastures and the knowledge&#xA;of these programs no longer serves me.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Simply configuring a wireless network on Linux became a huge hassle:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;User&lt;/strong&gt;: Which tool do I use to configure my wireless? &lt;code&gt;ifconfig&lt;/code&gt;&#xA;doesn&amp;rsquo;t seem to be able to help me.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Google[1]&lt;/strong&gt;: Well it depends on what driver you are using.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;User&lt;/strong&gt;: Intel blablablbla.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Google[1] -&amp;gt; Intel Site&lt;/strong&gt;: &lt;code&gt;iwconfig&lt;/code&gt;! The command is going to look&#xA;very similar to &lt;code&gt;ifconfig&lt;/code&gt; but don&amp;rsquo;t let that fool you! It&amp;rsquo;s very&#xA;different and only works with one very specific type of wireless&#xA;device!&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;[1]&lt;/strong&gt; Note, the use of google here. This is very crucial, and the&#xA;very first sign of poor UPI, if the user has to go somewhere outside&#xA;the system to find information on the system, you have already lost.&#xA;Your UPI sucks.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;The Double Drill Set&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;All of this inconsistency with the wireless stuff left me with a&#xA;dirty, uneasay feeling. Where else is this disregard for users&#xA;manifesting? Is there no process that looks at tooling and says:&#xA;&amp;ldquo;Wait, these tools do very similar things from a users&#xA;perspective. Let&amp;rsquo;s not clutter the environment with more tools that do&#xA;&lt;em&gt;almost&lt;/em&gt; the same thing.&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s like having two drills, one that drives screws in, and another&#xA;that take them out.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Maybe none of this is Linux (the kernel)&amp;rsquo;s fault, maybe it&amp;rsquo;s because&#xA;userland is built over here by these people&amp;hellip; and the kernel over&#xA;there by those people. Perhaps it&amp;rsquo;s the job of a distributor like&#xA;Debian or RedHat to keep things consistent for the end user. I don&amp;rsquo;t&#xA;really know, but at this point, it didn&amp;rsquo;t seem like it&amp;rsquo;s a high&#xA;priority for any of them.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;Back and Forth&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Throughout my OS travels, I have consistently gone back and forth&#xA;between Linux and the BSDs. At least yearly, I would have FreeBSD,&#xA;OpenBSD or NetBSD on my main system. Usually this would end after a few&#xA;months because one tiny thing that worked in Linux was missing. Be it&#xA;an application or a driver.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;But then something changed. I decided that I had enough of this dirty&#xA;feeling. I was going to abandon Linux and use one of the BSDs full&#xA;time. If something didn&amp;rsquo;t work, I was going to fix it. If I didn&amp;rsquo;t&#xA;have an application I needed, I was going to port it. But I didn&amp;rsquo;t&#xA;know which BSD to choose. All of them had issues with at least one&#xA;thing I needed, so all were candidates for adoption!&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;The Showdown&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;One month, one BSD. Starting with FreeBSD, then OpenBSD, then NetBSD.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since none of the BSDs completely worked for me, I knew it would be a&#xA;tough journey. There would be sacrifices, there would be work that&#xA;needed to be done.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A few things were clear:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;1) If I found myself googling for information that the system should&#xA;have provided, that system was not the one for me.&#xA;2) If the system had glaring UPI violations, it wasn&amp;rsquo;t the system for me.&#xA;3) If system simplicity was created via overly complex mechanisms, the&#xA;system was not for me.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;Long Story Short&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;OpenBSD won the showdown. It was the most complete, simple, and&#xA;coherent system. The documentation was thorough, the code was easy to&#xA;follow and understand.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It had one command to configure all of the network interfaces!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I didn&amp;rsquo;t have wireless, but I was able to find a cheap USB adapter&#xA;that worked by simply running &lt;code&gt;man -k wireless&lt;/code&gt; and reading about the&#xA;USB entries.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It didn&amp;rsquo;t have some of the applications I use regularly, so I started&#xA;reading about ports (intuitively, via &lt;code&gt;man ports&lt;/code&gt;!).&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;The Test&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Shortly after selecting OpenBSD, I switched my ISP from Comcast to&#xA;Century Link. Early on I decided I would run my modem in &amp;ldquo;bridge&amp;rdquo;&#xA;mode, and have OpenBSD doing all the PPPoE stuff. To test my metal&#xA;(and OpenBSD&amp;rsquo;s) I was going to configure everything without consulting&#xA;the internet!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Armed with ONLY OpenBSD and its excellent documentation, I was able to&#xA;configure an OpenBSD router doing PPPoE, NAT, DNS and DHCP. All&#xA;without installing a single thing outside of the base OS (which, I&#xA;might add, was installed on a 2G CF card with room to spare!) and not&#xA;a single search engine query (no internet, remember? :P)!&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;FastForward to Now&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;OpenBSD is my main OS and the only OS I truly enjoy running. With&#xA;every release it gains new, awesome features that embody simplicity,&#xA;security, and consistency.&lt;/p&gt;&#xA;</description>
104        <author>Aaron Bieber</author>
105        <pubDate>Tue, 31 May 2016 16:04:05 -0600</pubDate>
106      </item>
107      <item>
108        <title>On Shells and Static Paths</title>
109        <link>https://deftly.net/posts/2016-04-26-on-shells-and-static-paths.html</link>
110        <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;&lt;em&gt;In a previous post, I told people not to start their scripts with&#xA;&lt;code&gt;#!/bin/bash&lt;/code&gt;. In this post, I will explain in more detail why you&#xA;shouldn&amp;rsquo;t do this if you want your script to be portable!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Operating systems, they are neat, aren&amp;rsquo;t they? So much diversity, so&#xA;many options! Don&amp;rsquo;t like the shell that comes stock on your OS because&#xA;it doesn&amp;rsquo;t connect to the internet, download a list of packages that&#xA;&lt;em&gt;might&lt;/em&gt; be similar to a mistyped command you haphazardly pasted into&#xA;your terminal? Great, you can install one that does! So many options!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With all these options available to us, how can someone settle on a&#xA;single PATH to contain all this greatness? Why put &lt;code&gt;bash&lt;/code&gt; in &lt;code&gt;/bin&lt;/code&gt;?&#xA;Why not &lt;code&gt;/opt/fancy/oh-bash-my-face/bin&lt;/code&gt;?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Well.. lets not get crazy here&amp;hellip; That&amp;rsquo;s clearly a terrible location&#xA;for &lt;code&gt;bash&lt;/code&gt;, no way it&amp;rsquo;s standard!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Right!&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Lets talk about a specific set of standards, &lt;a href=&#34;http://pubs.opengroup.org/onlinepubs/7990989775/index.html&#34;&gt;The Single UNIX®&#xA;Specification&lt;/a&gt;&#xA;and &lt;a href=&#34;http://pubs.opengroup.org/onlinepubs/9699919799/&#34;&gt;POSIX IEEE Std 1003.1&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s true that not all Unixie operating systems conform to these&#xA;standards, but all of them implement enough to solve the problem of a&#xA;given shell not being installed in &lt;code&gt;/bin&lt;/code&gt;!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;The wisdom of The Grey Ones&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Long ago, the Great Grey Ones knew that not everyone would put things&#xA;in &lt;code&gt;/bin&lt;/code&gt;. They also knew that for a script/binary to be usefull.. it&#xA;needed to be in your PATH environment variable! Because of this.. they&#xA;made statements like:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Applications should note that the standard PATH to the shell cannot&#xA;be assumed to be either /bin/sh or /usr/bin/sh, and should be&#xA;determined by interrogation of the PATH returned by getconf PATH,&#xA;ensuring that the returned pathname is an absolute pathname and not a&#xA;shell built-in.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Both POSIX and SUS define this.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I know what you are thinking: &amp;ldquo;Surely this applies only to &lt;code&gt;sh&lt;/code&gt;, &lt;code&gt;bash&lt;/code&gt;&#xA;is the new standard, &lt;code&gt;bash&lt;/code&gt; is everywhere! Anything that doesn&amp;rsquo;t have&#xA;&lt;code&gt;bash&lt;/code&gt; is old and therefore not used! My &lt;code&gt;bash&lt;/code&gt; is in &lt;code&gt;/bin/bash&lt;/code&gt; -&#xA;yours &lt;strong&gt;MUST&lt;/strong&gt; be as well!&amp;rdquo;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;No!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;What if I told you, some systems like &lt;a href=&#34;http://openbsd.org&#34;&gt;OpenBSD&lt;/a&gt; and&#xA;&lt;a href=&#34;http://freebsd.org&#34;&gt;FreeBSD&lt;/a&gt; do things a little differently. They have&#xA;a clear distinction between &amp;ldquo;base&amp;rdquo; applications and applications that&#xA;are installed via their respective &lt;code&gt;ports&lt;/code&gt; systems.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For various reasons, things like &lt;code&gt;bash&lt;/code&gt; and &lt;code&gt;zsh&lt;/code&gt; are not included in&#xA;&amp;ldquo;base&amp;rdquo;. This means they will be installed outside of the typical &amp;ldquo;/bin,&#xA;/usr/bin&amp;rdquo; directory structure. Which means when you put lines like:&#xA;&lt;code&gt;#!/bin/bash&lt;/code&gt; at the top of your script you are ensuring that your&#xA;script will not run on OpenBSD or FreeBSD (or any other system that has&#xA;&lt;code&gt;bash&lt;/code&gt; installed somewhere else)!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Back to The Grey Ones&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;They planned for this! They gave us nifty tools that allow us to&#xA;invoke these these shells without knowing the explicit path for said&#xA;shell!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Tools like &lt;code&gt;/usr/bin/env&lt;/code&gt; which:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;executes utility after modifying the environment as specified on the&#xA;command line.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Simply calling &lt;code&gt;env&lt;/code&gt; will spit out a list of all your currently set&#xA;variables! These vars get passed to &lt;code&gt;utility&lt;/code&gt; when you execute&#xA;something like &lt;code&gt;env bash&lt;/code&gt; (where &lt;code&gt;bash&lt;/code&gt; is the utility).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This means if we have our scripts execute &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt; as the&#xA;first line of our script, the PATH variable will be set to something&#xA;that is more likely to contain &lt;code&gt;bash&lt;/code&gt; than an explicit declaration&#xA;like &lt;code&gt;/bin/bash&lt;/code&gt; which, as we learned, doesn&amp;rsquo;t exist on some systems!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Conclusion&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Don&amp;rsquo;t be &lt;strong&gt;&lt;em&gt;that guy&lt;/em&gt;&lt;/strong&gt;. If your script is meant to run on a variety&#xA;of systems, follow the advice of The Grey Ones, use something like&#xA;&lt;code&gt;env&lt;/code&gt; to make your scripts portable. I have yet to see a *NIX OS that&#xA;lacks &lt;code&gt;/usr/bin/env&lt;/code&gt;. This includes things like True64.&lt;/p&gt;&#xA;</description>
111        <author>Aaron Bieber</author>
112        <pubDate>Tue, 26 Apr 2016 00:00:00 +0000</pubDate>
113      </item>
114      <item>
115        <title>pledge(2)&#39;ing Xmonad</title>
116        <link>https://deftly.net/posts/2016-03-06-pledge-xmonad.html</link>
117        <description>&lt;h2&gt;Background&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;For those that don&amp;rsquo;t know, &lt;a href=&#34;http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/pledge.2?query=pledge&amp;amp;arch=i386&#34;&gt;pledge(2)&lt;/a&gt; is an OpenBSD specific feature that allows applications to &amp;ldquo;promise&amp;rdquo; to use a subset of system calls. If an app has promised to only use, say, &lt;code&gt;rpath&lt;/code&gt; (obviously this is a contrived example) it would only be allowed to run this subset of system calls: &lt;code&gt;chdir(2)&lt;/code&gt;, &lt;code&gt;getcwd(3)&lt;/code&gt;, &lt;code&gt;openat(2)&lt;/code&gt;, &lt;code&gt;fstatat(2)&lt;/code&gt;, &lt;code&gt;faccessat(2)&lt;/code&gt;, &lt;code&gt;readlinkat(2)&lt;/code&gt;, &lt;code&gt;lstat(2)&lt;/code&gt;, &lt;code&gt;chmod(2)&lt;/code&gt;, &lt;code&gt;fchmod(2)&lt;/code&gt;, &lt;code&gt;fchmodat(2)&lt;/code&gt;, &lt;code&gt;chflags(2)&lt;/code&gt;, &lt;code&gt;chflagsat(2)&lt;/code&gt;, &lt;code&gt;chown(2)&lt;/code&gt;, &lt;code&gt;fchown(2)&lt;/code&gt;, &lt;code&gt;fchownat(2)&lt;/code&gt;, &lt;code&gt;fstat(2)&lt;/code&gt;, &lt;code&gt;getfsstat(2)&lt;/code&gt;. If the app tries to access a system call other than these, the kernel will kill the app with a SIGABRT.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Since the addition of pledge(2) a handful of OpenBSD ports (including ghc) have added support for it! This means we can use pledge(2) in haskell apps like Xmonad!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;When you pledge an app, you need to read through and understand what it is doing so that you can properly set the promises it will use. In larger apps you can make successive calls to pledge(2) from various parts of the app, this allows you to conditionally ratchet down the required promises.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For example, you could make an initial loose pledge of &lt;code&gt;stdio rpath wpath cpath proc exec unix&lt;/code&gt;, then later remove a few calls like so: &lt;code&gt;stdio rpath wpath cpath unix&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The second set of promises listed above is a fairly bad example in this case, as window managers will need &lt;code&gt;proc&lt;/code&gt; and &lt;code&gt;exec&lt;/code&gt; to start new programs.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;Hello Pledge!&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Lets write an extremely limited app that can only make calls from the &lt;code&gt;stdio&lt;/code&gt; set.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import System.OpenBSD.Process ( pledge )&#xA;&#xA;main = do&#xA;    _ &amp;lt;- pledge &amp;quot;stdio&amp;quot; Nothing&#xA;    putStrLn &amp;quot;Hello, World!&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;As a test, you can run with &lt;code&gt;tty&lt;/code&gt; specified instead of &lt;code&gt;stdio&lt;/code&gt;. ghc will be able to build the binary, but upon execution you will see something like following in dmesg:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;hello(21115): syscall 92 &amp;quot;stdio&amp;quot;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h2&gt;Pledged Xmonad&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Finally on to Xmonad! Here is an extremely basic example of a &lt;code&gt;xmonad.hs&lt;/code&gt; file you could use.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;import XMonad&#xA;import System.IO&#xA;import System.OpenBSD.Process ( pledge )&#xA;&#xA;main = do&#xA;    _ &amp;lt;- pledge &amp;quot;stdio rpath proc exec unix&amp;quot; Nothing&#xA;    xmonad $ defaultConfig&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
118        <author>Aaron Bieber</author>
119        <pubDate>Sun, 06 Mar 2016 12:00:00 -0700</pubDate>
120      </item>
121      <item>
122        <title>Experiments in Wood Carving</title>
123        <link>https://deftly.net/posts/2016-01-23-wood-carving-experiment-one.html</link>
124        <description>&lt;h1&gt;Ceder Beard Comb!&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/images/wood-beardcomb.jpg&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;First attempt at a beard comb made of wood! Found it very easy to carve compared to bone!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s a little rough around the edges.. I need to figure out a good way to make the teeth a bit more even!&lt;/p&gt;&#xA;</description>
125        <author>Aaron Bieber</author>
126        <pubDate>Sat, 23 Jan 2016 12:00:00 -0700</pubDate>
127      </item>
128      <item>
129        <title>Manual import of repos into Gogs</title>
130        <link>https://deftly.net/posts/2015-12-31-gogs-manual-import-of-big-repo.html</link>
131        <description>&lt;p&gt;Recently I used setup a &lt;a href=&#34;https://gogs.io/&#34;&gt;Gogs&lt;/a&gt; instance and attempted to pull in some very large&#xA;repositories (OpenBSD source tree). In doing so, I reached a timeout issue during the clone operation.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;    if err = git.Clone(opts.RemoteAddr, repoPath, git.CloneRepoOptions{&#xA;            Mirror:  true,&#xA;            Quiet:   true,&#xA;            Timeout: 10 * time.Minute,&#xA;    }); err != nil {&#xA;            return repo, fmt.Errorf(&amp;quot;Clone: %v&amp;quot;, err)&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The 10 minute timeout listed above was being hit. And updating the code to a larger timeout caused some new issues. So I had to make a workaround!&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Step 1&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Become the git user:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;su - git&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;Step 2&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Now clone the repo into your desired user&amp;rsquo;s repo directory. In my case, this was to be a mirror, so pass that option to git-clone(1):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;git clone --mirror git@sourceurl/repo.git ~/gogs-repositories/qbit/openbsd-src.git/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;h1&gt;Step 3&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Now we need to tell the Gogs db about the repo:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;sqlite3 ./go/src/github.com/gogits/gogs/data/gogs.db&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;then:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;insert into repository (&#xA;    owner_id,&#xA;    lower_name,&#xA;    name,&#xA;    description,&#xA;    website,&#xA;    default_branch,&#xA;    num_watches,&#xA;    num_stars,&#xA;    num_forks,&#xA;    num_issues,&#xA;    num_closed_issues,&#xA;    num_pulls,&#xA;    num_closed_pulls,&#xA;    num_milestones,&#xA;    num_closed_milestones,&#xA;    is_private,&#xA;    is_bare,&#xA;    is_mirror,&#xA;    is_fork,&#xA;    created,&#xA;    updated,&#xA;    enable_wiki,&#xA;    enable_external_wiki,&#xA;    enable_issues,&#xA;    enable_external_tracker,&#xA;    enable_pulls&#xA;) values (&#xA;    1,&#xA;    &#39;openbsd-src&#39;,&#xA;    &#39;openbsd-src&#39;,&#xA;    &#39;Mirror of sthen@s anoncvs repo&#39;,&#xA;    &#39;&#39;,&#xA;    &#39;master&#39;,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    1,&#xA;    0,&#xA;    datetime(&#39;now&#39;),&#xA;    datetime(&#39;now&#39;),&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0,&#xA;    0&#xA;);&#x9;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Obviously you will need to change the strings and &lt;code&gt;owner_id&lt;/code&gt; to those that correspond to your repo&amp;rsquo;s information. Owner ID can be queried from the &lt;code&gt;user&lt;/code&gt; table.&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;Step 4&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Now we need to tell Gogs about our repository mirror relation. To do this, you will need the ID of the repository you just created. This can be acquired by running a select on the &lt;code&gt;repository&lt;/code&gt; table: &lt;code&gt;select * from repository&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Next update the mirror table:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;insert into mirror (repo_id, interval) values (40, 2);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
132        <author>Aaron Bieber</author>
133        <pubDate>Thu, 31 Dec 2015 12:00:00 -0700</pubDate>
134      </item>
135      <item>
136        <title>Setting up networking on OpenBSD hosted VMs</title>
137        <link>https://deftly.net/posts/2015-11-14-openbsd-vm-networking.html</link>
138        <description>&lt;p&gt;With OpenBSD getting a &lt;a href=&#34;http://undeadly.org/cgi?action=article&amp;amp;sid=20151101223132&#34;&gt;native hypervisor&lt;/a&gt;, I figured I would quickly describe my setup for allowing the VMs to access network resources!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This setup is using NAT and IP forwarding.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;First thing, enable forwarding:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;doas echo &amp;quot;net.inet.ip.forwarding=1&amp;quot; &amp;gt;&amp;gt; /etc/sysctl.conf &#xA;# Only run the above if you want this all to start at boot&#xA;sysctl net.inet.ip.forwarding=1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Next we need to configure a &lt;a href=&#34;http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man4/tap.4?query=tap&#34;&gt;tap&lt;/a&gt; interface at &lt;code&gt;tap0&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;cat /etc/hostname.tap0&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;inet 10.10.10.1 255.255.255.0&#xA;up&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Now tell &lt;code&gt;pf&lt;/code&gt; what to do with the packets coming from the &lt;code&gt;tap0&lt;/code&gt; interface:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;match out on $ext_if inet from tap0:network nat-to ($ext_if)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;At this point, you could just manually assign ips to your VMs when booting / installing.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For a bit more automation, we can run &lt;code&gt;dhcpd&lt;/code&gt; on the &lt;code&gt;tap0&lt;/code&gt; interface:&#xA;&lt;code&gt;cat /etc/dhcpd.conf&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;option  domain-name &amp;quot;vm.bolddaemon&amp;quot;;&#xA;option  domain-name-servers 8.8.8.8, 8.8.4.4;&#xA;&#xA;subnet 10.10.10.0 netmask 255.255.255.0 {&#xA;&#x9;option routers 10.10.10.1;&#xA;&#x9;range 10.10.10.5 10.10.10.30;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Pretty nifty, and all of it is in base (on amd64 and i386)!!&lt;/p&gt;&#xA;</description>
139        <author>Aaron Bieber</author>
140        <pubDate>Sat, 14 Nov 2015 12:00:00 -0700</pubDate>
141      </item>
142      <item>
143        <title>Experiments in Bone Carving - Hei matau</title>
144        <link>https://deftly.net/posts/2015-03-21-fish-hook.html</link>
145        <description>&lt;p&gt;Round two in my experiments with bone carving is a &lt;a href=&#34;https://en.wikipedia.org/wiki/Hei_matau&#34;&gt;Hei matau&lt;/a&gt; - a stylised fish hook from Māori legend. I still have quite a bit of finishing to do, but the general shape is complete!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The bone I used (part of a femur) to create this piece is much more suitable to carving than the &lt;a href=&#34;/posts/2015-03-08-bone-carving-experiment-one.html&#34;&gt;rib bone&lt;/a&gt; I had previously used in for the beard comb. It is extremely strong!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The next steps are to finish off the edging and polish!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/images/bone-front.jpg&#34; alt=&#34;Front&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/images/bone-back.jpg&#34; alt=&#34;Back&#34; /&gt;&lt;/p&gt;&#xA;</description>
146        <author>Aaron Bieber</author>
147        <pubDate>Sat, 21 Mar 2015 13:00:00 -0600</pubDate>
148      </item>
149      <item>
150        <title>Experiments in Coffee Roasting</title>
151        <link>https://deftly.net/posts/2015-03-15-coffee-roast.html</link>
152        <description>&lt;h1&gt;Etgiopia Yirga Cheffe Kore Kochoer &amp;amp; Brazil Pulp Natural Fazenda do Sertao&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Beans&lt;/strong&gt;: &lt;sup&gt;50&lt;/sup&gt;&amp;frasl;&lt;sub&gt;50&lt;/sub&gt; of each. (Batch of 100g)&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;First Crack&lt;/strong&gt;: Ooops&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Second Crack&lt;/strong&gt;: Ooops&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Total Roast Time&lt;/strong&gt;: Ooops&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;img src=&#34;/images/coffee_r_1.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;First Crack&lt;/strong&gt;: 2:35&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Second Crack&lt;/strong&gt;: 4:00&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Total Roast Time&lt;/strong&gt;: 4:55&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;img src=&#34;/images/coffee_r_2.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;First Crack&lt;/strong&gt;: 2:08&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Second Crack&lt;/strong&gt;: 3:54&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Total Roast Time&lt;/strong&gt;: 4:34&lt;/p&gt;&lt;/li&gt;&#xA;&#xA;&lt;li&gt;&lt;p&gt;&lt;img src=&#34;/images/coffee_r_3.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
153        <author>Aaron Bieber</author>
154        <pubDate>Sun, 15 Mar 2015 13:00:00 -0600</pubDate>
155      </item>
156      <item>
157        <title>Experiments in Bone Carving - part one</title>
158        <link>https://deftly.net/posts/2015-03-08-bone-carving-experiment-one.html</link>
159        <description>&lt;h1&gt;Beard Comb - first attempt!&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;&lt;img src=&#34;/images/bone-beardcomb1.jpg&#34; alt=&#34;Beard Comb&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I have been interested in bone carving for some time now, but it hasn&amp;rsquo;t been&#xA;until recently that I have actually started doing it! It is proving to be a&#xA;fun and challenging hobby!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Today&amp;rsquo;s project was a Beard Comb carved from a rib bone! In hind sight, rib might&#xA;not have been the best choice for this particular project. The bone is very strong&#xA;length wise, as that is the direction of the &amp;ldquo;grain&amp;rdquo;. This makes for weak teeth.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Some other valuable lessons I learned while undertaking this are:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Use of a jig is very important.&lt;/li&gt;&#xA;&lt;li&gt;Remove all material to form the shape of your project prior to diving into&#xA;aspects like the teeth of the comb.&lt;/li&gt;&#xA;&lt;li&gt;Pick the right bone for the job.&lt;/li&gt;&#xA;&lt;li&gt;Pencil rubs off fast.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;While I was able to &amp;ldquo;finish&amp;rdquo; the comb, it isn&amp;rsquo;t very useful. I broke off three&#xA;teeth while cutting them out (torqued the saw just a bit when taking it out of the&#xA;slot). The teeth are also too thick which prevents the comb from actually being used.&lt;/p&gt;&#xA;</description>
160        <author>Aaron Bieber</author>
161        <pubDate>Sun, 08 Mar 2015 13:00:00 -0600</pubDate>
162      </item>
163      <item>
164        <title>Revisiting the PicoLCD 256x64</title>
165        <link>https://deftly.net/posts/2014-03-20-re-picolcd.html</link>
166        <description>&lt;p&gt;&lt;img src=&#34;/images/banner1.gif&#34; alt=&#34;OpenBSD Banner&#34; /&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Today marks my first commits (&lt;a href=&#34;http://www.openbsd.org/cgi-bin/cvsweb/src/sys/dev/usb/usbdevs.diff?r1=1.626;r2=1.627;f=h&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;http://www.openbsd.org/cgi-bin/cvsweb/src/sys/dev/usb/usbdevs.h.diff?r1=1.638;r2=1.639;f=h&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;http://www.openbsd.org/cgi-bin/cvsweb/src/sys/dev/usb/usb_quirks.c.diff?r1=1.72;r2=1.73;f=h&#34;&gt;3&lt;/a&gt;) to the OpenBSD &lt;code&gt;src&lt;/code&gt; tree (up until now it has all bee in &lt;code&gt;ports&lt;/code&gt; and one in &lt;code&gt;www&lt;/code&gt;)!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;add USB_PRODUCT_ITUNER_USBLCD256x64 as UQ_BAD_HID so libusb can talk via&#xA;interrupt transfers&#xA;&#xA;OK sthen@&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The last commit makes the PicoLCD 256x64 not attach as a &lt;code&gt;HID&lt;/code&gt;, so that it can be used by applications that talk to usb devices with &lt;code&gt;libusb&lt;/code&gt;!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The next step is to finish up the lcdproc driver for it - currently I can only turn on or of the backlight and +,- the contrast!&lt;/p&gt;&#xA;</description>
167        <author>Aaron Bieber</author>
168        <pubDate>Thu, 20 Mar 2014 13:00:00 -0600</pubDate>
169      </item>
170      <item>
171        <title>Hey Kid, I&#39;ma Interpreter!! Stop all the static interpreter referenci&#39;n!</title>
172        <link>https://deftly.net/posts/2014-03-17-stop-all-the-ref.html</link>
173        <description>&lt;p&gt;If you have ever explicitly set the path of an interpreter at the top of a script.. This post is about you.&lt;/p&gt;&#xA;&#xA;&lt;h1&gt;STOP IT!&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Not every system has binaries in the same location!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#!/bin/bash&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;The above might &lt;em&gt;seem&lt;/em&gt; awesome, and it might be tempting to use it, but if you do, and your project is something that I am interested in, you will receive a pull request (&lt;a href=&#34;https://github.com/JuliaLang/julia/pull/5493&#34;&gt;here&lt;/a&gt; are &lt;a href=&#34;https://github.com/nitrogen/nitrogen/pull/67&#34;&gt;some examples&lt;/a&gt;) to change it to:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;On OpenBSD, bash is not in base, meaning it is not installed in &lt;code&gt;/bin&lt;/code&gt; or even &lt;code&gt;/usr/bin&lt;/code&gt;.  It gets plopped right into &lt;code&gt;/usr/local/bin&lt;/code&gt;. Almost all users will have &lt;code&gt;/usr/local/bin&lt;/code&gt; set in their &lt;code&gt;PATH&lt;/code&gt; variable, so use the above and do not be a turdburgler!&lt;/p&gt;&#xA;</description>
174        <author>Aaron Bieber</author>
175        <pubDate>Mon, 17 Mar 2014 13:00:00 -0600</pubDate>
176      </item>
177      <item>
178        <title>Using a picoLCD 256×64 on OpenBSD 4.7</title>
179        <link>https://deftly.net/posts/2012-01-12-picolcd-openbsd.html</link>
180        <description>&lt;p&gt;The first thing you will notice if you connect your fancy picoLCD 256×64 to your OpenBSD box, is that it shows up as a Human Interface Device.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Unfortunately libusb doesn’t know what to do with devices on bsd systems that are NOT using the &lt;strong&gt;ugen&lt;/strong&gt; driver:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt; 464     if (strncmp(di.udi_devnames[0], &amp;quot;ugen&amp;quot;, 4) != 0)&#xA; 465       /* best not to play with things we don&#39;t understand */&#xA; 466       continue;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Fine libusb!  We will have to come up with another way to use this screen!  OR!  We could tell OpenBSD to use ugen when ever it sees the lcd! :D&lt;/p&gt;&#xA;&#xA;&lt;p&gt;To do that – you need the the OpenBSD source, knowledge of how to build Open’s kernel, and my patch!  Getting the source is beyond the scope of this little post.. so you will have to rtfm that action.&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;cd to the usb source directory: cd /usr/src/sys/dev/usb&lt;/li&gt;&#xA;&lt;li&gt;Download the patch ( md5: 85e7498826635c612ede672f5e295e7a ): &lt;a href=&#34;http://qbit.devio.us/picoLCD256x64.patch&#34;&gt;picoLCD256x64.patch&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Apply said patch: patch -p1 &amp;lt; picoLCD256x64.patch&lt;/li&gt;&#xA;&lt;li&gt;pkg_add libusb&lt;/li&gt;&#xA;&lt;li&gt;Compile your kernel, install and reboot!&lt;/li&gt;&#xA;&lt;li&gt;Once you are running your freshly compiled kernel, download the lcd4linux-256×64 source from &lt;a href=&#34;http://picolcd.com/drivers/&#34;&gt;http://picolcd.com/drivers/&lt;/a&gt; .  Apply this patch ( md5: 3852103e3e5a13a3cd6b0c49389688f6 ): &lt;a href=&#34;http://qbit.devio.us/lcd4linux-256x64.patch&#34;&gt;lcd4linux-256×64.patch&lt;/a&gt;, compile ( You will have to play around with the plugins as some of them use linux’s proc fs and are not compatible with OpenBSD ).&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;Now check out the sample config files and have fun!&lt;/p&gt;&#xA;</description>
181        <author>Aaron Bieber</author>
182        <pubDate>Thu, 12 Jan 2012 12:00:00 -0700</pubDate>
183      </item>
184      <item>
185        <title>Using VIM to make erlang pretty</title>
186        <link>https://deftly.net/posts/2010-03-12-vi-pretty-erlang.html</link>
187        <description>&lt;p&gt;I recently read an article ( Which no longer exists  ) talking about purtifying erlang. This inspired me to create a quick function in vim to do this for me!&#xA;Here it is:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;function! ErlPretty()&#xA;    silent !erl -noshell -eval &#39;erl_tidy:file(&amp;quot;%&amp;quot;,[verbose]).&#39; -s erlang halt&#xA;endfunction&#xA;nmap ep :execute ErlPretty()&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
188        <author>Aaron Bieber</author>
189        <pubDate>Fri, 12 Mar 2010 12:15:00 -0700</pubDate>
190      </item>
191      <item>
192        <title>Concurrent Hello with Erlang</title>
193        <link>https://deftly.net/posts/2010-03-12-concurrent-hello.html</link>
194        <description>&lt;p&gt;I recently picked up a copy of Joe Armstrong’s superb Programming Erlang book ( from the folks @ pragprog.com ). While reading the chapter on concurrent programming I was completely stumped by one of the examples. It basically creates a “server” and “client” and allows for message passing between the two. I found it very difficult to follow the passing of messages from a to b, and back.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Enter &lt;code&gt;chello.erl&lt;/code&gt;! I created a slightly modified version of Joe’s example that uses some &lt;code&gt;io:format&lt;/code&gt; to tell you what’s going on. Hope someone finds this useful.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-erlang&#34;&gt;-module (chello).&#xA;-export ([loop/0, rpc/2]).&#xA;&#xA;rpc(Pid, Request) -&amp;gt;&#xA;    io:format(&amp;quot;rpc[~p]  sending ~p to ~p~n&amp;quot;, [self(), Request, Pid]),&#xA;    Pid ! {self(), Request},&#xA;    receive&#xA;        Response -&amp;gt;&#xA;            io:format(&amp;quot;rpc[~p]  responding with : ~p~n&amp;quot;, [self(), Response]),&#xA;            {Pid,Response}&#xA;    end.&#xA;&#xA;loop() -&amp;gt;&#xA;receive&#xA;    {From, {hello}} -&amp;gt;&#xA;        io:format(&amp;quot;loop[~p] received info from: ~p~n&amp;quot;, [self(), From]),&#xA;        From ! {self(), &amp;quot;Hello&amp;quot;},&#xA;        loop();&#xA;    {From, {goodbye}} -&amp;gt;&#xA;        io:format(&amp;quot;loop[~p] received info from: ~p~n&amp;quot;, [self(), From]),&#xA;        From ! {self(),&amp;quot;Goodbye&amp;quot;},&#xA;        loop();&#xA;    {From, Other} -&amp;gt;&#xA;        io:format(&amp;quot;loop[~p] received info from: ~p~n&amp;quot;, [self, From]),&#xA;        From ! {self(),{error, Other}},&#xA;        loop()&#xA;    end.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;p&gt;Run from the erl shell with:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code&gt;1&amp;gt; Pid = spawn(fun chello:loop/0).&#xA;&#xA;&amp;lt;0.38.0&amp;gt;&#xA;&#xA;2&amp;gt; chello:rpc(Pid, {hello}).&#xA;rpc[&amp;lt;0.31.0&amp;gt;] sending {hello} to &amp;lt;0.38.0&amp;gt;&#xA;&#xA;loop[&amp;lt;0.38.0&amp;gt;] received info from: &amp;lt;0.31.0&amp;gt;&#xA;&#xA;rpc[&amp;lt;0.31.0&amp;gt;] responding with : {&amp;lt;0.38.0&amp;gt;,”Hello”}&#xA;&#xA;{&amp;lt;0.38.0&amp;gt;,{&amp;lt;0.38.0&amp;gt;,”Hello”}}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</description>
195        <author>Aaron Bieber</author>
196        <pubDate>Fri, 12 Mar 2010 12:01:00 -0700</pubDate>
197      </item>
198    </channel>
199  </rss>