<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>ariedro&#x27;s page</title>
    <link rel="self" type="application/atom+xml" href="https://ariedro.dev/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://ariedro.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-02-02T00:00:00+00:00</updated>
    <id>https://ariedro.dev/atom.xml</id>
    <entry xml:lang="en">
        <title>I&#x27;ve got mail</title>
        <published>2025-02-02T00:00:00+00:00</published>
        <updated>2025-02-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ariedro.dev/6-ive-got-mail/"/>
        <id>https://ariedro.dev/6-ive-got-mail/</id>
        
        <content type="html" xml:base="https://ariedro.dev/6-ive-got-mail/">&lt;p&gt;Recently I&#x27;ve started to notice that I&#x27;m getting my mail notifications late,
I used to get the inbox directly with the &lt;code&gt;atom.xml&lt;&#x2F;code&gt; that Gmail provides and
be notified by checking my RSS feed, the problem is that this only gets
updated every 20 minutes or so.&lt;&#x2F;p&gt;
&lt;p&gt;The obvious solution would be to have a mail app that is constantly updating
the inbox and getting notified that way, but this is costly for my phone,
which is kind of old and not in the best debloated shape.&lt;&#x2F;p&gt;
&lt;p&gt;So for this I wanted to make something like I&#x27;ve already done &lt;a href=&quot;&#x2F;1-smtp-faker&quot;&gt;previously&lt;&#x2F;a&gt;,
which is a way to relay this to a server process and be notified via Telegram.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;imap&quot;&gt;IMAP&lt;&#x2F;h2&gt;
&lt;p&gt;Internet Message Access Protocol is one of the two standard protocols for
retrieving mails from a remote mail server. Being the most used one I chose
it over POP3, but this could have been done with POP3 as well.&lt;&#x2F;p&gt;
&lt;p&gt;It works like normal application layers old internet protocols such as SMTP,
in the way that the session is managed via plain text querying commands and
retrieving the results.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;programming-the-solution&quot;&gt;Programming the solution&lt;&#x2F;h2&gt;
&lt;p&gt;For my purposes, I only wanted to get the latest unread mails, so the only
query that I need to do is to fetch the mails on the inbox. However, being
that this is a little more complicated than SMTP, this time I will be using
an external library, so no hardcoding commands this time.&lt;&#x2F;p&gt;
&lt;p&gt;I used NodeJs for this and used the &lt;a href=&quot;https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;node-imap&quot;&gt;node-imap&lt;&#x2F;a&gt; library.
The code for this is kind of ugly as it&#x27;s event-based so it doesn&#x27;t follow a
sequential flow.&lt;&#x2F;p&gt;
&lt;p&gt;Basically what I did was:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Establish a connection&lt;&#x2F;li&gt;
&lt;li&gt;Open the inbox&lt;&#x2F;li&gt;
&lt;li&gt;Fetch the messages, filtering only the headers fields &lt;code&gt;SUBJECT&lt;&#x2F;code&gt; and &lt;code&gt;FROM&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;For each message do some parsing, both of its headers as well as its metadata&lt;&#x2F;li&gt;
&lt;li&gt;If the message doesn&#x27;t have a &lt;code&gt;\\Seen&lt;&#x2F;code&gt; flag and hasn&#x27;t already been cached, send it to Telegram&lt;&#x2F;li&gt;
&lt;li&gt;Save the message to the cache&lt;&#x2F;li&gt;
&lt;li&gt;Exit&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;You can check out the full code &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ariedro&#x2F;youve-got-mail&#x2F;blob&#x2F;master&#x2F;index.js&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;seeing-it-in-action&quot;&gt;Seeing it in action&lt;&#x2F;h2&gt;
&lt;p&gt;On Telegram I&#x27;ve created yet another bot for this specific purpose, that way I
can customize its notification sound to be the iconical &quot;You&#x27;ve got mail&quot; voice
alert each time I get a new mail.&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;audio controls src=&quot;&amp;#x2F;imap-youvegotmail.ogg&quot; &gt;&lt;&#x2F;audio&gt;
   
      &lt;figcaption class=&quot;left&quot;&gt;The iconical voice alert&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;p&gt;And here&#x27;s a censored screenshot of it in action:&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;img src=&quot;&#x2F;imap-screenshot.png&quot; &#x2F;&gt;
    
  &lt;&#x2F;figure&gt;

&lt;p&gt;Now I can get notified for my mails right away, without having bloat running on my phone!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hacking my health insurance security token generation</title>
        <published>2024-09-01T00:00:00+00:00</published>
        <updated>2024-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ariedro.dev/5-hack-osde/"/>
        <id>https://ariedro.dev/5-hack-osde/</id>
        
        <content type="html" xml:base="https://ariedro.dev/5-hack-osde/">&lt;p&gt;Following up with my quest to clean my phone from apps that I was forced to
install by living in a civilization that doesn&#x27;t care about bloated software.
This time it was the turn of my health insurance app.&lt;&#x2F;p&gt;
&lt;p&gt;I have OSDE. On there, in order to have a medical appointment, purchase
discounted medications and other related actions, you MUST have installed the
OSDE app, not only for presenting the card credential number, but for it to
give you a &quot;token&quot; that generates every 5 minutes.&lt;&#x2F;p&gt;
&lt;p&gt;You show this token to the person who is taking your medical appointment or
purchase, thus validating that you are authorized to do it.&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;img src=&quot;&#x2F;osde-app.jpg&quot; &#x2F;&gt;
    
      &lt;figcaption class=&quot;left&quot;&gt;OSDE App with generated token, in this case is 602 and it will be valid for 2 minutes&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;p&gt;I don&#x27;t think this seem like a particularly bad way to validate your authority
to use the service, but I&#x27;d rather not have an app installed for something
that could be a card. And I knew this could be circunvented because it works
offline.&lt;&#x2F;p&gt;
&lt;p&gt;So here we go with the hack.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;otp&quot;&gt;OTP&lt;&#x2F;h2&gt;
&lt;p&gt;Asking to a friend about this, I realized that this app implements a
cryptographic
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;One-time_password&quot;&gt;One-Time Password (OTP)&lt;&#x2F;a&gt;
just like Google Authenticator.&lt;&#x2F;p&gt;
&lt;p&gt;In short this takes a static identity seed, the current timestamp (mod by
5 minutes), and hashes it, producing a number that should guarantee the user&#x27;s
identity in that moment.&lt;&#x2F;p&gt;
&lt;p&gt;Knowing this, and having my phone rooted, I could grep the app&#x27;s storage and
find the needed seed.&lt;&#x2F;p&gt;
&lt;p&gt;After a few attempts I found what I was looking for:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; strings &#x2F;data&#x2F;data&#x2F;ar.com.osde.ads&#x2F;databases&#x2F;credencialDigitalSqlite | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; OTP
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;credenciales&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;[ ... ,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;semilla&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;( This is it )&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; ... ]&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;matching-the-token&quot;&gt;Matching the token&lt;&#x2F;h2&gt;
&lt;p&gt;Having the seed, all I had to do was replicate the same encodings and options
that the app uses.&lt;&#x2F;p&gt;
&lt;p&gt;After a few failed attempts with publicly available OTP libraries, I realized
that it would be easier to decompile the app and take a look at how the app is
actually hashing the seed.&lt;&#x2F;p&gt;
&lt;p&gt;As with the &lt;a href=&quot;&#x2F;3-hack-trains-api&quot;&gt;trains app hack&lt;&#x2F;a&gt;, I used the jadx program
and took a peek inside.&lt;&#x2F;p&gt;
&lt;p&gt;Quickly I found it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;otplib_otplib_browser__WEBPACK_IMPORTED_MODULE_4__&lt;&#x2F;span&gt;&lt;span&gt;[&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;totp&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;].options = {
&lt;&#x2F;span&gt;&lt;span&gt;    digits: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    step: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;300&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    algorithm: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;sha256&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;createHmacSecret&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;secret&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;params&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;secret&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With this I&#x27;ve got both the encodings and the js library used (&lt;a href=&quot;https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;otplib&quot;&gt;otplib&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;And finally I was able to reproduce the same token generation as the app:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;totp &lt;&#x2F;span&gt;&lt;span&gt;} = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;otplib&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;seed &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;totp&lt;&#x2F;span&gt;&lt;span&gt;.options = {
&lt;&#x2F;span&gt;&lt;span&gt;    digits: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    step: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;300&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    algorithm: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;sha256&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;createHmacSecret&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;secret&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;params&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;secret&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;totp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;generate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;seed&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; node index.js
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;602
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;minimizing-the-code&quot;&gt;Minimizing the code&lt;&#x2F;h2&gt;
&lt;p&gt;From previous work experience, I have had major problems relying on external
cryptographic libraries. So this time I would like to not depend on otplib and
have it to manually generate the token by myself.&lt;&#x2F;p&gt;
&lt;p&gt;By scrapping the otplib code and minimizing it to only do the generation for
this type of token, I ended up with a compact version of it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;createHmac &lt;&#x2F;span&gt;&lt;span&gt;} = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;crypto&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;seed &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;...&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;generateToken &lt;&#x2F;span&gt;&lt;span&gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;secret&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;counter &lt;&#x2F;span&gt;&lt;span&gt;= Math.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;floor&lt;&#x2F;span&gt;&lt;span&gt;(new Date().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;getTime&lt;&#x2F;span&gt;&lt;span&gt;() &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;300000&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;padStart&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;digest &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;createHmac&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;sha256&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;secret&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;update&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Buffer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;counter&lt;&#x2F;span&gt;&lt;span&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;hex&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;))
&lt;&#x2F;span&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;offset &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;.length - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0xf&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;binary &lt;&#x2F;span&gt;&lt;span&gt;=
&lt;&#x2F;span&gt;&lt;span&gt;    ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;offset&lt;&#x2F;span&gt;&lt;span&gt;] &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0x7f&lt;&#x2F;span&gt;&lt;span&gt;) &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;) |
&lt;&#x2F;span&gt;&lt;span&gt;    ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;offset &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0xff&lt;&#x2F;span&gt;&lt;span&gt;) &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;) |
&lt;&#x2F;span&gt;&lt;span&gt;    ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;offset &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;] &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0xff&lt;&#x2F;span&gt;&lt;span&gt;) &amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;) |
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;offset &lt;&#x2F;span&gt;&lt;span&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;] &amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0xff&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tokenNumber &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;binary &lt;&#x2F;span&gt;&lt;span&gt;% Math.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;pow&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tokenNumber&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;padStart&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;generateToken&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;seed&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;osde-cli&quot;&gt;OSDE-CLI&lt;&#x2F;h2&gt;
&lt;p&gt;For the final touch I ended up adding a few optional parameters and printing
extra information. This way anyone could use this &quot;terminal version of the OSDE
app&quot;, without the need to use the official one.&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;img src=&quot;&#x2F;osde-cli.jpg&quot; &#x2F;&gt;
    
      &lt;figcaption class=&quot;left&quot;&gt;Running it on Termux, much faster than the OSDE app&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;p&gt;I published it &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ariedro&#x2F;osde-cli&quot;&gt;on a github repository&lt;&#x2F;a&gt;,
so anyone can use it freely.&lt;&#x2F;p&gt;
&lt;p&gt;I hope you liked this blogpost, until next time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Self-hosting my alarm clock radio</title>
        <published>2023-12-30T00:00:00+00:00</published>
        <updated>2023-12-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ariedro.dev/4-self-hosting-my-alarm-clock-radio/"/>
        <id>https://ariedro.dev/4-self-hosting-my-alarm-clock-radio/</id>
        
        <content type="html" xml:base="https://ariedro.dev/4-self-hosting-my-alarm-clock-radio/">&lt;p&gt;I don’t like waking up, before going to sleep I tend to schdule many alarms and the next morning I turn off each one of them.&lt;&#x2F;p&gt;
&lt;p&gt;When I was younger I remember having an old radio alarm that would turn on at a scheduled time, I used it as an wake up alarm and I remember being effective.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe because hearing people talking would be less numbing that hearing the same song every day, and it would motivate me more to not turn off the alarm, maybe, I don’t know.&lt;&#x2F;p&gt;
&lt;p&gt;But I wanted to try this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;radio&quot;&gt;Radio&lt;&#x2F;h2&gt;
&lt;p&gt;The trivial solution would be to just buy a radio with an alarm, but I discarded this from the start because&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;I don&#x27;t like the radio static, and even less when I can listen to a live broadcast on the internet very clearly.&lt;&#x2F;li&gt;
&lt;li&gt;I didn’t want to spend money&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;mobile&quot;&gt;Mobile&lt;&#x2F;h2&gt;
&lt;p&gt;My first attempt was downloading an app that would do this. As I’m already waking up with my cellphone I might as well continue using it.&lt;&#x2F;p&gt;
&lt;p&gt;I tried the &lt;a href=&quot;https:&#x2F;&#x2F;f-droid.org&#x2F;es&#x2F;packages&#x2F;net.programmierecke.radiodroid2&#x2F;&quot;&gt;RadioDroid&lt;&#x2F;a&gt; app, it seems like it has the features I want, it connects to a radio URL and can be used as an alarm clock. But upon using a few nights I’ve noted that the alarm doesn’t always go off. I guess it might be because it’s trying to attempt an active connection and Android goes into idle mode after a while?&lt;&#x2F;p&gt;
&lt;p&gt;Besides I like to turn Wi-Fi off at night, and I realise that it lacks some other nice-to-haves, like adjusting the volume incrementally.&lt;&#x2F;p&gt;
&lt;p&gt;I tried others apps but this was the more promising, I don&#x27;t want payware, and I surely didn’t feel like programming in Android, so it seemed like I would need another option.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;raspberry-pi&quot;&gt;Raspberry Pi&lt;&#x2F;h2&gt;
&lt;p&gt;I have a couple of raspberry pis through the house, one of them I use it as a server for various services that are running all day long. So I thought about using it for this purpose as well.&lt;&#x2F;p&gt;
&lt;p&gt;I moved the raspi to the bedroom and connected to it some old PC speakers I had.&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;img src=&quot;&#x2F;cereza.png&quot; &#x2F;&gt;
    
      &lt;figcaption class=&quot;left&quot;&gt;Ignore the poor state of the raspberry&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;p&gt;Having the interface of a whole computer now I had much more control, as I can program it however I want. All I had to do is play audio through the speakers at a certain time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-player&quot;&gt;The player&lt;&#x2F;h3&gt;
&lt;p&gt;The core of the schedule is to just to reproduce audio through the raspberry’s speakers, so I needed an audio player for it.&lt;&#x2F;p&gt;
&lt;p&gt;My priorities were that I needed a program that would be lightweight, CLI so I could run it directly on the terminal, and that could also play radio files.&lt;&#x2F;p&gt;
&lt;p&gt;I wasn’t going to install anything fancy like VLC or MPV just to play an audio file. So after searching around I found &lt;a href=&quot;https:&#x2F;&#x2F;www.mpg123.de&#x2F;&quot;&gt;mpg123&lt;&#x2F;a&gt;, which fullfilled my needs perfectly, it is extremely lightweight, is CLI, doesn’t have an interface and reproduces radio files directly from the URL.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-radio&quot;&gt;The radio&lt;&#x2F;h3&gt;
&lt;p&gt;As I said on the beginning, I wanted to hear people talking, so I searched for an AM radio. The most popular here regardless of political spectrum is Radio Mitre, which I don&#x27;t find it entirely despicable, so it works for me.&lt;&#x2F;p&gt;
&lt;p&gt;I scrapped it’s web and found a link for a MP3 file that could be reproduced directly&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;http:&#x2F;&#x2F;27323.live.streamtheworld.com&#x2F;AM790_56.mp3&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And after executing the following on the raspberry pi.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;$ mpg123 http:&#x2F;&#x2F;27323.live.streamtheworld.com&#x2F;AM790_56.mp3
&lt;&#x2F;span&gt;&lt;span&gt;High Performance MPEG 1.0&#x2F;2.0&#x2F;2.5 Audio Player for Layers 1, 2 and 3
&lt;&#x2F;span&gt;&lt;span&gt;	version 1.26.4; written and copyright by Michael Hipp and others
&lt;&#x2F;span&gt;&lt;span&gt;	free software (LGPL) without any warranty but with best wishes
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Directory: http:&#x2F;&#x2F;27323.live.streamtheworld.com&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Terminal control enabled, press &amp;#39;h&amp;#39; for listing of keys and functions.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Playing MPEG stream 1 of 1: AM790_56.mp3 ...
&lt;&#x2F;span&gt;&lt;span&gt;ICY-NAME:
&lt;&#x2F;span&gt;&lt;span&gt;ICY-URL: https:&#x2F;&#x2F;radiomitre.com.ar&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;MPEG 1.0 L III cbr96 44100 j-s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;ICY-META: StreamTitle=&amp;#39;SEP WHATSAPP MITRE -SMD&amp;#39;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It’s working! The live radio is coming out from the speakers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;off-button&quot;&gt;Off button&lt;&#x2F;h3&gt;
&lt;p&gt;Now that it works, I need a way to turn it off when I’m already awake.&lt;&#x2F;p&gt;
&lt;p&gt;As I was thinking about how I could attach a physical button to the raspi and having to attach wires and other electronical things and such. I thought to myself&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;”Wait, I’m a Node.js developer, I don’t need buttons, I can host a bloated express server just to listen for an action, and then send a HTTP request from my phone to trigger it.”&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So I had all the elements to start programming.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;programming&quot;&gt;Programming&lt;&#x2F;h2&gt;
&lt;p&gt;I started with the core functionality, spawning the radio process.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;spawn &lt;&#x2F;span&gt;&lt;span&gt;} = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;node:child_process&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;play &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;spawn&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;mpg123&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;http:&#x2F;&#x2F;27323.live.streamtheworld.com&#x2F;AM790_56.mp3&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;]);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then handling the process killing on an express endpoint.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;express &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;express&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;app &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;express&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;app
&lt;&#x2F;span&gt;&lt;span&gt;  .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;apagar&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;_req&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;res&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;try &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;play&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;kill&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;res&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Apagado&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;);
&lt;&#x2F;span&gt;&lt;span&gt;      process.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;catch &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;res&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;status&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;500&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;      process.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;  })
&lt;&#x2F;span&gt;&lt;span&gt;  .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;listen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3000&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On my phone, I created a termux shortcut script that does the HTTP request.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;curl &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RASPBERRY_IP&lt;&#x2F;span&gt;&lt;span&gt;:3000&#x2F;apagar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From this I can turn the alarm off with a single tap on my phone.&lt;&#x2F;p&gt;
&lt;p&gt;And the core functionality is done!&lt;&#x2F;p&gt;
&lt;h4 id=&quot;cron-job&quot;&gt;Cron job&lt;&#x2F;h4&gt;
&lt;p&gt;All I had to do now is set the alarm in motion each morning, which I simply added a cron job to execute it at a determined time. In this case at 08:30.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;30 8 * * * cd radespertador &amp;amp;&amp;amp; npm run start
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;increasing-volume-and-parametrizing&quot;&gt;Increasing volume and parametrizing&lt;&#x2F;h3&gt;
&lt;p&gt;One last feature I’d like to have is to the volume being increasing slowly, I don’t want to get startled all of the sudden of my sleep.&lt;&#x2F;p&gt;
&lt;p&gt;I had to spawn another child process with a call to control the volume, and in intervals call the controller with smaller increments of the percentage for the volume.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;setVolume &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;volume &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;spawn&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;amixer&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;sset&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;Headphone&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;volume&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;}%&lt;&#x2F;span&gt;&lt;span&gt;`]);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;setVolume&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;currentVolume &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;setInterval&lt;&#x2F;span&gt;&lt;span&gt;(() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;setVolume&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;currentVolume &lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;99 &lt;&#x2F;span&gt;&lt;span&gt;? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;currentVolume &lt;&#x2F;span&gt;&lt;span&gt;: ++&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;currentVolume&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;}, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2000&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And of course it would be a bad practice to leave all of this with literals and magic numbers, so I had everything parameterized, and the values can be tweaked on the config file.&lt;&#x2F;p&gt;
&lt;p&gt;You can see the final code &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ariedro&#x2F;radespertador&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;final-result&quot;&gt;Final result&lt;&#x2F;h4&gt;
&lt;p&gt;Here’s a recording of how it works, for demostration purpose the increment for the volume is way more frequent than it is in reality&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;video controls style=&quot;max-width: 100%;&quot;&gt;
      &lt;source src=&quot;&amp;#x2F;radio.mp4&quot; type=&quot;video&#x2F;mp4&quot; &#x2F;&gt;
    &lt;&#x2F;video&gt;
   
      &lt;figcaption class=&quot;left&quot;&gt;Wait for it&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Did it work? Kind of, I still struggle to wake up. But at least now I can listen to boomers say random things on the morning before turning off the alarm, and I can say that I build that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hacking my local trains schedules API</title>
        <published>2022-11-21T00:00:00+00:00</published>
        <updated>2022-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ariedro.dev/3-hack-trains-api/"/>
        <id>https://ariedro.dev/3-hack-trains-api/</id>
        
        <content type="html" xml:base="https://ariedro.dev/3-hack-trains-api/">&lt;p&gt;Here in Buenos Aires we rely mainly on 3 modes of public transportation:
buses, subways and trains. Buses are often the primary choice because they&#x27;re
everywhere, but in terms of efficiency and speed subways and trains are
by far the best choice, if you can take advantage of the proximity of
a railroad branch line.&lt;&#x2F;p&gt;
&lt;p&gt;Say you want to take a train somewhere, and you want to make sure
you are on time, you can download the android app &quot;
&lt;a href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;apps&#x2F;details?id=com.mininterior.trenesenvivo&quot;&gt;Trenes Argentinos&lt;&#x2F;a&gt;
&quot; from the Google Play store, developed by the private company SOFSE,
and check the time schedules there.&lt;&#x2F;p&gt;
&lt;p&gt;Upon installing it you&#x27;ll see right away that the app starts requiring
permissions, permissions that a simple app for checking the trains schedule
shouldn&#x27;t require, like GPS location and file storage access.&lt;&#x2F;p&gt;
&lt;p&gt;If you deny these requests it would still prompt you every time you select a station.&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;img src=&quot;&#x2F;trenes-app.jpg&quot; &#x2F;&gt;
    
      &lt;figcaption class=&quot;left&quot;&gt;Shady dialogs in the app, the right one appears everytime you select
a station&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;p&gt;If you&#x27;re like most people you probably wouldn&#x27;t care much about these things
because the app in the end actually fulfills its purpose.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;del&gt;You don&#x27;t mind having your privacy being invaded any more than it already is
every day, or having to navigate to a horrible UX by closing a dozen
of pop-ups like it&#x27;s the early internet days.&lt;&#x2F;del&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully I&#x27;m not, so I began searching for the API behind it so
I could just write a bash script and &lt;code&gt;curl&lt;&#x2F;code&gt; it away.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;research&quot;&gt;Research&lt;&#x2F;h2&gt;
&lt;p&gt;Being a public transportation service, I expected the API to also be public.&lt;&#x2F;p&gt;
&lt;p&gt;For example, in the internal jurisdiction of the city of Buenos Aires they implemented an
&lt;a href=&quot;https:&#x2F;&#x2F;www.buenosaires.gob.ar&#x2F;desarrollourbano&#x2F;transporte&#x2F;apitransporte&quot;&gt;unified public transport API specification&lt;&#x2F;a&gt;
that provides information on buses, subways and even the status of the city&#x27;s
traffic lights.&lt;&#x2F;p&gt;
&lt;p&gt;However, this does not seem to be the case for trains, after googling
a little bit I didn&#x27;t find anything, and everything pointed to this
being a private service. Even in violation of the
&lt;a href=&quot;http:&#x2F;&#x2F;servicios.infoleg.gob.ar&#x2F;infolegInternet&#x2F;anexos&#x2F;265000-269999&#x2F;265949&#x2F;texact.htm&quot;&gt;national law 27,275&lt;&#x2F;a&gt;
that guarantees the right of access to public information.&lt;&#x2F;p&gt;
&lt;p&gt;This leaves me with only one option.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hacking-the-app&quot;&gt;Hacking the App&lt;&#x2F;h2&gt;
&lt;p&gt;I downloaded the app&#x27;s raw apk to my pc with a generic apk downloader,
and after researching a little bit about how to decompile an android app file,
I ended up using a program called &lt;code&gt;jadx&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;gt;: jadx com.mininterior.trenesenvivo.apk
&lt;&#x2F;span&gt;&lt;span&gt;INFO  - loading ...
&lt;&#x2F;span&gt;&lt;span&gt;INFO  - processing ...
&lt;&#x2F;span&gt;&lt;span&gt;ERROR - finished with errors, count: 8
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I didn&#x27;t care much about those errors because I wasn&#x27;t going to recompile
the app anyway, I just wanted to look for the internal service it used.&lt;&#x2F;p&gt;
&lt;p&gt;So I started browsing the decompiled codebase and found the URL right away.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;string &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;trenesApiUrl&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&amp;gt;https:&#x2F;&#x2F;apiarribos.sofse.gob.ar&#x2F;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;string&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the endpoint&#x27;s paths and params.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;v1&#x2F;estaciones&#x2F;buscar&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Call&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;PaginationContainer&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Estacion&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;buscarEstaciones&lt;&#x2F;span&gt;&lt;span&gt;(@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;nombre&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt; str, @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;lineas&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;RetrofitArray&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Integer&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; retrofitArray, @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;ramales&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;RetrofitArray&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Integer&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; retrofitArray2, @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;exclude&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;RetrofitArray&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Integer&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; retrofitArray3, @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;limit&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Integer&lt;&#x2F;span&gt;&lt;span&gt; num, @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Query&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;orderBy&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt; str2);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;v1&#x2F;alertas&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Call&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;List&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;AlertaResponse&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;getAlertas&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Before I started testing, and thinking I had everything I needed,
to my suprise I also found a little file called &lt;code&gt;TokenAuthenticator.java&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Thinking to myself: &quot;Well, they probably added an authentication token
that is freely obtainable with an endpoint, in order to avoid getting
spammed&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;But after browsing the file a little bit:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt; userApi = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;getUserApi&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt; codificar = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(userApi);
&lt;&#x2F;span&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;tokenRequest.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;setUsername&lt;&#x2F;span&gt;&lt;span&gt;(userApi);
&lt;&#x2F;span&gt;&lt;span&gt;tokenRequest.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;setPassword&lt;&#x2F;span&gt;&lt;span&gt;(codificar);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Why would there be a user and a password, if the app
doesn&#x27;t require a login or anything like that?&lt;&#x2F;p&gt;
&lt;p&gt;And then I found it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;public static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;getUserApi&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Date&lt;&#x2F;span&gt;&lt;span&gt; date = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Date&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Base64&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;encodeToString&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;SimpleDateFormat&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;yyyyMMdd&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span&gt;(date) + &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;sofse&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;getBytes&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;  );
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;public static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt; str) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span&gt; stringBuffer = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;StringBuffer&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Base64&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;encodeToString&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;StringBuffer&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;Base64&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;encodeToString&lt;&#x2F;span&gt;&lt;span&gt;(str.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;getBytes&lt;&#x2F;span&gt;&lt;span&gt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#t&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#x&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#f&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;o&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#l&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;u&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#7&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#g&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      )
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;reverse&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;getBytes&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;      .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#j&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#p&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#w&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;o&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;u&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;      .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;#v&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;  )
&lt;&#x2F;span&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;reverse&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Up until this point I thought that maybe they didn&#x27;t publish their API because
they were lazy, or because they did not see the need to do so.&lt;&#x2F;p&gt;
&lt;p&gt;But no, not only did they fill their app with shady storage and GPS accesses,
not only did they not publish their API specification evading a national law,
but they also obscured the access to it with some encoding, being 100% assholes.&lt;&#x2F;p&gt;
&lt;p&gt;I felt that I had a moral obligation to not only circumvent this, but also
to publish it so anyone can use it freely.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remaking-it&quot;&gt;Remaking it&lt;&#x2F;h2&gt;
&lt;p&gt;I wanted to make a public proxy that would bypass all of this, so I made a simple
nodejs program using &lt;code&gt;express&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The core of the program would just be something like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;app &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;express&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;app&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;redirection&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;app&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;listen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;PORT&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And in the &lt;code&gt;redirection&lt;&#x2F;code&gt; middleware it would be located the generation
and maintenance of such obscured tokens, of which they should be made in the
same way as in the app.&lt;&#x2F;p&gt;
&lt;p&gt;After a bit of trial and error, after having to root my phone in order to
be able to sniff HTTP requests, because I couldn&#x27;t get to replicate the same
exact encoding, I finally did it, I was able to bypass the token generation
and make direct use of the API.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the full source code &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ariedro&#x2F;api-trenes&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;publication-and-usage&quot;&gt;Publication and usage&lt;&#x2F;h2&gt;
&lt;p&gt;I set up a public instance of this proxy service on the same server where
this blog is hosted, by the path &lt;code&gt;&#x2F;api-trenes&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;With this service anyone can make request to it, and it would take care
of the internal authentication, without the user having to worry about it.&lt;&#x2F;p&gt;
&lt;p&gt;For example you can get the lines information:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;curl &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;https:&#x2F;&#x2F;ariedro.dev&#x2F;api-trenes&#x2F;lineas&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or the schedules to go from &quot;Drago&quot; to &quot;Miguelete&quot;
(Previously you would need to find the corresponding ids for such stations):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-sh &quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;curl &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;https:&#x2F;&#x2F;ariedro.dev&#x2F;api-trenes&#x2F;estaciones&#x2F;236&#x2F;horarios?hasta=271&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can find more info and the full endpoints specification
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ariedro&#x2F;api-trenes&quot;&gt;in the repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Having all this live, I can finally make scripts on for example Termux
and be able to get the schedules information instantly, without having to
go through all the spyware in the app.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-things&quot;&gt;Further things&lt;&#x2F;h2&gt;
&lt;p&gt;I wanted to give a big shout-out to &lt;a href=&quot;https:&#x2F;&#x2F;tinchomika.com&#x2F;&quot;&gt;Tincho Mika&lt;&#x2F;a&gt; for using this to make
a fully featured web application to view all the information that this API
provides in a properly formatted way. Be sure to check out &lt;a href=&quot;https:&#x2F;&#x2F;trencitos.tinchomika.com&#x2F;&quot;&gt;Trencitos&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I hope you liked this blogpost, and I look forward to keep posting other
interesting stuff like this more often.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I&#x27;m using Zola</title>
        <published>2022-10-08T00:00:00+00:00</published>
        <updated>2022-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ariedro.dev/2-zola-update/"/>
        <id>https://ariedro.dev/2-zola-update/</id>
        
        <content type="html" xml:base="https://ariedro.dev/2-zola-update/">&lt;p&gt;Hi! I&#x27;m now using &lt;a href=&quot;https:&#x2F;&#x2F;www.getzola.org&#x2F;&quot;&gt;Zola&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ve decided that I don&#x27;t have the time or inclination to deal with CSS and
responsiveness hell that requires me to learn in order to maintain a plain
HTML page.&lt;&#x2F;p&gt;
&lt;p&gt;So now, thanks to &lt;a href=&quot;https:&#x2F;&#x2F;www.enzocioppettini.com&#x2F;&quot;&gt;Enzo&lt;&#x2F;a&gt;, I&#x27;m now using
this framework that only requires me to write markdown files and it
does the rest for me.&lt;&#x2F;p&gt;
&lt;p&gt;Stay tuned for the updates with the new
&lt;a href=&quot;&#x2F;atom.xml&quot;&gt;RSS feed&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How I tricked my camera into believing it was sending mails</title>
        <published>2022-03-04T00:00:00+00:00</published>
        <updated>2022-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ariedro.dev/1-smtp-faker/"/>
        <id>https://ariedro.dev/1-smtp-faker/</id>
        
        <content type="html" xml:base="https://ariedro.dev/1-smtp-faker/">&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve got a security camera, it&#x27;s kind of old and limited in the amount of
features it has. I recently installed it on my front yard, and I wanted a
motion detection alert. This camera actually supports that feature, but it
has one problem:&lt;&#x2F;p&gt;
&lt;p&gt;The alerts can only be sent via mail.&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;img src=&quot;&#x2F;cam-config.png&quot; &#x2F;&gt;
    
      &lt;figcaption class=&quot;left&quot;&gt;Camera config page&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;p&gt;Now, this wouldn&#x27;t be an issue if I actually paid attention to mails as soon
as they come, but I don&#x27;t, I relay them to a RSS feed and I do not read it
until I log on to the internet and start browsing the feed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;possible-solutions&quot;&gt;Possible solutions&lt;&#x2F;h2&gt;
&lt;p&gt;If recieving mails is not the most convenient thing to do, another way to get
notifications that I know i&#x27;ll be reading them as soon as they come is a
telegram bot, this is easy since the API is pretty simple and it could be
simplified to sending a single HTTP request.&lt;&#x2F;p&gt;
&lt;p&gt;In order to achieve this, the first thing that it occurred to me was mounting
a full SMTP server and somehow hook a curl command in there when it detects
that an email is coming from the camera.&lt;&#x2F;p&gt;
&lt;p&gt;But then I realized it wasn&#x27;t necessary, since if I could simply emulate a
SMTP server, then I would receive the data directly and handle it as I wish.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;emulating-a-smtp-server&quot;&gt;Emulating a SMTP server&lt;&#x2F;h2&gt;
&lt;p&gt;So I opened up the &lt;a href=&quot;https:&#x2F;&#x2F;datatracker.ietf.org&#x2F;doc&#x2F;html&#x2F;rfc5321&quot;&gt;RFC 5321&lt;&#x2F;a&gt;
to see what were the standard steps in the communication for receiving an email.
And SMTP lives up to its name since it is extremely simple.&lt;&#x2F;p&gt;
&lt;p&gt;Basically it comes down to this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Send a greeting message with 220 code identifying ourselves&lt;&#x2F;li&gt;
&lt;li&gt;Get a &lt;code&gt;EHLO&lt;&#x2F;code&gt; command with the client&#x27;s identity&lt;&#x2F;li&gt;
&lt;li&gt;Reply with &lt;code&gt;250 OK&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Get a &lt;code&gt;MAIL&lt;&#x2F;code&gt; command with the mail&#x27;s sender&lt;&#x2F;li&gt;
&lt;li&gt;Reply with &lt;code&gt;250 OK&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Get a &lt;code&gt;RCPT&lt;&#x2F;code&gt; command with the mail&#x27;s reciever&lt;&#x2F;li&gt;
&lt;li&gt;Reply with &lt;code&gt;250 OK&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Get a &lt;code&gt;DATA&lt;&#x2F;code&gt; command&lt;&#x2F;li&gt;
&lt;li&gt;Reply with 354 telling the client to start sending the data&lt;&#x2F;li&gt;
&lt;li&gt;Get the data, ending with a &lt;code&gt;CRLF.CRLF&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Reply with &lt;code&gt;250 OK&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Get a &lt;code&gt;QUIT&lt;&#x2F;code&gt; command&lt;&#x2F;li&gt;
&lt;li&gt;Reply with &lt;code&gt;221 Bye&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Since all of this is just text, I can test a mail send directly
by typing in netcat:&lt;&#x2F;p&gt;

  &lt;img src=&quot;&#x2F;smtp.gif&quot; class=&quot;center&quot; &#x2F;&gt;

&lt;p&gt;The content of the mails is in MIME, so in the motion detection mails with the
attachments are just text encoded in base64.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote a short nodejs program, you can check the full source code
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ariedro&#x2F;smtp-faker&#x2F;blob&#x2F;master&#x2F;faker.js&quot;&gt;here&lt;&#x2F;a&gt;. It all comes
down to emulating the same communication described above, parsing the
attachments and send them to a telegram bot or any other service you&#x27;d want.&lt;&#x2F;p&gt;

  &lt;figure class=&quot;center&quot; &gt;
    &lt;img src=&quot;&#x2F;telegram-bot.png&quot; &#x2F;&gt;
    
      &lt;figcaption class=&quot;left&quot;&gt;A screenshot of the telegram bot sending me a photo everytime someone passes on the street, while Tiburcio rests&lt;&#x2F;figcaption&gt;
    
  &lt;&#x2F;figure&gt;

&lt;h2 id=&quot;further-things&quot;&gt;Further things&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve discovered that the mail sending feature only supports sending photos
when the motion detection happens. So it would be nice to instead have a
full video of the detection.&lt;&#x2F;p&gt;
&lt;p&gt;According to the
&lt;a href=&quot;https:&#x2F;&#x2F;www.foscam.es&#x2F;descarga&#x2F;Foscam-IPCamera-CGI-User-Guide-AllPlatforms-2015.11.06.pdf&quot;&gt;camera manual&lt;&#x2F;a&gt;,
this would be possible if instead the file got recorded with a FTP server.
So I think it would be more or less the same procedure I did with this
but with the FTP protocol.&lt;&#x2F;p&gt;
&lt;p&gt;Or I may just end up buying a newer camera.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
