Alle Beiträge von adlerweb

Deinstallation von Kaspersky Endpoint / Total / Select Security

Wenn es eine Software gibt, welche potentiell mehr Schaden anrichten kann und schwerer zu entfernen ist als ein Virus, dann handelt es sich um ein Produkt aus der Schlangenölbranche. Ein besonderes Schätzchen ist hier Kaspersky, deren Firmenchef sich gerne als Gehilfe diverser Dienste positioniert und aktuell unter Beschuss steht. Aber genug Themenausflug – mein Wunsch ist schnell definiert: Deinstallieren. Vorzugsweise automatisch. Nicht wegen den aktuellen Problemen, sondern eher da die Systeme sauber sein sollen.

Kaspersky besteht dabei in der Business-Variante aus drei Teilen:

Das Kaspersky Security Center (KSC, ehemals Kaspersky Administration Kit oder auch KAK), welches zentral installiert ist und für Management und Deployment zuständig ist

Der Kaspersky Administration Agent, einem kleinen Tool, welches auf allen Rechnern installiert ist und primär die Verbindung zwischen dem Security Center und den Schutzprogrammen des Rechners herstellt. Weiterhin kann es zur Installation von beliebigen Programmen und Patches genutzt werden.

Zuletzt das eigentliche Schutzprogramm, auf Nutzerseite meist Kaspersky Endpoint Security, welches Dienste wie Signaturscan, Software-Firewall und Gerätekontrolle bereitstellt.

Leider ist das Management an vielen Stellen trotz der langen Reife noch ausbaufähig. Verschiedene Sprachversionen oder gar Rechner mit unterschiedlichen Service-Packs der Software lassen sich nur schwer gemeinsam verwalten oder gegeneinander austauschen, die Managementverbindung geht gerne mal verloren und für die Rechnergeschwindigkeit ist eine solche Software ebenfalls nur wenig zuträglich.

Zur Deinstallation hatte ich hierzu üblicherweise eine „Geheimwaffe“: Den KAVRemover. Dieses Tool des Herstellers ist in der Lage viele Installationen auf dem verwendeten Rechner mit einem Schlag zu entfernen. Aus Sicherheitsgründen hat sich der Hersteller jedoch dazu entschieden die Deinstallation mit einem CAPTCHA abzusichern. Da ich nun eine größere Charge Rechner vor mir hatte tut diese Unmöglichkeit der Automation natürlich weh. Also ran an die offiziellen Deinstallationsroutinen.

Erstes Problem: Passwörter. Insgesamt gibt es 2-3 Passwortebenen, mit denen eine lokale Installation im genannten Konstrukt geschützt ist:

Endpoint Security nutzt, wenn in der entsprechenden Policy angegeben, einen Passwortzugang zu allen administrativen Funktionen. Dieses wird auch zur Deinstallation benötigt. Bei neueren Versionen (ab 10.2ish) wird zusätzlich ein Benutzername verlangt, welcher jedoch augenscheinlich auf „KLAdmin“ hardcoded ist.

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2016/07/kavmenu-300×70.pngIst dieses Passwort nicht bekannt, jedoch Zugang und Verbindung zum Security Center noch vorhanden, kann man den Passwortschutz per Policy einfach ausschalten und so die Deinstallation etwas vereinfachen. Hierzu öffnet man die zum Produkt gehörende Policy und entfernt unter „Advanced Settings“ -> „Interface“ die Checkbox „Enable password protection“. Dies muss selbstverständlich für jede Sprache und Service-Pack-Version wiederholt werden.

Der Administration Agent nutzt eine separate Policy und hat ein dediziertes Passwort für die Deinstallation gesetzt. Ob sich dies ebenfalls irgendwo abschalten lässt habe ich nicht geprüft.

Das Passwort lässt sich glücklicherweise bei der Deinstallation als Parameter – natürlich je nach Version mit anderem Namen – angeben. Um die Funktion nutzen zu können muss man das Passwort jedoch vorher umrechnen: Es muss als ASCII-String einer HEX-Repräsentation des Passworts als 16Bit-ASCIIish (sieht aus wie ein Byte-Invertiertes UTF16) eingetragen werden. Besser keine Fragen stellen.

Also rechnen wir mal: Wäre unser Passwort „Geheim“ müssen wir dies erst mal in Hex konvertieren. Hierzu kann man – bei einfachen Zeichen – die gute, alte ASCII-Tabelle bemühen. G ist in HEX 0x47, e 0x65 – und so weiter. Am Ende erhalten wir „47 65 68 65 69 6D“. Da wir jedoch noch die 00en für 16 Bit brauchen wird daraus ein „470065006800650069006D00“. Mit diesem String können wir dann weiter an’s Werk. Zu beachten ist, dass einige Versionen der 10er-Serie (10.0.3361) zwischendrin plötzlich mal nur 8 Bit brauchten um beim nächsten Update wieder auf 16 zu springen. Kurzfassung: Wenns nicht geht einfach anders nochmal versuchen.

Für die Deinstallationen benötigt man weiterhin die MSI-IDs der Produkte. Einige seien hier mal gelistet, wer weitere hat: Die Kommentare stehen offen. Wer sich nicht sicher ist sollte in der Registry unter HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall und HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall nach Kaspersky-Einträgen suchen.

Danke an dawinci für das Listen der auswärtigen Agent-IDs

  • Kaspersky Endpoint Security 8.x Deutsch
    • {D72DD679-A3EC-4FCF-AFAF-12E2552450B6}
  • Kaspersky Endpoint Security 10.x (Deutsch, 64Bit)
    • {04CF7FBD-E56C-446D-8FC9-DD444BDBEE8E}
  • Kaspersky Endpoint Security 10.x (English, 32Bit)
    • {7A4192A1-84C4-4E90-A31B-B4847CA8E23A}
  • Kaspersky Admin Agent 9.x/10.x (Deutsch)
    • {2F383CB3-6D7C-449D-9874-164E49E1E0F5}
  • Kaspersky Admin Agent 9.x/10.x (English)
    • {BCF4CF24-88AB-45E1-A6E6-40C8278A70C5}
  • Kaspersky Admin Agent 9.x/10.x (Arabisch)
    • {FA7BF140-F356-404A-BDA3-3EF0878D7C63}
  • Kaspersky Admin Agent 9.x/10.x (Bulgarisch)
    • {4DBF6741-FA51-4C14-AFD2-B7D9246995F6}
  • Kaspersky Admin Agent 9.x/10.x (Tschechisch)
    • {478A6A0B-D177-4402-B703-808C05C56B13}
  • Kaspersky Admin Agent 9.x/10.x (Französisch)
    • {2924BEDA-E0D7-4DAF-A224-50D2E0B12F5B}
  • Kaspersky Admin Agent 9.x/10.x (Ungarisch)
    • {8899A4D4-D678-49F8-AD96-0B784F58D355}
  • Kaspersky Admin Agent 9.x/10.x (Italiänisch)
    • {DC3A3164-36B3-4FB4-B7BF-16A41C35A728}
  • Kaspersky Admin Agent 9.x/10.x (Japanisch)
    • {790C176F-7780-4C84-8B9C-455F5C0E61C5}
  • Kaspersky Admin Agent 9.x/10.x (Koreanisch)
    • {70812A40-973B-4DA1-96B9-C2011280CD99}
  • Kaspersky Admin Agent 9.x/10.x (Polnisch)
    • {1A7B331A-ABBE-4230-995E-BCD99C5A18CF}
  • Kaspersky Admin Agent 9.x/10.x (Portugiesisch / Brasilien)
    • {0F05E4E5-5A89-482C-9A62-47CC58643788}
  • Kaspersky Admin Agent 9.x/10.x (Rumänisch)
    • {FF802D76-E241-41D3-AAB4-DC7FBD659446}
  • Kaspersky Admin Agent 9.x/10.x (Russisch)
    • {ED1C2D7E-5C7A-48D8-A697-57D1C080ABA7}
  • Kaspersky Admin Agent 9.x/10.x (Chinesisch, vereinfacht)
    • {FBD7C01E-49CB-4182-8714-9DB1EAE255CB}
  • Kaspersky Admin Agent 9.x/10.x (Chinesisch, Traditionell)
    • {F6AD731A-36B4-4739-B1D4-70D6EDA35147}
  • Kaspersky Admin Agent 9.x/10.x (Spanisch / Mexiko)
    • {29748B5F-D88A-4933-B614-1CCCD6EFB0B7}
  • Kaspersky Admin Agent 9.x/10.x (Türkisch)
    • {2475A66D-698B-4050-93FF-9B48EE82E2BA}

Die Deinstallationsbefehle für die Endpoint Security lauten:

  • Kein Passwort
    • MsiExec.exe /x {MSI-ID} /qb- REBOOT=ReallySuppress
  • Nur Passwort
    • MsiExec.exe /x {MSI-ID} /qb- REBOOT=ReallySuppress KLPASSWDHEX=470065006800650069006D00
    • bzw. MsiExec.exe /x {MSI-ID} /qb- REBOOT=ReallySuppress KLPASSWDHEX=47656865696D
    • Alternativ kann man bei KES statt KLPASSWDHEX die Variable KLPASSWD verwenden und das Kennwort in Klartext angeben
  • Nutzername + Passwort
    • MsiExec.exe /x {MSI-ID} /qb- REBOOT=ReallySuppress KLLOGIN=KLAdmin KLPASSWDHEX=470065006800650069006D00

Für den Kaspersky Administration Agent lauten die Befehle:

  • Ohne Passwort
    • MsiExec.exe /x {MSI-ID} /qb- REBOOT=ReallySuppress
  • Mit Passwort
    • MsiExec.exe /x {MSI-ID} /qb- REBOOT=ReallySuppress KLUNINSTPASSWD=470065006800650069006D00

Beim Admin-Agent schlägt die Installation teilweise trotz richtigem Passwort mit dem Exit-Code 1603 fehl. In dem Fall kann es helfen einfach mal bis 10 zu zählen und die Deinstallation nochmal zu starten.

Bei /qb- wird ein Fortschrittsbalken angezeigt, welcher leider auch „abbrechen“ ermöglicht. Alternative /qn komplett im Hintergrund.

In meinem Fall habe ich eine Loop, welche für jede bekannte MSI-ID alle Deinstallationsbefehle mehrmals durchprobiert. Bei ca. 90% der Rechner funktioniert holzhammer(); – immerhin etwas weniger Arbeit.

RasPi/OSMC: SSH-Login bricht ab

Mal wieder ein Fehler, der im ersten Moment nicht wirklich zu erklären ist: An einem meiner Mediacenter konnte ich mich nicht mehr per SSH anmelden. Alle anderen Netzwerkfunktionen sahen OK aus, der SSH-Client meines Rechners zeigt jedoch folgendes:

> ssh osmc@1.2.3.4 -v
OpenSSH_7.5p1, OpenSSL 1.1.0f  25 May 2017
debug1: Reading configuration data /home/adlerweb/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 20: Applying options for *
debug1: Connecting to 1.2.3.4 [1.2.3.4] port 22.
debug1: Connection established.
[…]
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.5
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.7p1 Raspbian-5+deb8u3
debug1: match: OpenSSH_6.7p1 Raspbian-5+deb8u3 pat OpenSSH* compat 0x04000000
debug1: Authenticating to 1.2.3.4:22 as 'osmc'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256@libssh.org
debug1: kex: host key algorithm: ecdsa-sha2-nistp256
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:xyz
debug1: Host '1.2.3.4' is known and matches the ECDSA host key.
debug1: Found key in /home/adlerweb/.ssh/known_hosts:853
debug1: rekey after 1234 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey after 1234 blocks
debug1: SSH2_MSG_SERVICE_ACCEPT received
Authentication failed.
> 

Da es vor dem „Authentication failed“ ein paar Sekunden Wartezeit gibt kam mir ein alter Bekannter in den Sinn: DNS. Meldet man sich per SSH an versucht dieser standardmäßig den zur IP gehörenden Hostname zu ermitteln. Erhält der SSH-Daemon keine Antwort kann es zu einem Timeout kommen und die Verbindung abbrechen. Auch in meinem Fall fand ich in der Konfiguration einen veralteten DNS-Server.

Die ultimative Lösung besteht natürlich darin die Netzwerkkonfiguration zu fixen und somit DNS wieder lauffähig zu bekommen. Um zukünftig den hier nötigen Gang zum Raspi zu sparen und SSH auch ohne DNS lauffähig zu bekommen kann man folgende Zeilen in /etc/ssh/sshd_config hinzufügen:

GSSAPIAuthentication no
UseDNS no

UseDNS schaltet den Reverse-DNS ab – im LAN wohl zu verkraften. GSSAPI kann ohne DNS ebenfalls Fehler verursachen und wird bei einfachen Setups ohnehin nicht aktiv sein, daher auch dies nochmal explizit abgeschaltet. Nach dem nächsten Neustart des sshd sollte der Login dann auch ohne DNS immer und so die Reparatur der Netzwerkkonfiguration auch übers Netz möglich sein.

BTRFS: Dateisystem mit mehreren Festplatten vergrößern

Das ist jetzt doof – Platte voll. Und das auf einem Multi-Device/RAID BTRFS-System. Die unterliegenden LUNs zu vergrößern ist kein wirkliches Problem, aber btrfs zeigte sich etwas widerspenstig: Die meisten Anleitungen empfehlen folgendes:
btrfs filesystem resize max /mnt/data

Leider scheint es bei multi-device keine reaktion zu geben. Der Trick: Dieser Befehl lässt nur die erste Festplatte wachsen. Hat man mehrere muss man den Befehl für jede LUN separat ausführen, die Plattennummer wird dabei als ID mitgegeben:
btrfs filesystem resize 2:max /mnt/data

Die IDs aller beteiligten Platten kann man mit

btrfs filesystem show /mnt/data
anzeigen. Wurden alle Platten vergrößert kann man natürlich auch eine bash-Schleife bemühen um den Befehl für alle abzusetzen.
for i in {1..8} ;do btrfs filesystem resize $i:max /mnt/data/ ;done

[Fotos] Kirmes in Saffig 2017

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2017/09/KIRMESSAFFIG2017-208×300.jpgWie jedes Jahr am ersten September-Wochenende startete auch heute wieder die Saffiger Kirmes, dieses Jahr unter Federführung des Fördervereins der Freiwilligen Feuerwehr. Um 16:00 stand das traditionelle Baumstellen mit Fassanstich auf dem Plan. Pünktlich zu den ersten Klängen des Spielmannszuges traf jedoch auch eine Unwetterzelle samt Starkregen ein. Während die Besucher im erstmalig angelegten Biergarten Schutz fanden ließen sich die Wehrleute nicht aufhalten und trotzdem dem Regen – auch, wenn für die Befestigung kurzerhand das Einsatzfahrzeug zum Leerpumpen des Schachtes eingesetzt werden musste. Die Fotos finden sich wie immer in der Gallerie.

Linux: Gerät wacht nach Suspend sofort wieder auf

Narf. Akku leer. Nur warum?
Tja, mein Laptop hatte sich entschieden nach meinem Klick auf „Suspend“ sofort wieder aus dem Standby-Modus aufzuwachen. Reproduzierbar. Erste Vermutung: Die GUI ist Schuld. Wie immer. Aber auch ein systemctl suspend zeigt nicht wirklich eine Besserung. Auch die Logs zeigen nichts verwertbares. Na dann graben wir etwas tiefer:

Erst mal zur Klarstellung: Standby funktioniert – der Laptop schaltet die Geräte aus, die Power-LED blinkt wie erwartet, doch nach knapp einer Sekunde wacht wer direkt wieder auf. Entsprechend des Fehlers dürfte also die Aufwachquelle am ehesten Verantwortlich sein. Eine Liste aller Quellen findet sich in /proc/acpi/wakeup:

# cat /proc/acpi/wakeup
LID	  S4	*enabled  platform:PNP0C0D:00
SLPB	  S3	*enabled   platform:PNP0C0E:00
IGBE	  S4	*enabled   pci:0000:00:19.0
EXP2	  S4	*disabled  pci:0000:00:1c.1
XHCI	  S3	*enabled   pci:0000:00:14.0
EHC1	  S3	*enabled   pci:0000:00:1d.0

Die Liste sieht natürlich je nach Verbauter Hardware anders aus, hier die Zuordnung meines Gerätes:

LID -> Laptop-Deckel
SLPB/SBTN -> Standby-Button
IGBE -> Integrated Gigabit Ethernet
EXP2 -> ??
XHCI -> USB3
EHC1 -> USB(1/2)

Wie wir sehen können diverse Geräte ein Aufwachen verursachen, lediglich EXP2 ist nicht aktiv. Um das Ganze einzugrenzen heißt es also nun: Aufwachquelle abschalten, Suspend testen und hoffen, dass es was bringt. Über ein gezieltes echo kann der Zustand zwischen enabled und disabled gewechselt werden:

echo LID > /proc/acpi/wakeup

In meinem Fall stellte sich USB als Fehlerteufel heraus. Offenbar störte sich das System an einem USB-Stick – egal ob gemountet oder nicht. Wie auch immer, USB brauche ich ohnehin nicht zum aufwachen, Deckel und/oder Power-Button sollten ausreichen. Den „bösen“ USB schalte ich beim Boot per Script nun ab.

[Gentoo] Apache 2.4.26 + WordPress: Invalid post type

Hmk? After the latest system updates on Gentoo I noticed WordPress was no longer able to open any kind of post list („invalid post type“), edit posts (you do not have access to this kind of post) or create posts (form shown, but right sidebar missing). Not quite uncommon, but this time it was no broken plugin – I could reproduce the same behavior with several other WordPress instances with different versions – even a fresh install. That’s a new one.

After some probing around I’m fairly certain Apache 2.4.26 is the culprit, after downgrading to 2.4.25 the problem disappeared. All other downgrades like PHP 7.0.15 instead of PHP 7.0.19 didn’t show any effect. I yet have to confirm which combination ultimately triggers the error (FPM? Event-MPM?), but if you have similar errors: Here is your starting point…

Windows: Wo ist Java?

Ich bin von Linux ja irgendwie verwöhnt: Alle Binärdateien sind üblicherweise unter /usr/bin und lassen sich direkt über den Namen des Programms aufrufen. Unter Windows gibt es mit $PATH zwar eine ähnliche Funktion, jedoch ist dort meist nur der Systempfad eingetragen. Da es für fast jedes Programm ein eigenes Verzeichnis gibt hat man so keine direkte Möglichkeit ein Programm zu starten ohne an den Systemvariabeln herumzueditieren.

In vielen Fällen nicht wirklich ein Problem – einmal gefunden kann man den Pfad in seinen Scripten hinterlegen und so die Software ansprechen. Leider ist das bei Programmen wie Java nicht so einfach: Diese legen ein Verzeichnis mit der Versionsnummer an, z.B. C:\Program Files\Java\jre_8.0.121\bin\java.exe. Ergebnis: Nach jedem Update versteckt sich die gesuchte EXE an einer anderen Stelle.

Hier ein Quick&Dirty CMD, welches die Java-Binary aufspüren sollte. Nicht Ideal, da z.B. nur das Systemlaufwerk unterstützt wird und diverses Errorhandling fehlt, aber immerhin zuverlässiger als hardcoded…

REM Find Java :/
pushd "%ProgramFiles%\java\jre*\bin\"
echo %JAVADIR%cd > %TEMP%\findjava.txt
set /p JAVADIR=<%TEMP%\findjava.txt
del %TEMP%\findjava.txt
popd
%JAVADIR%\java -jar meinesoftware.jar

 

Video: Karnevalsumzug Miesenheim

Analog zu den letzten Jahren war ich auch dieses mal mit meiner Kamera in Miesenheim unterwegs. Leider diesmal etwas kürzer, da die Vorbereitungszeit etwas knapp war und viele Gruppen Musikanlagen zur Beschallung verwendeten, deren Inhalt ich aus urheberrechtlichen Gründen hier vermeiden muss. Wer dennoch einen  Blick auf den Umzug werfen möchte wird wie immer auf YouTube fündig:

https://www.youtube.com/watch?v=8Vnnm1kjEOY

Thunderbird: Couldn’t load XPCOM

Diese Meldung weist erst mal darauf hin, dass die Installation beschädigt ist. Dies kommt häufig vor, wenn der Updater unterbrochen wird oder ein übereifriger Virenscanner genutzt wird. Eine Reparaturinstallation ist meist keine schlechte Idee – hierzu einfach die aktuelle Installation von der Webseite ohne vorherige Deinstallation ausführen. E-Mails und Einstellungen bleiben hierbei zu großen Teilen erhalten. Zeigt dies keine Wirkung kann auch ein Blick auf die Dateirechte nicht schaden – in meinem Fall war für den Ordner bzw. dessen Dateien das Execute-Recht verweigert.

Linux/Sane: Segfault mit Panasonic/Matsushita KVS-50xx-Scanner

Business as usual: Pünktlich zum Jahresanfang wird man von sämtlichen Vertragspartnern mit totem Baum zugeworfen. Glücklicherweise habe ich passende Scanner, die das Material in etwas besser verwaltbare Formen überführen können. Zuletzt verwendete ich dazu einen Panasonic/Matsushita KVS-5026, welchen ich aus dem Schrott retten konnte. Zwar habe ich noch einige schnellere Modelle, dieser hatte jedoch bisher die wenigsten Probleme mit Double-Feeding und ist durch die Bauform bei mir einfacher zu nutzen.

Leider war der Start dieses Jahr nicht ganz so erfolgreich – der Scanner wird korrekt erkannt, versuchte ich jedoch einen Scan zu starten gab es den allseits beliebten „Segmentation fault“. Boo.

Der Trick des letzten Problems half dieses mal leider nicht – auch die aktuelle GIT-Version zeigen den selben Fehler. Da es für das passende Backend kvs20xx keinen Maintainer gibt ist wohl auch keine Besserung zu erwarten.

OK, ich bin kein C-Programmierer, habe keine Ahnung von Debuggern unter X86 und produziere auch sonst eher nicht qualitätsorientieren Code – was kann schon schief gehen.

Ein paar Debug-Textausgaben später konnte ich den Fehler auf die Funktion sane_open, genauer die erste „echte“ Codezeile dort „for (i = 0; devlist[i]; i++)“ eingrenzen. Offenbar wurde früher durch sane automatisch ein Scan iniziiert und die devlist daher gefüllt. In der aktuellen Version scheint es beim Aufruf leer zu sein und mit NULL hantieren mag C wohl nicht. Als workaround konnte ich ein paar Zeilen des Fujitsu-Treibers ruberkopieren, welche die Inizialisierung ggf. nachholen. Auch diese musste etwas angepasst werden um mit dem direkten Aufruf umgehen zu können. Immerhin: Der Scanner läuft und ich kann weitermachen. Fein.

diff --git a/backend/kvs20xx.c b/backend/kvs20xx.c
index 955252a3..56095cb5 100644
--- a/backend/kvs20xx.c
+++ b/backend/kvs20xx.c
@@ -1,6 +1,8 @@
 /*
    Copyright (C) 2008, Panasonic Russia Ltd.
    Copyright (C) 2010, m. allan noah
+
+   Attn: Local workaround 2017-02-11 Florian Knodt, sane-kvs@adlerweb.info
 */
 /*
    Panasonic KV-S20xx USB-SCSI scanners.
@@ -141,6 +143,8 @@ sane_get_devices (const SANE_Device *** device_list,
       devlist = NULL;
     }
 
+  sanei_usb_init();
+
   for (curr_scan_dev = 0;
        curr_scan_dev < sizeof (known_devices) / sizeof (known_devices[0]);
        curr_scan_dev++)
@@ -156,7 +160,10 @@ sane_get_devices (const SANE_Device *** device_list,
 			       known_devices[curr_scan_dev].scanner.model,
 			       NULL, -1, -1, -1, -1, attach);
     }
-  *device_list = (const SANE_Device **) devlist;
+
+  if(device_list && devlist){
+      *device_list = (const SANE_Device **) devlist;
+  }
   return SANE_STATUS_GOOD;
 }
 
@@ -168,10 +175,22 @@ sane_open (SANE_String_Const devname, SANE_Handle * handle)
   struct scanner *s;
   SANE_Int h, bus;
   SANE_Status st;
+
+  if (devlist) {
+    DBG (DBG_INFO, "Using prepopulated device list\n");
+  }else{
+    DBG (DBG_INFO, "Device list empty - scanning...\n");
+    st = sane_get_devices(NULL,0);
+    if(st != SANE_STATUS_GOOD){
+      DBG (DBG_WARN, "Scan failed\n");
+      return st;
+    }
+  }
+
   for (i = 0; devlist[i]; i++)
     {
       if (!strcmp (devlist[i]->name, devname))
-	break;
+       break;
     }
   if (!devlist[i])
     return SANE_STATUS_INVAL;

 

Upstream: #315625