Tuesday, March 27, 2018

PHP can't write to directory although it should

If PHP is not writing to a directory (e.g. you can't upload files) although all directory permissions as well as PHP and Apache settings and configuration are correct then, in case you are on CentOS 7 (or RedHat 7), the culprit may be SELinux. Just disable it or, if needed, allow writing to the directory of interest using chcon command:

To disable SELinux

To resolve the issue with SELinux enabled

Thursday, March 8, 2018

How to configure drupal with clean URLs

There is some confusion on drupal.org (and other sites) on how exactly to do that: multiple conflicting articles, incomplete instructions, etc. The way to do it is to basically include the correct set of httpd.conf directives for all three of the following directories (assuming the default/usual directories are used):
  • /var/www 
  • /var/www/html
  • /var/www/html/sites/default
The httpd.conf sections for the first two directories normally already exist by default; the third one needs to be created. No .htaccess files need to be used; everything can be done in the httpd.conf file. Here is the relevant listing from my httpd.conf file that successfully configured Drupal with clean URLs for me:

#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "/var/www/html"

#
# Relax access to content within /var/www.
#
<Directory "/var/www">
    AllowOverride All
    # Allow open access:
    Require all granted
</Directory>

# Further relax access to the default document root:
<Directory "/var/www/html">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks
    #Options Includes ExecCGI FollowSymLinks MultiViews

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    #AllowOverride None
    AllowOverride All

    #
    # Controls who can get stuff from this server.
    #
    Require all granted

        RewriteEngine on
        RewriteBase /
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        #RewriteCond %{REQUEST_URI} !=/favicon.ico
        #RewriteRule ^ index.php [L]
        RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

</Directory>

<Directory "/var/www/html/sites/default">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks
    #Options Includes ExecCGI FollowSymLinks MultiViews

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    #AllowOverride None
    AllowOverride All

    #
    # Controls who can get stuff from this server.
    #
    Require all granted

        RewriteEngine on
        RewriteBase /
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        #RewriteCond %{REQUEST_URI} !=/favicon.ico
        #RewriteRule ^ index.php [L]
        RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

</Directory>


How to integrate PDFBox into WildFly 11

There are no specific instructions on how to do this. Here is how I did it and it works fine for my project:

  1. Add the three main PDFBox jar files as a WildFly module. To do this you have to create a new appropriately named folder under WildFly's installation directory. Like this: <some random directory>/wildfly-11.0.0.Final/modules/system/layers/base/org/apache/pdfbox/main

  2. Then, in that directory wget the three main PDFBox jar files. Currently the latest are the  ones that also appear in the XML listing right below.

  3. Then, in the same directory, create an XML file thusly:

    <?xml version="1.0" encoding="UTF-8"?>
    <module xmlns="urn:jboss:module:1.5" name="org.apache.pdfbox">
        <resources>
            <resource-root path="pdfbox-2.0.8.jar"/>
            <resource-root path="fontbox-2.0.8.jar"/>
            <resource-root path="xmpbox-2.0.8.jar"/>
        </resources>
    
        <dependencies>
            <module name="javax.api"/>
            <module name="org.apache.commons.logging"/>
        </dependencies>
    </module>
    

  4. Now what we need is to declare the newly added pdfbox WildFly module as a global one, i.e. one that can be referenced from any deployment in our WildFly instance. To do this we need to edit our standalone.xml or domain.xml file. In the case of out pdfbox module the global declaration needs to be done under the <subsystem xmlns="urn:jboss:domain:ee:4.0"> section of the file which, for WildFly 11, it already exists and is at version 4.0. Please note that for other WildFly configurations you may need to create it altogether or you may have a different ee version number. In my case what I did is I added the following simple XML markup at the end of the section:

    <global-modules>
        <module name="org.apache.pdfbox" slot="main" />
    </global-modules>
    

  5. Restart your WildFly and you should be on!

Monday, March 5, 2018

Date expiration (licensing) in a VSTO Office Add-In

Sometimes you want to have a VSTO Office add-in you've developed stop working on a specific date; this is usually done for licensing related purposes.

Here's how to gracefully stop a VSTO Office add-in from working before it even loads any Ribbon elements. Basically you have to modify the code in your ThisAddIn class to look like this:

    public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        private Boolean isExpired()
        {
            DateTime end = DateTime.Parse("2018-03-21"); //This can be any date you like
            DateTime today = DateTime.Today;

            if (today >= end)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        protected override Microsoft.Office.Core.
            IRibbonExtensibility CreateRibbonExtensibilityObject()
        {
            if (!isExpired())
            {
                return new Ribbon1(); //Or whatever your ribbon class is called
            }
            else
                return null;
        }

        ... //Unrelated code from here on 
    }

Don't try to stop the Add-In from loading in the ThisAddIn_Startup() method as this gets called after the Add-In's Ribbon elements get loaded and display in the Office application.

Sunday, February 25, 2018

Find which process holds a particular connection to a MySQL database

Finding which process holds a particular connection to a MySQL database is often not immediately obvious or well documented.

First do this in your mysql command line client:
mysql> show full processlist;
+-----+--------+-----------------+----------+---------+------+----------+-----------------------+
| Id  | User   | Host            | db       | Command | Time | State    | Info                  |
+-----+--------+-----------------+----------+---------+------+----------+-----------------------+
|   2 | root   | localhost       | adspider | Query   |    0 | starting | show full processlist |
| 257 | fotios | localhost:35828 | adspider | Sleep   |   20 |          | NULL                  |
| 259 | fotios | localhost:35832 | adspider | Sleep   |   17 |          | NULL                  |
| 261 | fotios | localhost:35836 | adspider | Sleep   |    3 |          | NULL                  |
| 263 | fotios | localhost:35840 | adspider | Sleep   |    1 |          | NULL                  |
+-----+--------+-----------------+----------+---------+------+----------+-----------------------+
5 rows in set (0.00 sec)

Then, on your Linux command line do this to see which process holds the socket to the port of interest:

[root@li1849-192 ~]# netstat -np | grep 35828
tcp6       0      0 127.0.0.1:35828         127.0.0.1:3306          ESTABLISHED 28509/java
tcp6       0      0 127.0.0.1:3306          127.0.0.1:35828         ESTABLISHED 28432/mysqld

In my case the connection to MySQL was being made by a java process via JDBC

Tuesday, February 13, 2018

letsencrypt.org makes everyone less secure

letsencrypt.org have taken DV (Domain Validation) certificate issuance requirements a notch down.

So, verification of domain ownership simply requires access to the server where the domain points - no domain administrative contact email verification, no registration with the site/CA required. This is very convenient, especially as the certs are also free and their installation (even their renewal) is done automatically on Apache by letsencrypt's software agent (see here), but it is also fairly insecure, which given that this is a CA that issues SSL certs acceptable by all major browsers, makes everyone less secure.

To explain, using them, an attacker that has compromised a DNS A record can also spoof the website normally under that domain WITHOUT breaking https. That cannot be good.


Monday, January 1, 2018

Ways to open the task pane in a task pane Office add-in

Old style task pane addins (Office 2013) get embedded in the open document at the time of add-in installation and persist in it. The task pane can be closed but when the document is reopened the task pane re-opens too. If a user that does not have the add-in installed and tries to open the document he will be prompted to install the add-in.

With newer task pane add-ins (Office 2016) the task pane can either be opened from an Office UI Ribbon button or be auto-opened on document launch, for properly tagged documents, via the new auto-open feature, see: https://docs.microsoft.com/en-us/office/dev/add-ins/design/automatically-open-a-task-pane-with-a-document