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