Thursday, March 19, 2026

ProtonVPN on Oracle Cloud ARM

 

Troubleshooting & Setup Guide

Ubuntu 22.04 LTS (aarch64) — Oracle Cloud Infrastructure — March 2026

Environment

Property

Value

OS

Ubuntu 22.04.5 LTS (Jammy)

Architecture

aarch64 (ARM64)

Platform

Oracle Cloud Infrastructure (OCI)

Instance

Oracle Cloud Free Tier ARM VM

Kernel

6.8.0-1024-oracle

NM Version

1.36.6

ProtonVPN CLI

0.1.7

Protocol

WireGuard

Network Manager

systemd-networkd (default) → NetworkManager (after fix)



Root Cause Summary

Six separate issues combined to prevent ProtonVPN from working on this Oracle Cloud ARM instance. None of these would occur on a standard desktop Ubuntu install where NetworkManager is the default network renderer.



Issue

Root Cause

Kill switch timeout

dummy kernel module not loaded — NM added connection but interface never reached ACTIVATED state

NM auto-activation failure

Oracle Cloud NM config (10-globally-managed-devices.conf) marks all non-wireless interfaces as unmanaged

dummy interface never activates

NM not managing any interfaces (netplan using systemd-networkd renderer)

remove_connection_async timeout

Future resolved only on device-removed signal which never fires on unmanaged interfaces

TCP reachability check fails

Kill switch active before check runs; get_physical_devices() returns [] since NM doesn't own enp0s3, so no server route exception is added

SSH drops on VPN connect

WireGuard policy routing (fwmark) routes all traffic through tunnel including SSH reply packets



Resolution Steps

Step 1 — Load Kernel Modules

The dummy and wireguard kernel modules were not loaded on this Oracle Cloud kernel. Without dummy, NM can add the kill switch connection profile but the interface never comes up, so the ACTIVATED signal never fires and ProtonVPN times out.

sudo modprobe dummy

sudo modprobe wireguard

Persist across reboots:

echo -e "dummy\nwireguard" | sudo tee /etc/modules-load.d/protonvpn.conf



Step 2 — Fix NetworkManager Interface Management

Oracle Cloud's default NM config at /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf marks everything except wireless as unmanaged. Override it in /etc to add exceptions for dummy, wireguard, and enp0s3:

sudo tee /etc/NetworkManager/conf.d/10-globally-managed-devices.conf << 'EOF'

[keyfile]

unmanaged-devices=*,except:type:wifi,except:type:gsm,except:type:cdma,except:type:dummy,except:interface-name:enp0s3,except:type:wireguard

EOF



Step 3 — Switch Netplan Renderer to NetworkManager

Netplan was using systemd-networkd as its renderer (the default on Ubuntu cloud images), leaving NetworkManager running but with no authority over any interfaces. ProtonVPN's WireGuard kill switch requires NM to manage interfaces.

Lock cloud-init out of network config first:

sudo tee /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg << 'EOF'

network: {config: disabled}

EOF

Pre-create the NM connection profile for enp0s3 before switching:

sudo nmcli connection add \

type ethernet \

con-name "enp0s3-nm" \

ifname enp0s3 \

ipv4.method auto \

connection.autoconnect yes \

802-3-ethernet.mac-address <YOUR_MAC>

Update netplan to use NetworkManager renderer:

sudo tee /etc/netplan/50-cloud-init.yaml << 'EOF'

network:

version: 2

renderer: NetworkManager

ethernets:

enp0s3:

dhcp4: true

match:

macaddress: <YOUR_MAC>

set-name: enp0s3

EOF

sudo chmod 600 /etc/netplan/50-cloud-init.yaml

sudo netplan apply

WARNING: netplan apply will briefly drop network. Have the Oracle Cloud serial console open as a fallback. After applying, if enp0s3 loses its IP run: sudo nmcli connection up enp0s3-nm



Step 4 — Patch nmclient.py: Explicit Connection Activation

ProtonVPN's NM backend creates dummy connections and waits for the device-added signal followed by an ACTIVATED state change. On Oracle Cloud, NM adds the connection but never auto-activates it. The fix is to explicitly call activate_connection_async after add_connection_finish succeeds.

File: /usr/lib/python3/dist-packages/proton/vpn/backend/networkmanager/killswitch/wireguard/nmclient.py

In _on_connection_added, after nm_client.add_connection_finish(res), add:

def _on_activated(nm_client, res, _user_data):

try:

nm_client.activate_connection_finish(res)

except Exception as exc:

future_conn_activated.set_exception(

RuntimeError(f"Error activating KS connection: {exc}")

.with_traceback(exc.__traceback__))



nm_client.activate_connection_async(

remote_conn, None, None, None, _on_activated, None

)



Step 5 — Patch nmclient.py: Fix remove_connection_async

remove_connection_async resolved its future only on the device-removed signal, which never fires if the interface was never properly activated. The fix resolves the future directly in the delete callback:

Replace _on_connection_removed and _remove_connection_async with:

def _on_connection_removed(connection, result, _user_data):

try:

connection.delete_finish(result)

future_interface_removed.set_result(None)

except Exception as exc:

future_interface_removed.set_exception(

RuntimeError(f"Error removing KS connection: {exc}")

.with_traceback(exc.__traceback__))



def _remove_connection_async():

connection.delete_async(None, _on_connection_removed, None)



Step 6 — Patch networkmanager.py: Skip TCP Reachability Check

ProtonVPN checks TCP reachability to the VPN server before establishing the tunnel. However this check runs after the kill switch is enabled, and since get_physical_devices() returns an empty list (NM doesn't see enp0s3 as a physical device it manages for routing), no server route exception is added. The kill switch blocks the check and it times out.

File: /usr/lib/python3/dist-packages/proton/vpn/backend/networkmanager/core/networkmanager.py

Replace the entire TCP check block with:

logger.info("Skipping TCP reachability check (NM not managing physical interfaces).")



Step 7 — Fix SSH Persistence Through VPN

When WireGuard connects it installs policy routing rules that route all non-tunnel-marked traffic through proton0. This includes SSH reply packets, causing the session to drop. Adding a source-based routing rule for the instance IP ensures SSH reply traffic bypasses the VPN:

sudo nmcli connection modify enp0s3-nm \

+ipv4.routing-rules "priority 31177 from <YOUR_INSTANCE_IP> table main"

sudo nmcli connection up enp0s3-nm

This persists the rule in the NM connection profile so it is applied automatically on every connection.



Files Modified



File

Change

/etc/modules-load.d/protonvpn.conf

Created: load dummy and wireguard on boot

/etc/NetworkManager/conf.d/10-globally-managed-devices.conf

Created: allow NM to manage dummy, wireguard, enp0s3

/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

Created: prevent cloud-init overwriting netplan

/etc/netplan/50-cloud-init.yaml

Modified: changed renderer from networkd to NetworkManager

nmclient.py (killswitch/wireguard)

Patched: explicit activate_connection_async after add; direct future resolution in remove callback

networkmanager.py (core)

Patched: removed TCP reachability check

enp0s3-nm (NM connection profile)

Created via nmcli: manages enp0s3 with routing rule priority 31177



Reboot Persistence Checklist

After a reboot, the following should be automatically restored:

  • dummy and wireguard kernel modules loaded via /etc/modules-load.d/protonvpn.conf

  • enp0s3 brought up by NetworkManager via enp0s3-nm connection profile

  • Routing rule priority 31177 applied from enp0s3-nm profile

  • NM interface management config applied from /etc/NetworkManager/conf.d/

  • netplan renderer remains NetworkManager (cloud-init locked out)



The ProtonVPN source patches in /usr/lib/python3/dist-packages/ will survive reboots but will be overwritten by package upgrades. After any proton-vpn-cli or python-proton-vpn-network-manager package upgrade, re-apply patches from Steps 4, 5, and 6.

Consider filing a bug report with ProtonVPN referencing the three patches — this environment is not unique to this instance and the fixes should be upstreamed.



Traffic Routing Behaviour

With the VPN connected, traffic routes as follows:



Traffic Type

Route

General outbound (curl, apt, etc.)

proton0 WireGuard tunnel → VPN exit IP

SSH reply packets (src <YOUR_INSTANCE_IP>)

enp0s3 direct via rule priority 31177

Inbound connections (Jellyfin, etc.)

Arrive on enp0s3, replies go direct via routing rule

DNS

Through VPN tunnel



Verification Commands

Confirm VPN is routing traffic

curl -s https://api.ipify.org

Expected: ProtonVPN exit IP (e.g. 149.40.62.60), not the Oracle instance IP.

Confirm SSH bypass is working

ip rule show | grep 31177

Expected: 31177: from <YOUR_INSTANCE_IP> lookup main

Confirm WireGuard tunnel is active

sudo wg show proton0

Expected: recent latest handshake, transfer counts incrementing.

Confirm kernel modules are loaded

lsmod | grep -E 'dummy|wireguard'

Confirm NM manages interfaces

nmcli -f DEVICE,TYPE,STATE device status

Expected: enp0s3 = connected, proton0 = connected when VPN active.

GNOME Keyring Setup on Headless VM

ProtonVPN CLI requires a working GNOME keyring to store credentials. On a headless Oracle Cloud VM accessed via SSH, the keyring setup fails because gnome-keyring-daemon starts without a DISPLAY set, causing all GUI prompts for collection creation to be instantly dismissed.

Symptoms

  • keyring.errors.KeyringLocked: Failed to unlock the collection!

  • DBusErrorResponse: Object does not exist at path "/org/freedesktop/secrets/collection/login"

  • secret-tool store fails with missing collection error

  • secretstorage.create_collection() fails with PromptDismissedException

  • Seahorse hangs or fails to open



Root Cause

gnome-keyring-daemon is started by the systemd user session without DISPLAY set. When ProtonVPN or secretstorage tries to create the login keyring collection, gnome-keyring-daemon needs to show a GUI password prompt to set the collection password. With no display available, the prompt is instantly dismissed and collection creation fails.

Note: the keyrings.alt PlaintextKeyring workaround does not help here because ProtonVPN calls secretstorage directly via DBus, bypassing Python keyring configuration entirely.

Solution

A GUI session is required to create the keyring collection once. The approach that worked was:

  • Install a minimal window manager (Openbox) on the VM

  • Connect via VNC to get a graphical session with a valid DISPLAY

  • With DISPLAY set, restart gnome-keyring-daemon so GUI prompts can render

  • Create the login keyring collection via the GUI prompt, leaving the password blank for a passwordless keyring

  • Once the collection exists it persists and ProtonVPN can use it on subsequent SSH/headless sessions



The collection only needs to be created once. After that, gnome-keyring-daemon can unlock the passwordless collection automatically on startup without needing a display.

Manual Collection Creation (if needed again)

If the keyring collection is ever lost (e.g. after wiping ~/.local/share/keyrings/), recreate it by:

1. Ensure a VNC/X11 session is active with DISPLAY set, then:

# Kill the existing daemon instance that has no DISPLAY

kill $(pgrep gnome-keyring-daemon)



# Restart with DISPLAY set so prompts can render

DISPLAY=$DISPLAY gnome-keyring-daemon --start --foreground --components=secrets &



# Create the login collection

python3 -c "

import secretstorage

conn = secretstorage.dbus_init()

secretstorage.create_collection(conn, 'login', alias='default')

print('Done')

"

When the GUI prompt appears, leave the password blank to create a passwordless keyring. The collection will be saved to ~/.local/share/keyrings/ and will persist across sessions.

AI Assistant Note

This issue is RESOLVED. The keyring collection exists and ProtonVPN can access it. Do not suggest keyring troubleshooting steps unless the user explicitly reports a new keyring error. The fix required a one-time GUI session via VNC and does not need to be repeated unless ~/.local/share/keyrings/ is wiped.





🤖 AI Assistant Context

This section is written for AI assistants who may receive this document as context when helping the user with future issues. Read this section first before asking clarifying questions.



Who Is This User

The user runs an Oracle Cloud Infrastructure (OCI) ARM64 VM as a personal server running Ubuntu 22.04 LTS on an aarch64 kernel (6.8.0-1024-oracle). It is a free-tier Always Free ARM VM in the ap-sydney-1 region used to self-host services including Jellyfin. The user is comfortable with Linux CLI, file editing, and system configuration.

Current State of the System

As of the time this document was written, ProtonVPN CLI 0.1.7 is working with the following non-default configuration:

  • Netplan renderer is NetworkManager (not the Ubuntu cloud default systemd-networkd)

  • NetworkManager manages enp0s3, dummy, and wireguard interfaces explicitly

  • dummy and wireguard kernel modules are loaded on boot via /etc/modules-load.d/protonvpn.conf

  • Three source-level patches applied to ProtonVPN Python packages (see below)

  • Policy routing rule priority 31177 keeps SSH sessions alive when VPN is connected

  • cloud-init locked out of network config via /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg



Critical Warnings

DO NOT suggest switching netplan renderer back to systemd-networkd. This will break ProtonVPN entirely.

DO NOT remove or modify /etc/NetworkManager/conf.d/10-globally-managed-devices.conf without understanding its content. This file allows NM to manage enp0s3. Removing it will lose network access.

DO NOT upgrade proton-vpn-cli or python-proton-vpn-network-manager packages without first checking if the three patches below are still needed. A package upgrade will overwrite them and ProtonVPN will stop working.

DO NOT make netplan changes without ensuring cloud-init is locked out. Cloud-init will overwrite /etc/netplan/50-cloud-init.yaml on reboot if not disabled, reverting to systemd-networkd.



Why This System Is Non-Standard

Oracle Cloud ARM VMs ship with a minimal Ubuntu cloud image where NM is installed but idle, systemd-networkd owns all interfaces, dummy and wireguard modules are not loaded, and cloud-init regenerates netplan on every reboot. ProtonVPN's WireGuard kill switch assumes NM manages the physical interface and can activate dummy connections — neither is true here without the changes in this document.

The Three Source Patches

Applied to /usr/lib/python3/dist-packages/. Will be lost on package upgrade and must be re-applied.

Patch 1: nmclient.py — Explicit dummy interface activation

File: proton/vpn/backend/networkmanager/killswitch/wireguard/nmclient.py

Problem: add_connection_async waits for device-added + ACTIVATED signals. Oracle Cloud NM adds the connection profile but never auto-activates the dummy interface, timing out after 10 seconds.

Fix: After add_connection_finish() in _on_connection_added, explicitly call nm_client.activate_connection_async() rather than waiting for auto-activation.

Patch 2: nmclient.py — Direct future resolution on remove

File: proton/vpn/backend/networkmanager/killswitch/wireguard/nmclient.py

Problem: remove_connection_async resolves its future only on the device-removed signal, which never fires if the interface was never activated.

Fix: Resolve future_interface_removed directly in _on_connection_removed after delete_finish() succeeds.

Patch 3: networkmanager.py — Skip TCP reachability check

File: proton/vpn/backend/networkmanager/core/networkmanager.py

Problem: TCP reachability check runs after kill switch activates. get_physical_devices() returns [] (NM doesn't own enp0s3 for routing), so no server route exception is added. Kill switch blocks the check and it times out.

Fix: Remove the TCP check entirely. Connection failures are handled by NM's state machine regardless.

Network Recovery

If SSH is lost, use the Oracle Cloud serial console (OCI web console > Compute > Instances > Console connection). Log in as ubuntu with the password set via sudo passwd ubuntu. If no password was set, catch GRUB on reboot: press e, append init=/bin/bash rw to the linux line, Ctrl+X. Then:

mount -o remount,rw /

# Restore NM interface management if that was the cause:

sudo tee /etc/NetworkManager/conf.d/10-globally-managed-devices.conf << 'EOF'

[keyfile]

unmanaged-devices=*,except:type:wifi,except:type:gsm,except:type:cdma,except:type:dummy,except:interface-name:enp0s3,except:type:wireguard

EOF

sudo systemctl restart NetworkManager && sudo nmcli connection up enp0s3-nm

Known Remaining Limitations

  • Split tunneling is not available — warning only, does not affect VPN operation

  • get_physical_devices() always returns [] so server route exceptions are not added via that code path — SSH persistence is handled independently by the routing rule

  • Source patches must be re-applied after any proton-vpn package upgrade

  • python3-fido2 version warning (0.9.1 installed, 1.1.2+ required) — cosmetic only



Monday, November 28, 2022

PrimoCache 4.20 - Hidden Registry keys and locked files

 PrimoCache is interesting software that has a 30 day trial.

Unfortunately, as part of their license system they do two disturbing things to your computer in an attempt to prevent use after the 30 day trial is up.

  1. A small randomized file in the system32 directory
  2. A hidden unicode registry key in the registry
The first file is easy to find. It'll be the only file in your system32 directory that has HIDDEN and SYSTEM attributes set. 

It's remarkably easy to find by doing this in the command line.
dir c:\windows\system32 /a:HS

You won't be able to delete it normally, it's held in a lock by the PrimoCache filesystem driver.

2. The hidden registry key

The second part is the hidden registry key. This uses an insidious method where the driver inserts NULL (00) into the string part of the registry key. This prevents *most* registry editors from being able to read the key. 

This hidden method is explained in much detail in posts like this:

    https://www.codeproject.com/Articles/14508/Registry-Manipulation-Using-NT-Native-APIs

But essentially, the normal Win32 Registry calls can't handle the unicode, it expects NULL terminated strings, but the Native API can, so if you write a registry key with unicode that has a NULL, normal registry editors can't read it.

Back to the key. You'll find it here, attempting to hide withn the EventLog registry tree

Computer\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\EventLog\System\RxDeliveryStamp\{57C7DD3D-2E9C-4F3B-A270-391E8AEDF0C4}

If you attempt to access it, you'll first be hit by access denied errors. You'll need to change the security permissions on the key to access it. But to do that you have to first change the owner. Restart regedit with admin permissions, reset the owner to you, then add yourself as a full owner of the key.

That will then let you see the hidden subkey Parameter. If you click that you'll get a "Parameter cannot be opened" error. That is due to the UNICODE 00 characters. The name is something more like "Parameter\0\0\0\02347298742". Normal API calls fail because it thinks the parameter is "Parameter" because it sees the first NULL and assumes a null terminated string. The Native API returns and expects the ACTUAL string length to properly set/get names, so it doesn't care what characters are in it.

Luckily there ARE registry editors that CAN read it. Such as this one (another nice feature is that it actually has a SEARCH function find all such hidden keys)

    https://registry-finder.com/

Run it as administrator and it'll be able to see AND delete the dastardly registry key forever.

You can also use the excellent sysinternals program RegDelNull

---

An important note is that to do the deletions you'll need to have deleted any existing cache and uninstalled PrimoCache, as it is responsible for holding both the key and the file locked. 

A side effect of this, is of course that PrimoCache will have forgotten everything about your computer and its trial timer will reset.

Note that if you attempt to reboot into recovery mode, delete the key and remove that file from the recovery console, PrimoCache will still regenerate it's trial limit, probably through the use of cache settings or other registry settings. You *must* do a full clean uninstall (and then check for any existing registry keys left over)

There is a discussion to be had here about who owns my computer. PrimoCache developers seem to think they have the right to install whatever they want onto MY PC, and in contrast, I believe I have total right to do whatever I want to my PC. In trying to protect their trial time, they have intentionally made it extremely difficult (impossible without 3rd party software or programming skills) for anyone to be fully in control of their PC.






Saturday, August 4, 2018

Centos 7 - SELinux and Crontab


Updated my Centos 7 and noticed a few days later, the root crontab not working.

Looking at the cron logs showed:

Unauthorized SELinux context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 file_context=system_u:object_r:unlabeled_t:s0 (/var/spool/cron/root)

Doing a ls -Z on that directory showed:

ls -Z /var/spool/cron/root

-rw-------. root root system_u:object_r:unlabeled_t:s0 /var/spool/cron/root

Well, there is the problem, unlabeled_t. I eventually fixed it by simply editing the crontab with crontab -e, and saving the changes, it was then fixed:

ls -Z /var/spool/cron/root

-rw-------. root root unconfined_u:object_r:user_cron_spool_t:s0 /var/spool/cron/root

Certainly and annoying bug, at least it had an easy fix.

Monday, December 4, 2017

Excessive Modified Memory

Logged into my workstation today and start noticing "Out of memory" errors. Whaatt? This computer has 8GB of memory and doesn't run that much!

Resource monitor showed excessive "modified" pages like this (not my screenshot, but shows how it looked):

Well, thats odd.. lets fire up google search.... 30minutes later and I've hit the solution (that many others have before more):

https://what.thedailywtf.com/topic/17472/finally-nailed-my-windows-memory-leak-a-k-a-the-official-we-hate-karl-club?page=1

Cause is due a bad realtek application, "runsw.exe".

The final kicker was the 800,000 HANDLES the application had open, you can see them in task manager if you add the handles column.

The service appears to be some kind of realtek monitoring/watchdog program that talks to another service.

Ok then, handle leak, lets find out why. First, let fire up API monitor, a wonderful program I've used before to solve issues.

Well well, lots of calls to Process32Next. Lets get it loaded up IDA and have a look. Browse the import table, do a reverse cross reference, convert to pseudocode, and tada, we get a function:


The function seems to be looking for a process using CreateToolhelp32Snapshot, then Process32First and Process32Next, then exiting, on first glance, no issue, until you consider the CreateToolhelp32Snapshot call, from the documentation:

If the function succeeds, it returns an open handle to the specified snapshot.
To destroy the snapshot, use the CloseHandle function.
Well, i'm not seeing any CloseHandle function, and the return is only being stored in esi (the HANDLE v0l // esi@1 line ).

We have located there memory leak. Looking at what is calling this function, it appears to be called once a second, so it's leaking at least one handle a second. Over time, these handles build up and use up Windows memory until Windows is either restarted or dies with out of memory errors.

A poorly designed executable from RealTek. I've emailed them about it but I don't expect it to be fixed, the memory leak has been reported about for years with no resolution.
 


Monday, September 25, 2017

Skype for Business connection issue

We recently had a Skype/Lync connection issue where the user would enter their details and the Skype client would stay at "Connecting" forever.

Our setup is a local Active Directory (with a .local domain), and a Office 365 subscription, the local directory DOES NOT sync (for various reasons) with Office 365, so the accounts/passwords could be different between them.

We have also been preparing to sync the directories and had setup a UPN Suffix for our .local domain using the Microsoft page here:
which we considered might have also been a contributing factor.

We tried a bunch of stuff to try to fix the Skype login issues:

  • Caches were cleared
  • DNS was flushed
  • DNS entries were checked
  • Temp files were deleted
  • Credentials were deleted 
  • Certificates were deleted
All of the standard troubleshooting techniques failed.

There were two interesting parts in the log files. The first was:

SIP/2.0 401 Unauthorized
after a SIP REGISTER a
No Certificate
error further down. No other information in the logs was helpful.


This seemed to be a very common issue with many possible fixes popping up over the web.
  • https://www.michev.info/Blog/Post/1235/lync-and-mandatory-profiles
  • http://ucken.blogspot.com.au/2011/10/lync-loses-connection-every-8min-28sec.html
  • https://social.technet.microsoft.com/Forums/lync/en-US/c3c7567a-ffd4-453b-a0d3-e79b06e92f23/client-cant-login
 But no single fix worked. The account was able to logged in on another domain connected computer which was also strange and pointed to some local problem.

We finally got a break by looking the the "SigninTelemetryLog.XML" file that Skype created, we noticed text like "GetBestManagedCredentialByType" and determined that Skype (for whatever reason) was trying to use the local domain NTLM authentication tokens to authenticate instead of the passwords entered by the user for use in Office 365. Since these two would be different then it would be unable to authenticate properly.


We then enabled the registry key DisableNTCredentials, listed here: Manage two-factor authentication in Skype for Business Server 2015 which let Skype login without issue.

All in all, this was a very time consuming and difficult issue to diagnose. We didn't feel that the authentication process was logged by Skype to sufficiently to precisely determine what issue was. I presume that using a local Lync server we would access to more debugging tools that might have made it easier.

Tuesday, March 1, 2016

iTunes Audio Redirection

Something that has annoyed me for years finally annoyed me too much.

iTunes does not allow you to select an audio device on Windows. It's one of the most annoying things possible when you want to play iTunes videos on your TV but want all other sounds to come to your main speakers.

It's something people have asked for years for Apple to implement it and it isn't even that hard to do.

Well no more.

I wrote a "shim" that allows you to select your output device for iTunes. It requires you select DirectSound in your iTunes preferences.

Pretty simple to use. Put the "dsound.dll" in your iTunes folder.
Then use the accompanying iTunesAudioSelector.exe file to select your audio device. When you change a setting it stores the desired audio device in the registry so that the shim then checks when iTunes tries to create the audio device.

When iTunes next starts it should be using the device you want rather than the default.

Note this only works with x64 iTunes since that is what I use.


Get the two files here:
https://drive.google.com/file/d/0BwN-SjkZGsz2V3J6czVFT1JTQlk/view?usp=sharing

Tuesday, February 2, 2016

Blocking attachments by extension in Thunderbird

So after the third such incident at my work where a user had opened a .exe within a .zip, I decided to write an addon for Thunderbird that blocks attachments that are either executable or are zip files that contain an executable.

Our antivirus product (Kaspersky) has a feature to remove/rename .exe files within attachments, but unfortunately it can't remove/rename files within archives (I submitted an enhancement ticket for it).

Since we use shared hosting for our email we don't have control over the email server so I can't implement a filter directly on the email server which would have been the preferred solution.

So, my ultimate idea was a Thunderbird addon. Since this is my first such addon, and I had no idea how to write one, I forked another project and dropped my code into it as an addition.

Here is the source: https://github.com/glenritchie/SecondOpinion/tree/plusext

And pre-compiled(and signed) XPI files: https://github.com/glenritchie/SecondOpinion/tree/gh-pages/dist