2019/10/30

daemontools vs systemd

Here's the bare minimum to get daemontools running under systemd

cat <<CNF > /usr/lib/systemd/system/daemontools.service
[Unit]
Description=DJB daemontools
After=network.target

[Service]
ExecStart=/var/daemontools/command/svscanboot
Restart=always

[Install]
WantedBy=multi-user.target
CNF
systemctl enable daemontools
systemctl start daemontools

Note that the default daemontools install would put the executable in /command/svscanboot.

Sphinx and Mysql 5.7

So I need to move my big application from CentOS 6 to CentOS 8. First problem - systemd. Unfortunately there's no way to remove systemd, and I'm not sure I want to move to Slackware. Second problem - mysql 5.6 won't compile with a recent GNU C++ compiler ! OK, I'll move to 5.7. Wait, SphinxSE won't compile with 5.7. It looks like Sphinx has been abandoned, but it's successor Manticore hasn't moved SphinxSE to 5.7 either. It turns out that 5.7 should have been called 6.0. Maybe this is why the next version is called 8.0?

Fortunately some Googling allowed me to find someone who did the hard work. I cleaned up compiler warnings and updated INSTALL. Source is here.

2019/07/11

Arduino Nano sizeof()

In case you were wondering, here is the output of sizeof() and other things for an Arduino Nano. What's interesting (to me) is that while the Atmega328p is an 8-bit MCU, sizeof(int)==2 and sizeof(char *)==2. In other words, the compiler is treating it as a 16-bit processor.

Welcome to sizeof!
sizeof(bool)=1
sizeof(char)=1
sizeof(int)=2
sizeof(short)=2
sizeof(long int)=4
sizeof(long long int)=8
sizeof(char*)=2
sizeof(String)=6
sizeof(int8_t)=1
sizeof(uint8_t)=1
sizeof(int16_t)=2
sizeof(uint16_t)=2
sizeof(int32_t)=4
sizeof(uint32_t)=4
sizeof(int64_t)=8
sizeof(uint64_t)=8
__INT_MAX__=7FFF
__WINT_MAX__=FFFF
SHRT_MAX=7FFF
USHRT_MAX=FFFF
INT_MAX=7FFF
UINT_MAX=FFFF
LONG_MAX=7FFFFFFF
ULONG_MAX=FFFFFFFF

Here's the code that produces the above.

#include <avr/power.h>
#include <avr/sleep.h>
#include <limits.h>

#define SO( i ) Serial.print( "sizeof(" #i ")=" ); Serial.println( sizeof(i) )
#define Max( i ) Serial.print(  #i "=" ); Serial.println( i, HEX )

void setup(void)
{
    Serial.begin( 9600 );
    Serial.println( "Welcome to sizeof!" );
    
    SO( bool );
    SO( char );
    SO( int );
    SO( short );
    SO( long int );
    SO( long long int );
    SO( char* );
    SO( String );

    SO( int8_t );
    SO( uint8_t );
    SO( int16_t );
    SO( uint16_t );
    SO( int32_t );
    SO( uint32_t );
    SO( int64_t );
    SO( uint64_t );

    Max( __INT_MAX__ );
    Max( __WINT_MAX__ );
    Max( SHRT_MAX );
    Max( USHRT_MAX );
    Max( INT_MAX );
    Max( UINT_MAX );
    Max( LONG_MAX );
    Max( ULONG_MAX );
#ifdef LLONG_MAX
    Max( LLONG_MAX );
#endif
#ifdef ULLONG_MAX
    Max( ULLONG_MAX );
#endif
/*    Max( LONG_LONG_MAX );
    Max( ULONG_LONG_MAX ); */
}

void loop(void)
{

    delay(1000);    // allow serial buffer to empty
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
    sleep_mode(); // here the device is actually put to sleep!!
}

2019/04/04

Using a custom CA root in C#

Over the last year or so, I've been using C#. I'm surprised at how good a language it is. Yes, it suffers from MuchToMuchCamelCaseSyndrome(tm). Maybe Microsoft learned from all the mistakes of Java and avoided them. Maybe Microsoft Studio is just better then whatever that Java crap was. I did however find one problem : it's not easy to use a custom certificate authority file when using SSL. The following is the best I've put together.

using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System;

namespace NS
{
    public class Cls
    {
        static private X509Certificate2 CustomCA = null;
        static public Boolean ssl_verification(Object sender, X509Certificate certificate, 
                    X509Chain chain, SslPolicyErrors sslPolicyErrors) {

            custom_ca_create();
                    
            // remove this line if commercial CAs are not allowed to issue certificate for your service.
            if ((sslPolicyErrors & (SslPolicyErrors.None)) > 0) { return true; }

            // Upgrade the server cert 
            X509Certificate2 cert2 = new X509Certificate2( certificate );

            // Build a chain we'll check ourselves.
            X509Chain p_chain = new X509Chain();
            p_chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            p_chain.ChainPolicy.ExtraStore.Add( CustomCA );

            // Maybe no errors occur during this check?
            if ( p_chain.Build( cert2 ) )
                return true;

            bool OK = true;
            foreach ( X509ChainStatus sts in p_chain.ChainStatus ) {
                if( sts.Status == X509ChainStatusFlags.UntrustedRoot ) {
                    // We already know that the custom root CA isn't trusted by .Net
                    // So we make sure the root in our custom chain is the custom root CA
                    X509Certificate2 root = p_chain.ChainElements[p_chain.ChainElements.Count - 1].Certificate;
                    if( root.Thumbprint != CustomCA.Thumbprint ) {
                        OK = false;
                        break;
                    }
                }
                else if ( sts.Status != X509ChainStatusFlags.NoError ) {
                    OK = false;
                    break;
                }
            }

            return OK;
        }

        static public void quaero_ca_create()
        {
            if ( CustomCA == null ) {
                // You must include your certificate.pem fil in your resources.
                Byte[] raw = NS.Properties.Resources.Custom_CA;
                CustomCA = ca_create( raw );
            }
        }
        static public X509Certificate2 ca_create( Byte[] raw)
        { 
            X509Certificate2 cert = new X509Certificate2();
            cert.Import( raw );
            return cert;
        }
    }
}

The above code is used with the following:

    System.Net.ServicePointManager.ServerCertificateValidationCallback = NS.Cls.ssl_verification;

As a comparison, this is how I did the same thing in Perl:

    my $ua = LWP::UserAgent->new;

    $ua->ssl_opts( SSL_ca_file => "/home/dw/prive/dw-app/SSL/Custom.CA.pem" );
    $ua->ssl_opts( verify_hostname => 1 );

The following posts helped me figure this out : https://stackoverflow.com/questions/33627593/c-sharp-net-how-to-allow-a-custom-root-ca-for-https-in-my-application-on, https://stackoverflow.com/questions/9508388/how-to-add-a-trusted-ca-certificate-not-a-client-certificate-to-httpwebrequest and https://social.msdn.microsoft.com/Forums/vstudio/en-US/1966a6e8-b6f4-44d1-9102-ec3a26426789/how-can-i-verify-a-certificate-manually-without-installing-its-parents?forum=clr.