<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts | Craig Hesling</title><link>https://new.craighesling.com/post/</link><atom:link href="https://new.craighesling.com/post/index.xml" rel="self" type="application/rss+xml"/><description>Posts</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><image><url>https://new.craighesling.com/media/icon_hud2fdbe3c21f96e183bc7961971f91459_788_512x512_fill_lanczos_center_3.png</url><title>Posts</title><link>https://new.craighesling.com/post/</link></image><item><title>Insecure Temp WiFi Networks</title><link>https://new.craighesling.com/post/insecure-temp-wifi-networks/</link><pubDate>Mon, 04 Feb 2019 14:06:12 -0500</pubDate><guid>https://new.craighesling.com/post/insecure-temp-wifi-networks/</guid><description>&lt;h2 id="introduction-of-problem">Introduction of Problem&lt;/h2>
&lt;p>After traveling to SF and connecting to numerous free WiFi networks, I have
returned back to Pittsburgh and realized that my laptop still likes to connect
to unsecured xfinitywifi over my normal house network.
This would be the same deal if my laptop happen to see another insecure network
named SFO-AIRPORT-FREE-WIFI or the hotel&amp;rsquo;s free WiFi network.&lt;/p>
&lt;p>I understand that I could drop the connection priority of these insecure/free
networks in the network manager, but it still exposes a human centric
security flaw.&lt;/p>
&lt;p>The concern is that, by default, the Gnome network manager places newly connected WiFi network at the top of the preferred networks priority list.
So, if your laptop sees these newly connected networks in the same vicinity as your older home network, they connect to the temporary network instead of your trusted home network.
This wouldn&amp;rsquo;t be a serious issue if it weren&amp;rsquo;t for the fact that these temporary networks do not require any authentication. Anyone can create a network with the same name and no authentication and BOOM, your laptop connects.&lt;/p>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>I will just jump right to my point. I feel you should have an easy option to specify an expiration for a WiFi network, on connection.
The purpose would be to make sure your laptop will not connect to it after your trip or outing to Starbucks.&lt;/p>
&lt;p>An even easier half-way solution, would be to automatically drop the priority
of insecure networks to the very lowest.
The hope is that you laptop would always prefer you secure authenticated networks over a rouge insecure network, although I suspect this may not always be the case.&lt;/p>
&lt;h2 id="accidental-experiment">Accidental Experiment&lt;/h2>
&lt;p>I have been more cognizant of this issue ever since my little accidental experiment.&lt;/p>
&lt;p>While on campus, I configured a RaspberryPi to connect to my school&amp;rsquo;s insecure
WiFi network named &lt;code>CMU&lt;/code>. This was happening before the school offered their secure
option called &lt;code>CMU-SECURE&lt;/code>. I was never a fan of lugging around a monitor+keyboard, so I would interact with the Pi over ssh.
I then returned home and realized that I hadn&amp;rsquo;t configured it with my home WiFi network.
At the moment, I really didn&amp;rsquo;t feel like grabbing a monitor+keyboard or ripping out the SD card to write a new network. So, I simply created a guest WiFi network named &lt;code>CMU&lt;/code>, so that it would just connect. The plan was to have it connect and then add my WiFi network to the wpa_supplicant.conf.
It worked perfectly, but one might say that it worked a bit too well.&lt;/p>
&lt;p>I found the RPi&amp;rsquo;s IP in the DHCP Lease log, but I also found tons of other mysterious devices that I hadn&amp;rsquo;t ever seen before. Since I live near many other CMU students, I immediately realized that my neighbors laptops had automatically jumped on my CMU network.&lt;/p>
&lt;p>This obviously exposes an issue, where saved insecure networks can be used to grab traffic from unsuspecting devices. Not good! You might assume you traffic is broadcasted for anyone at Starbucks, but you assume it is safe(er) at your house.&lt;/p>
&lt;p>We can fix this issue.&lt;/p>
&lt;h2 id="call-to-action">Call to action&lt;/h2>
&lt;p>Calling on all Gnome, Windows, Android, and OSX developers.&lt;/p>
&lt;p>Please add an option to make WiFi networks temporary and have expiration dates.
It would be nice to check a box and specify an expiration date during the first
connect stage.&lt;/p>
&lt;p>At the very least, please make insecure networks the automatic lowest priority.
If this already has a solution that I am not aware of, please comment below.&lt;/p></description></item><item><title>Let's Encrypt Root CA Cert</title><link>https://new.craighesling.com/post/lets-encrypt-root-ca/</link><pubDate>Sat, 13 Oct 2018 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/lets-encrypt-root-ca/</guid><description>&lt;h2 id="overview--explination">Overview / Explination&lt;/h2>
&lt;p>Since Let&amp;rsquo;s Encrypt&amp;rsquo;s own root certificate authority, &lt;code>ISRG Root X1&lt;/code>, is still quite new and not commonly trusted.
To get around this issue, Let&amp;rsquo;s Encrypt&amp;rsquo;s intermediate has be graciously cross-signed by IdentTrust&amp;rsquo;s root certificate authority &lt;code>DST Root CA X3&lt;/code>, which is commonly trusted by clients.&lt;/p>
&lt;p>What this means is that most certificates issued by Let&amp;rsquo;s Encrypt have an origin of trust from IdentTrust&amp;rsquo;s root CA.&lt;/p>
&lt;p>Take for example the OpenChirp MQTT server. We can use &lt;code>openssl s_client&lt;/code> to inspect the certificate presented to the user.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">openssl s_client -connect mqtt.openchirp.io:8883
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">verify return:1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">depth=1 C = US, O = Let&amp;#39;s Encrypt, CN = Let&amp;#39;s Encrypt Authority X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">verify return:1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">depth=0 CN = mqtt.openchirp.io
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">verify return:1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">---
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Certificate chain
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 0 s:/CN=mqtt.openchirp.io
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> i:/C=US/O=Let&amp;#39;s Encrypt/CN=Let&amp;#39;s Encrypt Authority X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 1 s:/C=US/O=Let&amp;#39;s Encrypt/CN=Let&amp;#39;s Encrypt Authority X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> i:/O=Digital Signature Trust Co./CN=DST Root CA X3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">---
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The beginning of the output shows the root is &lt;code>CN = DST Root CA X3&lt;/code>, which doesn&amp;rsquo;t look like Let&amp;rsquo;s Encrypt&amp;rsquo;s own &lt;code>ISRG Root X1&lt;/code>.&lt;/p>
&lt;p>So, if you need to present the root CA cert to some program (for verification), you need to present IdentTrust&amp;rsquo;s root CA cert. See the next section to learn how to grab a usable x509 PEM formatted cert.&lt;/p>
&lt;h2 id="grab-cert-and-convert">Grab Cert and Convert&lt;/h2>
&lt;p>If we want to present the trusted root CA cert for a Let&amp;rsquo;s Encrypt issued certificate, we need to present the IdentTrust root CA cert. More specifically, we need to reference the &lt;code>TrustID X3&lt;/code> root cert.
The only problem with this is that IdentTrust only offers their certificate in PKCS7 binary format (&lt;code>.p7b&lt;/code>), which is unusable in a lot of reasonable applications. We need x509 PEM format.&lt;/p>
&lt;p>The following instructions will show how to compose the x509 &lt;code>.pem&lt;/code> file for the &lt;code>DST Root CA X3&lt;/code> cert.&lt;/p>
&lt;h3 id="tldr">TLDR&lt;/h3>
&lt;p>At the time of writing this, the following wget line was capable of grabbing the &lt;code>TrustID X3&lt;/code> cert in p7b format.
The next openssl would convert that &lt;code>.p7b&lt;/code> file to an x509 &lt;code>.pem&lt;/code> file for normal use.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">wget https://www.identrust.com/node/935 -O trustidrootx3_chain.p7b
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">openssl pkcs7 -inform DER -in trustidrootx3_chain.p7b -print_certs -outform PEM -out trustidrootx3_chain.pem
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can then use the &lt;code>trustidrootx3_chain.pem&lt;/code> as the CAfile parameter of client programs.&lt;/p>
&lt;h3 id="fallback-instructions">Fallback Instructions&lt;/h3>
&lt;p>If the above commands failed, you can download the PKCS7 binary file (&lt;code>.p7b&lt;/code>) file from the IdentTrust &lt;a href="https://www.identrust.com/support/downloads" target="_blank" rel="noopener">download page&lt;/a> bellow.&lt;/p>
&lt;p>To convert that PKCS7 binary file to x509 PEM, use the following openssl command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">openssl pkcs7 -inform DER -in &amp;lt;THE_DOWNLOADED_P7B_CERT&amp;gt; -print_certs -outform PEM -out trustidrootx3_chain.pem
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can then use the &lt;code>trustidrootx3_chain.pem&lt;/code> as the CAfile parameter of client programs.&lt;/p>
&lt;h2 id="example-usage-of-x509-pem">Example Usage of x509 PEM&lt;/h2>
&lt;h3 id="mosquitto-client">Mosquitto Client&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">mosquitto_sub -v -i monitor&lt;span class="nv">$RANDOM&lt;/span> -h mqtt.openchirp.io -p &lt;span class="m">8883&lt;/span> --cafile ./trustidrootx3_chain.pem -u &amp;lt;USER&amp;gt; -p &amp;lt;TOKEN&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="links">Links&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://letsencrypt.org/certificates/" target="_blank" rel="noopener">Let&amp;rsquo;s Encrypt Certificates and Explination&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.identrust.com/support/downloads" target="_blank" rel="noopener">IdentTrust Download&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>GOBF</title><link>https://new.craighesling.com/post/gobf/</link><pubDate>Fri, 04 May 2018 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/gobf/</guid><description>&lt;h2 id="intro">Intro&lt;/h2>
&lt;p>I have always been fascinated by compilers.
I think the idea of representing one language&amp;rsquo;s structure inside
of another language is just downright cool.
Furthermore, the ability to analyze another language and optimize it really peaks my interest.&lt;/p>
&lt;p>Recently, I worked on a project that would allow you to more precisely manage
which processor core a set of Goroutines would run on.
The idea was that Goroutines that communicate more than they process independently
would benefit from sharing that same processor core&amp;rsquo;s cache. I called them
M-Groups. The implementation called for modifying the &lt;code>runtime&lt;/code> package
and the Go scheduler.
While ripping through the Go internals, I stumbled upon quite a bit of the Go
compiler code, including the SSA library. As I ripped into it more,
I started to form an itch to make my own compiler of some kind.&lt;/p>
&lt;p>Fast forward a few months and I found myself staring at some examples of
my favorite simple esoteric language, &lt;a href="https://en.wikipedia.org/wiki/Brainfuck" target="_blank" rel="noopener">BF&lt;/a>.
BF is the perfect language to write a compiler / optimizer for because of its
extremely minimal syntax.
It only has 8 possible syntax items(called commands), &lt;code>&amp;lt;&amp;gt;+-.,[]&lt;/code>, but
those simple syntax items quickly form complex programs
(not in the sense of awesome functionality).&lt;/p>
&lt;p>Here is Hello World in BF&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-brainfuck" data-lang="brainfuck">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">++++++++&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++++&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="k">[&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="k">]&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">---&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">+++++++&lt;/span>&lt;span class="nt">..&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nb">-&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;lt;&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">+++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">------&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nb">--------&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&amp;gt;&lt;/span>&lt;span class="nb">+&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="nv">&amp;gt;&lt;/span>&lt;span class="nb">++&lt;/span>&lt;span class="nt">.&lt;/span>&lt;span class="c">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="gobf-overview">GOBF Overview&lt;/h2>
&lt;p>Introducing GOBF, an interpreter/optimizer/compiler/code_generator for the BF language.
It has two primary modes of operation, interpreting/running (as-is) and
converting BF to optimized Go code.&lt;/p>
&lt;h3 id="interpreting">Interpreting&lt;/h3>
&lt;p>Interpreting and running was the first mode of operation that really just
served to solidify my understanding of the BF language.
It simply sets up a virtual environment for the BF program and acts on each
syntax item as they come. There is no optimization here.&lt;/p>
&lt;h3 id="optimizing--compiling">Optimizing / Compiling&lt;/h3>
&lt;p>Next, I wanted to focus on how I would be able to generate super fast
binaries from my BF programs.
I considered lots of approaches, but the two most prominent ones were to
directly assemble a binary from the BF commands and convert BF to equivalent Go code.&lt;/p>
&lt;p>Directly assemble an x86 binary from the the BF commands seems like a natural
extension, since BF forces the programmer to act somewhat like a state machine.
The downside to this approach is that it would lack portability and would loose
out on further architectural optimizations that are found in modern compilers.&lt;/p>
&lt;p>I ultimately chose the ladder solution, where I convert the BF commands into
equivalent Go code.
Although it seems like a bulky implementation strategy, the program&amp;rsquo;s
functionality is quite limited and we gain the builtin compiler inlining.&lt;/p>
&lt;p>I have designed GOBF to parse BF programs and generate a internal
intermediate representation(IR) that resembles a tree.
The next major observation that BF contains lots of repetitive actions,
like &lt;code>++++++++&lt;/code>, which increments the local accumulator eight times, only to
save the value &lt;code>8&lt;/code>.
These repetitive actions can easily be smashed into a single operation, which
can yield massive speedups.
The GOBF optimizer traverses the IR tree and coalesces these
repetitive actions into a more descriptive single action.&lt;/p>
&lt;p>When the optimizer finishes, GOBF generates Go code from the IR
and optionally compiles it.&lt;/p>
&lt;h2 id="benchmarking">Benchmarking&lt;/h2>
&lt;p>I ran some of the typical BF programs you can find on the internet.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>BF Program&lt;/th>
&lt;th>Run Time&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>mandelbrot.b&lt;/td>
&lt;td>8.162s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>hanoi.b&lt;/td>
&lt;td>5.401s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>helloworld.b&lt;/td>
&lt;td>0.003s&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;div class="alert alert-note">
&lt;div>
Running on an Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
&lt;/div>
&lt;/div>
&lt;h2 id="future-work">Future Work&lt;/h2>
&lt;p>I would like to create a reverse code generator that takes a high-level
language, such as Go, and generates BF.&lt;/p>
&lt;h3 id="links">Links&lt;/h3>
&lt;p>&lt;a href="https://github.com/linux4life798/gobf" target="_blank" rel="noopener">GOBF on Github&lt;/a>&lt;/p></description></item><item><title>Regenerate Chrome App/Extension Desktop Shortcuts</title><link>https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/</link><pubDate>Wed, 20 Dec 2017 11:30:41 -0500</pubDate><guid>https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/</guid><description>&lt;details class="toc-inpage d-print-none " open>
&lt;summary class="font-weight-bold">Table of Contents&lt;/summary>
&lt;nav id="TableOfContents">
&lt;ul>
&lt;li>&lt;a href="#description">Description&lt;/a>&lt;/li>
&lt;li>&lt;a href="#here-is-how-to-fix-it">Here is how to fix it&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#method-1">Method 1&lt;/a>&lt;/li>
&lt;li>&lt;a href="#method-2">Method 2&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/nav>
&lt;/details>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>This is a quick how-to for regenerating the &lt;code>.desktop&lt;/code> shortcuts
associated with Google Chrome Apps or Extensions.&lt;/p>
&lt;details class="spoiler " id="spoiler-1">
&lt;summary>Rant&lt;/summary>
&lt;p>&lt;p>Being able to launch your favorite Chrome App/Extension straight
from your desktop manager&amp;rsquo;s launcher is a big win in my book.
My typical go-to is Google Keep. With my Gnome Shell setup, all I
have to do is hit the &lt;code>Super&lt;/code> key on my keyboard to bring up the
searchable Gnome launcher, ever so slightly start typing &lt;code>k&lt;/code> &lt;code>e&lt;/code> &lt;code>e&lt;/code> &lt;code>p&lt;/code>,
and pound the enter key. &lt;em>Presto&lt;/em>, I&amp;rsquo;m in my notes taking app.&lt;/p>
&lt;p>Every once in a while, a desktop shortcut disappears
(possibly self inflicted) or becomes corrupt.
The monotony of traversing through Chrome, to the Apps menu,
and clicking on the correct App/Extension tile haunts me to this day.&lt;/p>
&lt;p>This article is needed due to the dearth of information
related to Chrome Extension desktop shortcuts for Linux
desktop environments. I also needed a good tutorial to kickoff my Posts section.&lt;/p>
&lt;/p>
&lt;/details>
&lt;h2 id="here-is-how-to-fix-it">Here is how to fix it&lt;/h2>
&lt;h3 id="method-1">Method 1&lt;/h3>
&lt;ol>
&lt;li>Go to the All Apps page.
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="All apps" srcset="
/post/chrome-app-extension-desktop-shortcut/all-apps-menu-launcher_hu82f108345a474bb3c3cadc90be7606ee_1018_362ae99b347a562a126643fbafdd20a3.webp 400w,
/post/chrome-app-extension-desktop-shortcut/all-apps-menu-launcher_hu82f108345a474bb3c3cadc90be7606ee_1018_1551056afcee80194757d69d39d950cb.webp 760w,
/post/chrome-app-extension-desktop-shortcut/all-apps-menu-launcher_hu82f108345a474bb3c3cadc90be7606ee_1018_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/all-apps-menu-launcher_hu82f108345a474bb3c3cadc90be7606ee_1018_362ae99b347a562a126643fbafdd20a3.webp"
width="69"
height="28"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
This is also the URL &lt;code>chrome://apps&lt;/code>.&lt;/li>
&lt;li>Right click on the App or Extension you wish to regenerate a shortcut for.
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="App right-click menu" srcset="
/post/chrome-app-extension-desktop-shortcut/app-right-click-menu_hub6c3b39d92fc7ee62d1ad816ef758d0b_33658_12789b759a4d261762e6bb1f0a1c5a00.webp 400w,
/post/chrome-app-extension-desktop-shortcut/app-right-click-menu_hub6c3b39d92fc7ee62d1ad816ef758d0b_33658_469a63b2745f3802c89d33f1cd3ecb8c.webp 760w,
/post/chrome-app-extension-desktop-shortcut/app-right-click-menu_hub6c3b39d92fc7ee62d1ad816ef758d0b_33658_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/app-right-click-menu_hub6c3b39d92fc7ee62d1ad816ef758d0b_33658_12789b759a4d261762e6bb1f0a1c5a00.webp"
width="481"
height="481"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/li>
&lt;li>Click &lt;code>Create shortcuts...&lt;/code>&lt;/li>
&lt;li>Deselect &lt;code>Desktop&lt;/code>, select &lt;code>Application menu&lt;/code>, and click &lt;code>Create&lt;/code>.
&lt;em>A &lt;code>Desktop&lt;/code> shortcut is pointless when you have Desktop icons disabled in Gnome Shell. [default for Gnome Shell]&lt;/em>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="App Details menu" srcset="
/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_3fa38343896cc84f928c4346dfc34a13.webp 400w,
/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_c12fbcf83a86ca1fd5f41b9491d1ad73.webp 760w,
/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_3fa38343896cc84f928c4346dfc34a13.webp"
width="445"
height="245"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/li>
&lt;/ol>
&lt;h3 id="method-2">Method 2&lt;/h3>
&lt;ol>
&lt;li>Press the &lt;code>three vertical dots&lt;/code> in the top right of the browser.&lt;/li>
&lt;li>Navigate to &lt;code>More tools&lt;/code> and then &lt;code>Extensions&lt;/code>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Extensions menu" srcset="
/post/chrome-app-extension-desktop-shortcut/extension-menu_hua477484d3daabe2e4562eb49e450ad3e_43007_672b4da89cc8c02d3d55752bf49b9e3e.webp 400w,
/post/chrome-app-extension-desktop-shortcut/extension-menu_hua477484d3daabe2e4562eb49e450ad3e_43007_3ea45ceb534a6c5f4f1f04c5069b34cd.webp 760w,
/post/chrome-app-extension-desktop-shortcut/extension-menu_hua477484d3daabe2e4562eb49e450ad3e_43007_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/extension-menu_hua477484d3daabe2e4562eb49e450ad3e_43007_672b4da89cc8c02d3d55752bf49b9e3e.webp"
width="642"
height="642"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/li>
&lt;li>Click the &lt;code>Details&lt;/code> linked text on the App or Extension you wish to regenerate a shortcut for.
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="App Details" srcset="
/post/chrome-app-extension-desktop-shortcut/app-details_hu4e8e07b20272b8e43df386236ad035eb_11431_fddc99990184da264ac2176a45b35da7.webp 400w,
/post/chrome-app-extension-desktop-shortcut/app-details_hu4e8e07b20272b8e43df386236ad035eb_11431_b0bb3b2907d51d879d52ae23725339bf.webp 760w,
/post/chrome-app-extension-desktop-shortcut/app-details_hu4e8e07b20272b8e43df386236ad035eb_11431_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/app-details_hu4e8e07b20272b8e43df386236ad035eb_11431_fddc99990184da264ac2176a45b35da7.webp"
width="229"
height="169"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/li>
&lt;li>Click &lt;code>Create shortcuts...&lt;/code>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="App Details menu" srcset="
/post/chrome-app-extension-desktop-shortcut/app-details-menu_hu76bad809ef0df104cb9571677bc851fe_37062_298d4a9165741d8991951f513ecea49a.webp 400w,
/post/chrome-app-extension-desktop-shortcut/app-details-menu_hu76bad809ef0df104cb9571677bc851fe_37062_ee8d72e1ca52ed127ead5a21c26741d7.webp 760w,
/post/chrome-app-extension-desktop-shortcut/app-details-menu_hu76bad809ef0df104cb9571677bc851fe_37062_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/app-details-menu_hu76bad809ef0df104cb9571677bc851fe_37062_298d4a9165741d8991951f513ecea49a.webp"
width="432"
height="560"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/li>
&lt;li>Deselect &lt;code>Desktop&lt;/code>, select &lt;code>Application menu&lt;/code>, and click &lt;code>Create&lt;/code>.
&lt;em>A &lt;code>Desktop&lt;/code> shortcut is pointless when you have Desktop icons disabled in Gnome Shell. [default for Gnome Shell]&lt;/em>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="App Details menu" srcset="
/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_3fa38343896cc84f928c4346dfc34a13.webp 400w,
/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_c12fbcf83a86ca1fd5f41b9491d1ad73.webp 760w,
/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://new.craighesling.com/post/chrome-app-extension-desktop-shortcut/app-details-menu-create-shortcuts_hu07a0ccf4974fa49d44a915788114ccfc_19427_3fa38343896cc84f928c4346dfc34a13.webp"
width="445"
height="245"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/li>
&lt;/ol></description></item><item><title>Unified Altium Components Library for Lab</title><link>https://new.craighesling.com/post/altium-library/</link><pubDate>Wed, 20 Dec 2017 11:30:41 -0500</pubDate><guid>https://new.craighesling.com/post/altium-library/</guid><description>&lt;h2 id="description">Description&lt;/h2>
&lt;p>Within a lab group, there is need to standardize on footprints used, since
it takes such a large amount of time to create the footprints to begin with.&lt;/p>
&lt;p>&lt;a href="https://github.com/WiseLabCMU/AltiumLib" target="_blank" rel="noopener">https://github.com/WiseLabCMU/AltiumLib&lt;/a>&lt;/p></description></item><item><title>Web Development</title><link>https://new.craighesling.com/post/webdev/</link><pubDate>Wed, 13 Dec 2017 01:53:28 -0500</pubDate><guid>https://new.craighesling.com/post/webdev/</guid><description>&lt;p>I&amp;rsquo;m really starting to get the hang of this web development thing.
First Angular 1, then Angular 5, and now Hugo.&lt;/p></description></item><item><title>System Monitor Device (for OpenChirp)</title><link>https://new.craighesling.com/post/sysmonitor-device/</link><pubDate>Mon, 06 Nov 2017 00:00:00 +0000</pubDate><guid>https://new.craighesling.com/post/sysmonitor-device/</guid><description>&lt;h2 id="summary">Summary&lt;/h2>
&lt;h2 id="how-it-works">How it works&lt;/h2>
&lt;h2 id="links">Links&lt;/h2>
&lt;p>&lt;a href="https://github.com/OpenChirp/sysmonitor-device" target="_blank" rel="noopener">sysmonitor-device on Github&lt;/a>&lt;/p></description></item><item><title>TI CC2538/CC26xx Serial Bootloader Utility on Linux</title><link>https://new.craighesling.com/post/cc2538-cc26xx-bootloader/</link><pubDate>Tue, 11 Apr 2017 11:30:41 -0500</pubDate><guid>https://new.craighesling.com/post/cc2538-cc26xx-bootloader/</guid><description>&lt;p>If you have ever been curious about using the TI CC2650 and other similar SimpleLink devices&amp;rsquo; serial bootloader, wonder no longer.&lt;/p>
&lt;p>I recently implemented the TI CC2538/CC26xx Serial Bootloader protocol in a Go library, called &lt;a href="https://github.com/OpenChirp/ccboot" target="_blank" rel="noopener">ccboot&lt;/a>.
This simply uses standard IO operations that can be used with a generic serial library.&lt;/p>
&lt;p>Since a library is no fun without a command line interface, I have also implemented &lt;a href="https://github.com/OpenChirp/ccbootutil" target="_blank" rel="noopener">ccbootutil&lt;/a>, which exposes most of the low level bootloader primitives(which can be shell scripted) and has a complete program sequence that reads ELF binaries, flashes, and resets the chip. You simply run the following command and ccbootutil did the rest:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cbootutil /dev/ttyUSB0 prgm YourCompiledProgramInStandardELFFormat.out
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When implementing ccbootutil, I used a Go serial port interface library that indicated that it should work cross platform, so Windows and OSX users should not feel left out of the command line and scriptable goodness.&lt;/p>
&lt;p>I have compiled the utility for each of the platforms in the repository &lt;a href="https://github.com/OpenChirp/ccbootutil/tree/master/builds" target="_blank" rel="noopener">builds/&lt;/a> directory.&lt;/p>
&lt;h2 id="notes">Notes&lt;/h2>
&lt;ul>
&lt;li>I have found that the serial bootloader can flash the CC2650 faster than an XDS110 over cJTAG.&lt;/li>
&lt;li>TI Smart RF Flash Programmer 2 certainly works, but is strictly for Windows and is not scriptable.&lt;/li>
&lt;/ul>
&lt;h2 id="links">Links&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/OpenChirp/ccbootutil" target="_blank" rel="noopener">https://github.com/OpenChirp/ccbootutil&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/OpenChirp/ccboot" target="_blank" rel="noopener">https://github.com/OpenChirp/ccboot&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Please let me know if you find any issues. Happy coding!&lt;/p></description></item></channel></rss>