Jul 31, 2013

Garmin NĂ¼vi connected as media device - disable MTP, enable mass storage

What is MTP mode and which automotive devices use it?


Some automotive devices use Media Transfer Protocol (MTP) for connecting to your computer. MTP provides a more secure environment for the important system files on your device.
MTP connectivity requires the following:
  • Windows XP with service pack 3 or later
  • Windows Media Player 11 or later
The following devices use MTP  mode:
  • dezl 760
  • nuvi 2405 series
  • nuvi 2407 series
  • nuvi 2408 series
  • nuvi 2505 series
  • nuvi 2507 series
  • nuvi 2508 series
  • nuvi 2707 series
  • nuvi 2708 series
  • nuvi 3400 series
  • nuvi 3500 series
  • nuvi 3507 series
  • nuvi 3508 series
  • RV 760
  • zumo 350
If the above system requirements are not met, or you are using the device on a Mac, the device will connect to the computer using standard mass storage mode instead of MTP mode.
Make NUVI DIR & Files visible for Backup

1. To make all of Nuvi files visible you must unhide protected files via Win7 like any other HD.
2. Start NUVI by itself and go to Volume Screen.
3. Press the upper right hand corner of screen for 10 seconds.
4. The Developers Screen will pop up
5. Scroll down to MTP SETTINGS
6. Change from AUTO DETECT to MASS STORAGE
7. Shut down NUVI and hookup to Computer USB cable
8. Start NUVI and it should recognize it is hooked up to the computer.
9. Explorer will now see all files in ROOT directory and the .System directories.


BTW, have you backed up your Nuvi? If not, then this would be a good time to do it. Could save a lot of grief later if you have a problem.


Apr 17, 2013

wp-admin: You do not have sufficient permissions to access this page

When migrating a Wordpress instalation some things could go wrong.

If you changed the table prefix, you might be getting this error when logging in the wordpress admin:

You do not have sufficient permissions to access this page

Solution:
Open phpmyadmin or something like that and go through the values in tables:
PREFIX_options
PREFIX_usermeta

find values that start with the old prefix, for example wp_ and change it to the new prefix.

in
wp_usermeta I changed all meta_key values from wp_* to newprefix_*
and in
wp_options I changed wp_user_roles to newprefix_user_roles.


Mar 30, 2013

siwapp :: File does not exists error


We tested siwapp application, which is an opensource invoicing application, but we had some problems, the error log was full of these:



[Sat Mar 30 17:32:55 2013] [error] [client xx.xx.xx.xx] File does not exist: /home/invoice/web/invoices

The site seemed to work fine otherwise.

It seemed that there was a problem with the app's .htaccess.

The main problem was here:
RewriteCond %{REQUEST_URI} \..+$
which matches all files with a dot in the filename, but the rule was ment to match files that start with a dot.

The fix for this is:
RewriteCond %{REQUEST_URI} /\..+$

After that fix, the app created errors because of a request for favicon.ico.
Well, the fix for that is simple enough
RewriteRule .+/favicon.ico$ favicon.ico [L]

So the whole .htaccess looks like this:
Options +FollowSymLinks +ExecCGI -MultiViews

AddDefaultCharset utf-8 

 
    Order deny,allow
    Deny  from all
 

 
    Order deny,allow
    Deny  from all
 


  RewriteEngine On

  # Rule to test if rewrite module is available during
  # the install process
  RewriteRule test_rewrite1\.txt test_rewrite2.txt
  
  RewriteRule .+/favicon.ico$ favicon.ico [L]

  # uncomment the following line, if you are having trouble
  # getting no_script_name to work
  #RewriteBase /

  # we skip all files with .something
  RewriteCond %{REQUEST_URI} /\..+$
  RewriteCond %{REQUEST_URI} !\.html$
  RewriteRule .* - [L]

  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f

  # no, so we redirect to our front web controller
  RewriteRule (.*) index.php [L,QSA]

Mar 25, 2013

Java, PHP :: RSA Asymmetric Encryption

Information Security and Privacy was a pretty fun and interesting class I had in college, I learned quite a lot of interesting new stuff, but when it came down to it, in practice, I had some problems implementing encrypted communication between Android (Java) frontend and PHP backend because of a tiny little detail.
Algorithm of choice was RSA and the most important part is to use "RSA/ECB/PKCS1PADDING" algorithm when calling Cipher instance in Java, other stuff is pretty straightforward.

RSA works like this.
Imagine a scenario where Alice sends an encrypted message to Bob.
As you can see, Alice encrypts data with Bob's public key, and only Bob can decrypt it, because only he has his private key.

Here's the Java code (Warning, some Android elements ahead)
public class Encryption {
 private static Key  privKey;
 private static PublicKey pubKey;
 private static PublicKey servPub;
 
 private static String  tag  = "Encryption";
 private static String[]  alg  = {"RSA","RSA/ECB/PKCS1PADDING"};
 private static String  hash  = "SHA1";
 private static String  serverPubKeyB64 = ""; //Bob's public key here
 
 
 public static String encrypt(String data) {
  return b64(encrpyt(data.getBytes()));
 }
 
 public static byte[] encrpyt(byte[] data) {
  genKey();
  try {
   Cipher c1 = Cipher.getInstance(alg[1]);
         c1.init(Cipher.ENCRYPT_MODE, getServPub());
         return c1.doFinal(data);
  } catch(Exception e) {
   Log.e(tag, "encrpyt", e);
  }
  return new byte[0];
 }
 
 public static void genKey() {
  if (privKey == null || pubKey == null) {
   Log.i(tag, "generating key");
   try {
    KeyPairGenerator kpg = KeyPairGenerator.getInstance(alg[0]);
    kpg.initialize(1024);
    KeyPair kp = kpg.generateKeyPair();
    privKey = kp.getPrivate();
    pubKey = kp.getPublic();
   } catch (Exception e) {
    Log.e(tag, "genKey", e);
   }
  }
 }
 
 public static PublicKey getServPub() {
  if(servPub == null) {
   try {
    byte[] encodedPublicKey = b64decode(serverPubKeyB64);
    
    KeyFactory keyFactory = KeyFactory.getInstance(alg[0]);
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey);
    PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
    
    return publicKey;
   } catch(Exception e) {
    Log.e(tag, "getServPub", e);
   }
  }
  return servPub;
 }
 
 public static PublicKey getPubKey() {
  genKey();
  return pubKey;
 }
 
 public static String getPubKeyB64() {
  PublicKey key = getPubKey();
  if(key != null) {
   return b64(getPubKey().getEncoded());
  } else {
   Log.e(tag, "getPubKeyB64 - key is null");
   return "";
  }
 }
 
 public static String b64(byte[] b) {
  return Base64.encodeToString(b, Base64.DEFAULT);
 }
 
 public static byte[] b64decode(String str) {
  return Base64.decode(str, Base64.DEFAULT);
 }
 
 public static String sha1(String data) {
  return sha1(data.getBytes());
 }
 
 
 public static String sha1(byte[] data) {
  return formatString(sha1bytes(data));
 }
 
 public static byte[] sha1bytes(byte[] data) {
  try {
   MessageDigest md = MessageDigest.getInstance(hash);
   return md.digest(data);
  } catch(Exception e) {
   Log.e(tag, "sha1", e);
   return new byte[0];
  }
 }
 
 @SuppressLint("DefaultLocale")
 public static String formatString(byte[] data) {
  StringBuilder sb = new StringBuilder();

  for (byte b : data) {
      sb.append(String.format("%02X", b));
  }
  
  return sb.toString().toLowerCase();
 }
}
And the PHP code:
class Encryption {

    public $pubkey = '...';

    public $privkey;
 
 public function __construct() {
  $this->privkey = openssl_pkey_get_private(file_get_contents('....pem'));
 }

    public function encrypt($data) {
        if (openssl_public_encrypt($data, $encrypted, $this->pubkey))
            $data = base64_encode($encrypted);
        else
            throw new Exception('Unable to encrypt data.');

        return $data;
    }

    public function decrypt($data) {
        if (openssl_private_decrypt(base64_decode($data), $decrypted, $this->privkey))
            $data = $decrypted;
        else
            $data = '';

        return $data;
    }
}

Jan 9, 2013

DKIM + SPF + Sendmail for multiple domains (Ubuntu)

First things first,

DKIM is DomainKeys Identified Mail and is used in mail servers, such as Postfix or Sendmail to sign e-mails and thus authenticating the sender so that a forgery can be detected. It also reduces the possibility of an e-mail being flagged as spam, but it's not a definite prevention.

A much simpler method is using SPF (Sender Policy Framework) which, in a nutshell, verifies the sender IP address.

According to the internet, using both should result to ????, PROFIT !!!.

SPF does not need a specific configuration. Whitelisted servers are listed in a DNS record, TXT or SPF, and an example record is:

example.com. IN TXT "v=spf1 a mx ~all"

And that's preety much it, for the simplest case there is. This record specifies the policy (v=spf1), whitelisted servers (a and mx records), and ~all states that every other IP address should be tagged as SOFTFAIL.
It can get much more complicated than this, so RTFM.

Okay, so, DKIM.

DKIM includes a cryptographic hash in the e-mail header which is calculated with the private key (on the server) and verified with the public key (in the DNS record).
DKIM-Signature: v=1; a=rsa-sha256; d=example.net; s=brisbane;
     c=relaxed/simple; q=dns/txt; l=1234; t=1117574938; x=1118006938;
     h=from:to:subject:date:keywords:keywords;
     bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;
     b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZ
              VoG4ZHRNiYzR


First, install opendkim.
apt-get install opendkim

Edit the configuration file of opendkim.conf, located in /etc/opendkim.conf.
AutoRestart             Yes
UMask                   002
Syslog                  yes
AutoRestartRate         10/1h
Canonicalization        relaxed/simple
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
KeyTable                refile:/etc/opendkim/KeyTable
LogWhy                  Yes
Mode                    sv
PidFile                 /var/run/opendkim/opendkim.pid
SignatureAlgorithm      rsa-sha256
SigningTable            refile:/etc/opendkim/SigningTable
Socket                  inet:8891@localhost
SyslogSuccess           Yes
TemporaryDirectory      /var/tmp
UserID                  opendkim:opendkim
As you can see, there are three more files to be added, TrustedHosts (whitelisted IPs that can sign e-mails), KeyTable (multiple domain configuration for public and private keys) and SigningTable (whitelisted users that can sign e-mail).

/etc/opendkim/TrustedHosts:
127.0.0.1
example.com
192.168.0.1/24
You get the idea.

/etc/opendkim/SigningTable:
*@example.com default._domainkey.example.com
All users from @example.com can sign. You can specifiy usernames and domains, instead of the wildcard, for additional security.

/etc/opendkim/KeyTable:
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com.pvt
Location of the private key and name of the DNS record for each domain. The "default" before _domainkey.example.com and :default: is a selector. This can be changed to something else.

Next, we need to generate the public and private key for each domain.
Shouldn't be too difficult.
If some folders don't exist, just create them.
root@ubuntu:/etc/opendkim/keys# opendkim-genkey -D /etc/opendkim/keys/example.com -d example.com -s default
Again -s flag is for the selector. If you changed it, you need to enter it here.
The command generates a private key (default) and public key (default.txt). You will probably rename them, to match the configuration.
An important note here is that the files are owned by user opendkim, or you will get permission denied errors in /var/log/mail.err. Default permissions on those files are -rw------.

Move the private key to where you specified it should be in the KeyTable.
Insert the public key in your DNS as a TXT record.

Next up, telling sendmail to talk to opendkim.
Edit /etc/mail/sendmail.mc and add this line at the end. DO NOT EDIT sendmail.cf.
INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@localhost')

Rebuild sendmail configuration and restart, start opendkim if it's not running yet
root@ubuntu:~# sendmailconfig; service sendmail restart; service opendkim start
Test it out.

That's it, you're done!