SwiftMailer 5, PHP5, and ISO-8859-15

I’ve been using SwiftMailer for as long as I can remember because it’s, IMHO, a great library and far more logical than PHPMailer and “others”. While maintaining a PHP5 codebase for a rather large project, I ran into an issue while using ISO-8859-15 encoded data. Most people won’t care about ISO-8859-15 over ISO-8859-1 (“Latin1”), but since I live in Europe, I prefer to have support for the €uro character 🙂

To make a long story short, if you need SwiftMailer 5 to properly handle ISO-8859-15, look for a line in “MimePart.php” that looks like this:

if (!in_array($charset, array('utf-8', 'iso-8859-1', ''))) {

and change it to this:

if (!in_array($charset, array('utf-8', 'iso-8859-15', 'iso-8859-1', ''))) {

(Yes, the project will move to a PHP7 codebase at some not so distant point in the future.)

Things to do after migrating to Zimbra 8.8.x

As I recently handled a migration from Zimbra 8.7.11 to Zimbra 8.8.12, I’ve been running into things I think the Zimbra updater should handle by itself, and/or things that should be documented in a more practical way than they currently are. I’ll just keep updating this post with things I find and learn.

(The migration turned into an 18 hour job since we ran into a +1 year old problem where an Ubuntu upgrade form 14.04.LTS to 16.04.LTS more or less wipes your Zimbra setup and leaves it in a very sorry state. Fortunately, I managed to piece it back by hand.)

Zimbra Backup NG

The new and improved Zimbra Backup NG should be enabled IMHO. It does things a lot better than the previous version(s). In a number of places, Zimbra makes references to its improvements, and so on. They should probably include this instruction too:

To disable the “classic” (or “legacy”) backups, a simple

zmschedulebackup -F

(as the “zimbra” user) is all you need to execute. (You may want to hang on to your old backups until they’ve outlived their purpose though. This command only disables/removes the scheduled “legacy” backups.)

Lightbox for Bootstrap 4 and jQuery

Lightbox (or “image preview”) functionality for Bootstrap 4 without additional libraries (apart from jQuery).

Written by Joaquim Homrighausen <joho@webbplatsen.se>
30-May-2019
TEAMYUJO

Do as you wish with this 🙂

This is the Javascript/jQuery code for the Bootstrap 4 modal. You don’t have to use jQuery to accomplish this obviously.

$(document).ready(function($) {

  $(".xslightbox").click(function () {
    if ($(this).attr("data-message") != "undefined") {
      document.getElementById("lightbox_target").src = "";
      document.getElementById("lightbox_target").src = $(this).attr("data-message");
    }
    if ($(this).attr("data-title") != "undefined") {
      document.getElementById("lightbox_title").innerText = $(this).attr("data-title");
      }
    $("#xslightmodal").modal("show");
  });
  /* This will focus the close button, but you don't really need to do this or
     have a close button for that matter since Bootstrap will close the modal
     if you click outside the modal or - in this case - press the Esc key */
  $("#xslightmodal").on("shown.bs.modal", function () {
    $("#lightbox_close").trigger("focus");
  });

});

This is the HTML for the Bootstrap 4 modal. You can style it any which way you want. The key to getting the image to behave as you want it (i.e. to make the image responsive) is adding the “img-fluid” class to the img tag.

You can add the “fade” class to the modal if you want it to be “animated”.

<div class="modal" id="xslightmodal" tabindex="-1" role="dialog" aria-hidden="true" data-keyboard="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content bg-light">
      <div class="modal-header">
        <div class="modal-title text-lowercase text-monospace small" id="lightbox_title">
          placeholder
        </div>
      </div>
      <div class="modal-body text-center">
        <img id="lightbox_target" class="img-fluid border border-secondary rounded" />
      </div>
      <div class="modal-footer">
        <button type="button" tabindex="-1" id="lightbox_close" class="btn btn-primary btn-sm" data-dismiss="modal">'.
          Close
        </button>
      </div>
    </div>
  </div>
</div>

And then, to use the lightbox, you need:

<a class="xslightbox" title="Preview me"
   data-message="https://url/to/image/or/loader/script"
   data-title="Name of image">Preview</a>

This is also available as a gist on GitHub. Knock yourself out 🙂

Simple password construct validator for PHP

/* 
 * Simple password construct validator for PHP 
 * Joaquim Homrighausen <joho@webbplatsen.se>
 * May 30, 2019 
 * TEAMYUJO 
 * 
 * Do whatever you want with this snippet :) 
 * 
 * This may not necessarily agree with the section
 * "Strength of Memorized Secrets" in the document
 * from NIST:
 *
 * NIST Special Publication 800-63B 
 * Digital Identity Guidelines 
 * Authentication and Lifecycle Management 
 * https://pages.nist.gov/800-63-3/sp800-63b.html 
 */

function password_check_construct ($pstr, $min_length = 8)
{
  //Setup pattern and stuff minimum requested length into it
  if ($min_length < 4) {
    //We need at least four characters to satisfy our regexp
    $min_length = 4;
  }

  $match_rules = '/^(?=.{'.(int)$min_length.',})(?=.*[a-z])(?=.*[0-9])(?=.*[A-Z])(?=.*[[:punct:]]).*$/';

  //Require at least one a-z, one A-z, one 0-9, and one punctuation/special character
  if (preg_match ($match_rules, $pstr) === 1) {
    return (true);
  }
  return (false);
}

This is also available as a gist on GitHub. Knock yourself out 🙂

Using sfdisk to recover a partition table on Linux

As he re-entered the sfdisk dump manually in the remote recovery console, using the devil’s editor (vi), he was silently thanking the Linux developers for not screwing around with the file system when it cannot be mounted.

Messing around with partition tables, disk volumes, and similar critical configuration parameters can lead to quite unexpected and unintended results. So, it may be a good idea to actually dump the current configuration before you begin your magic.

Using sfdisk, you can dump your Linux partition configuration in a fairly straightforward way. You can try the command by typing just sfdisk -d /dev/disk, where disk is one of the disks in your Linux system. For a list of disks in your system, use the lsblk command. They are identified as “disk” (surprise).

sfdisk -d /dev/sda > sda.txt

This would dump the partition table data for the /dev/sda disk to the file sda.txt. Your output will look something like this:

label: dos
label-id: 0xa828a5d8
device: /dev/sda
unit: sectors

/dev/sda1 : start= 2048, size= 997376, type=83, bootable
/dev/sda2 : start= 999424, size= 999424, type=82
/dev/sda3 : start= 1998848, size= 249659359, type=83

The partition table information can then later be restore by issuing the reverse, i.e.

sfdisk /dev/sda < sda.txt

DO NOT PERFORM THE ABOVE COMMAND IF YOU DON’T KNOW WHAT YOU ARE DOING!

This procedure may come in handy if you, like me, manage to screw up the partition table and find yourself at the (initramfs) prompt when you restart your Linux machine. You will (obviously) need to save the dump file (sda.txt above) in a location other than your computer. Using this method, it’s often possible to recover your partition table from a rescue boot (be it on CD, DVD or a flash drive).

I happened to have a previous terminal session window open with the above information, so I hand-typed it from one window to another, where I was running the remote recovery console.

There are a lot more complex partition setups than the above, and sfdisk may not work in those cases or for certain RAID and LVM setups. But it it’s a good procedure in applicable situations.

Show which process/program is listening to what port using netstat and lsof

lsof -Pnl +M -i4
lsof -Pnl +M -i6

or

netstat -tulpn
netstat -npl

There are obviously a number of ways to accomplish this, but these variations will cover a lot of ground. You can also combine this with grep to filter out things you don’t need to see, or to only include specific processes and/or ports.

See post from @geek1968 on Instagram

Filmjölk, Google Translate och Machine Learning

Det pratas mycket om machine learning och deep learning inom IT.

Ibland har man lite otur när man tänker 🙄🤔

Deep learning i sitt esse hos Google Translate:

Filmjölk -> Sour milk
Sour milk -> Surmjölk
Surmjölk -> Sour
Sour -> Sur

Vilket kanske mer poängterar att vi ibland måste tänka lite extra när vi uttrycker oss i “självklara termer”.

Saker som vi upplever som självklarheter kan lätt misstolkas av mottagaren och ge helt andra signaler än de vi tänkt oss.

Apache goodies for WordPress security

The list of things to do to harden a WordPress site with Apache is long, but some things that could be done include:

FileETag None                                                                                                                       
                                                                                                                                    
<Files wp-config.php>                                                                                                               
    Require all denied                                                                                                              
</Files>                                                                                                                            
                                                                                                                                    
<Files xmlrpc.php>                                                                                                                  
    Require all denied                                                                                                              
</Files>                                                                                                                            
                                                                                                                                    
<LocationMatch "/wp-content/uploads/.*(?i)\.php$">                                                                                  
    Require all denied                                                                                                              
</LocationMatch>