Co rozpakowuje pliki na systemie Linux Mint MATE? Małe śledztwo
W tym miniwpisie opiszę historię z życia – przypadek, kiedy skorzystałem z paru konsolowych programów załączonych do Linuksa.
Dzięki nim zajrzałem „pod maskę” przyjaznego interfejsu pewnego programu i znalazłem sposób na odtworzenie jego działania we własnym, minimalistycznym skrypcie.
Spis treści
Opis problemu
Miałem pewne spakowane, zabezpieczone hasłem archiwum w formacie ZIP. Dajmy na to: archiwum.zip
. Wewnątrz niego różne pliki, z którymi chciałem coś porobić.
System Linux Mint (wariant MATE), z którego korzystam, jest bardzo przyjazny codziennym użytkownikom. Mógłbym łatwo rozpakować plik najzwyklejszym klikaniem.
W tym celu wystarczyłoby odnaleźć archiwum w przeglądarce plików, kliknąć je prawym przyciskiem myszy i wybrać opcję Rozpakuj tutaj
.
W związku z tym, że to ZIP chroniony hasłem, pojawia się okno z prośbą o jego wpisanie. Jeśli podam poprawne, to zaczyna się rozpakowywanie archiwum. Obok jego ikony pojawią się wszystkie zawarte w nim pliki i foldery.
Parę razy rozpakowałem archiwa ręcznie, właśnie w taki sposób. Ale kiedy się okazało, że będę musiał to robić częściej – wraz z powtarzalnymi działaniami na wypakowanych plikach – to wewnętrzny leniuch rzekł stanowczo: „automatyzujmy”.
A do tego przydałyby mi się nazwy programów do wpisywania w konsolę. Zaczęło się szperanie.
Unzip i mylny trop
Wyszukałem w sieci odpowiedzi na pytanie w stylu: „jak rozpakować plik ZIP na systemie Linux”? Któraś z odpowiedzi zasugerowała programik unzip
.
Użyłem go przez konsolę na swoim zahasłowanym pliku. O dziwo zadziałało nawet bez pytania o hasło, rozpakowało zawartość… Tyle że były tam same foldery. Nie było natomiast żadnych plików, na których mi zależało.
Nawet plik ZIP zabezpieczony hasłem zawiera na widoku nazwy i hierarchię zawartych w sobie plików i folderów.
To dlatego unzip
mógł odtworzyć strukturę folderów – do tego wystarczą same ścieżki. Ale pliki już były zaszyfrowane, więc ich nie tknął.
Wniosek: lepiej nie umieszczać żadnych wrażliwych informacji w nazwach plików wrzucanych do archiwów
Pomijam już to, że samo hasło do pliku też nieraz łatwo złamać metodami siłowymi, zwłaszcza jeśli zawęzi się przestrzeń możliwości. Fajnie to pokazał ten wpis Informatyka Zakładowego.
Skoro ogólnie unzip działał, a jedynym problemem było hasło, to kolejna rzecz do wyszukania: „jak rozpakować przez unzipa plik chroniony hasłem”. Wpisałem takie coś i… okazało się, że raczej się nie da. Nie przy tym programie i tym szyfrowaniu.
Śledztwo
Tam, gdzie unzip poległ, domyślny program Minta dawał radę. Przyjmował hasło i rozpakowywał archiwum. Jak? Czy dałoby się w prosty sposób włączyć go w moją automatyzację?
Szukając odpowiedzi na te pytania, rozpocząłem krótkie śledztwo.
Ustalenie nazwy programu (xprop)
Zależało mi na nazwie programu, jakiemu odpowiadało okienko interfejsu pytające o hasło.
Mógłbym teoretycznie kliknąć pierwszą opcję z menu z pierwszego screena. Jest tam o otwarciu archiwum, więc mógłbym założyć, że pojawi się ten sam program, który rozpakowuje. Po jego uruchomieniu zajrzałbym w zakładkę O programie
i poznał nazwę.
Ale nie zawsze jest możliwość prostego przejścia od okna/opcji do programu. Sposobem bardziej uniwersalnym jest uruchomienie konsoli/terminala (np. kombinacją Ctrl+Alt+T
) i użycie polecenia:
xprop | grep WM_CLASS
Są tu dwa programiki: xprop
od sprawdzania informacji o wskazanym oknie, grep
od wyszukiwania tekstu (tu: WM_CLASS). Rura między nimi sprawia, że informacje ustalone przez pierwszy lecą do drugiego.
Kursor zmienił się w plusa. Kiedy kliknąłem okno pytające o hasło, wyświetliła się nazwa stojącego za nim programu:
Engrampa. Nazwa trochę kojarzy mi się z n-gramami, trochę z dziadkiem – i faktycznie program jest już nieco leciwy. Ale wciąż sprawny.
Krótka lektura dokumentacji
Wiedziałem z doświadczenia, że programy mają czasem dwa oblicza:
-
Graficzne
Uruchamiane przez kliknięcie jakiejś ikony wewnątrz systemu; czasem również przez wpisanie w konsolę samej nazwy programu.
-
Konsolowe
Dopisując po nazwie programiku dodatkowe opcje, da się z niego korzystać w sposób niestandardowy, na przykład robiąć coś całkowicie w tle, bez interfejsu graficznego.
Gdybym po prostu wpisał w konsolę engrampa archiwum.zip
, to otwarłoby interfejs graficzny od przeglądania – nawet nie znajome okno pytające o hasło.
Ja natomiast liczyłem na możliwość zrobienia czegoś takiego:
Czy moje oczekiwania miały szansę się spełnić? Nie wiedziałem tego, bo każdy program może działać po swojemu. Musiałem poznać możliwości Engrampy. Na przykład takim poleceniem.
Parę uwag
Nie każdy program da się wołać samą nazwą. Żeby się dało, musi się znajdować w którymś z folderów szybkiego dostępu. W innym razie trzeba podać jego pełną ścieżkę.
Poza tym nie każdy wyświetla dostępne opcje po dopisaniu --help
. To popularna konwencja, ale nie wszyscy twórcy się jej trzymają.
Przy Engrampie miałem to szczęście, że obie rzeczy się sprawdziły.
Wyświetliło mi garść informacji po angielsku. W tym jedną z dostępnych opcji, która brzmiała interesująco:
Opcja --extract-here
pasowała idealnie do tego, co chciałem zrobić. Ale używając jej na swoim archiwum, po prostu przywołałem znajome okno pytające o hasło.
Nie było to samo w sobie takie złe. Tyle że mnie, przypomnę, najbardziej pasowałoby rozwiązanie w całości konsolowe.
Spróbowałem jeszcze zajrzeć do dokładniejszej instrukcji, wpisując:
Programik man
(skrót od manual) to uniwersalny sposób na otwarcie instrukcji programów konsolowych.
W tym wypadku instrukcja była dość lakoniczna i zawierała właściwie te same informacje co skrócona pomoc konsolowa.
Na tym etapie mógłbym odpuścić i pogodzić się z tym, że moją automatyzację będzie przerywało jedno graficzne okno. Albo znaleźć inny program rozpakowujący.
Ale postanowiłem trochę drążyć. Sięgnąłem po program konsolowy strace
.
Program pod obserwacją (strace)
Strace to linuksowy odpowiednik agenta wysyłanego na przeszpiegi. Notującego z ukrycia wszystko, o co Engrampa prosi jądro systemu. Może to pozwoli rozpracować naszego odpakowywacza.
Żeby użyć strace’a, wystarczy dopisać po nim komendę, którą chciałoby się śledzić. Odpowiednie polecenie dla Engrampy ustaliłem parę akapitów wyżej. Dodałem jeszcze parę parametrów dla strace’a i uzyskałem takie polecenie:
strace -f -o zapis.txt engrampa --extract-here archiwum.zip
Po wykonaniu polecenia uruchomiło się to samo okienko pytające o hasło co poprzednio. Wpisałem je, poczekałem aż rozpakuje mi ZIP-a. Programik z powodzeniem zakończył działanie, a strace skończył notować.
W folderze, w którym użyłem konsoli, powstał plik liczący aż 4,5 MB. Szczegółowy zapis wszystkich interakcji Engrampy z systemem podczas tej krótkiej sesji.
Przeszukanie zapisków (grep)
Miałem pełną historię, mogłem teraz wyciągnąć z niej różne informacje.
Tak duży plik byłby jednak uciążliwy do przeglądania w domyślnym Notatniku Xedzie. Nawet przez programik less
, który ładuje pliki na raty, ręczne szukanie byłoby żmudne.
Może dałoby się wyjść od czegoś jak najbliżej momentu rozpakowania?
Wiedziałem, jakie podałem hasło do ZIP-a, więc spróbowałem je sobie wyszukać w obszernych zapiskach:
grep HASŁO zapis.txt
…I faktycznie, wyskoczyło kilka linijek, w których się pojawiło! Aż się zdziwiłem.
Kilka pierwszych, zawierających różne ścieżki, kończyło się tekstem Nie ma takiego pliku ani katalogu
. Sugeruje to, że strace bezskutecznie szukał. Aż dotarło do linijki, która chyba zakończyła się sukcesem:
Włączyłem zawijanie tekstu, żeby wszystko się zmieściło, za cenę lekkiego chaosu; ciemniejszym szarym wyróżniłem ścieżki, czerwonym hasło.
Początek linijki, execve
, wskazuje na wołanie przez śledzony proces Engrampy innego programu.
Pierwszą rzeczą w nawiasie jest ścieżka wołanego programu (gdzie /usr/lib/7zip
to ścieżka do folderu, zaś 7z
to konsolowa nazwa popularnego programu 7-Zip).
Potem miałem serię nawiasów kwadratowych. A to, co między nimi, było tak naprawdę pełną listą opcji (argumentów) przekazanych „podwykonawcy”, czyli 7-Zipowi.
Mogłem to sobie skopiować, oczyścić z cudzysłowów podwójnych oraz przecinków, zastąpić ścieżki zmiennymi… i tak oto zdobyłem polecenie rozpakowujące plik.
/usr/lib/7zip/7z x -bd -bb1 -y -pHASŁO -o -- .zip
Omówienie
Znaczenie większości opcji z komendy (zwanych zwyczajowo argumentami) mogłem łatwo poznać, wpisując 7z --help
. I tak oto, po kolei:
-
/usr/lib/7zip/7z
to po prostu pełna ścieżka do programu 7-Zip na moim Mincie. -
x
każe programowi działać w trybie rozpakowywania plików. -
-bd
ukrywa konsolowy wskaźnik postępów w rozpakowywaniu. -
-bb1
wskazuje, jak szczegółowe (w skali od 0 do 3, tu1
) mają być informacje wyświetlane przez program. -
-y
sprawia, że program nie pyta, czy na pewno chcę coś zrobić, tylko zawsze to robi. -
-p
to hasło; tutaj zapisane od razu po nazwie argumentu, więc ciut się z nim zlewa. -
-o
to ścieżka i nazwa folderu wyjściowego; tutaj taka sama jak nazwa archiwum (tyle że bez.zip
na końcu). - podwójna kreska (
--
) wskazuje, że to koniec ustawiania opcji. Po niej jest już tylko główny „wsad” do programu – ścieżka do archiwum.
Użyłem na próbę tego polecenia (zamiast HASŁO
dając oczywiście prawdziwe hasło do pliku, a zamiast PLIK
jego pełną ścieżkę, ale bez rozszerzenia .zip
).
Zadziałało, moje archiwum zostało rozpakowane w aktywnym folderze. Bez udziału interfejsu graficznego. Programem domyślnie zainstalowanym na systemie.
Kwestia prywatności
Choć możliwość wołania 7-Zipa przez konsolę jest bardzo wygodna i fajnie się integruje ze skryptami, warto zwrócić uwagę na możliwą ciemną stronę tego ułatwienia.
Jak widać w powyższym przypadku – wynik strace’a zawierał na widoku hasło, którego używałem do rozpakowania pliku.
Strace dla wielu osób nie będzie czymś, z czego korzysta się na co dzień… Ale zdarza się, że po wrzuceniu swojego problemu z komputerem na forum publiczne dostaje się prośbę właśnie o wynik działania strace’a (bo jego szczegółowość ułatwia rozwiązywanie problemów). Szkoda by było, gdyby zaplątało się tam coś, czego się nie chce ujawniać.
Widzę tu pewien potencjał na tryb prywatny strace’a albo chociaż nakładkę, która pozwoliłaby wyłapywać właśnie takie przypadki i nieco cenzurować zapiski.
Przy okazji mogłaby ukrywać nazwę użytkownika, również widoczną wewnątrz ścieżek do plików i mogącą ujawniać tożsamość; u mnie był to tylko domyślny mint
, u kogoś będzie arek-przykładnik
.
Na Cinnamonie, czyli innym wariancie Minta, nie byłem w stanie powtórzyć działań z tego wpisu.
Zamiast Engrampy jest tam inny program, o nazwie file-roller
(wedle pliku pomocy: to na jego kodzie opiera się Engrampa). Wygląda ciut inaczej, dając między innymi możliwość wyświetlania hasła podczas wpisywania.
…No i chyba więcej ukrywa, bo w zapiskach strace’a nie znalazłem ani wołania 7-Zipa, ani użytego hasła. Ale dokładnego mechanizmu działania jeszcze nie rozgryzłem, więc różnica niekoniecznie gwarantuje prywatnościową przewagę Cinnamona.
Podsumowanie
Na systemie Linux Mint MATE interfejs graficzny od pracy z plikami ZIP nazywa się Engrampa. Wykonawcą jego woli, wysyłanym do praktycznej roboty, jest natomiast 7-Zip.
Jak się okazuje, strace był strzałem w dziesiątkę, pozwalającym nie tylko odkryć tę zależność, ale nawet bezpośrednio zdobyć polecenie konsolowe, pomijające interfejs graficzny.
Mogłem je skopiować i wykorzystać wewnątrz własnego skryptu, żeby usprawnić pracę z zawartością archiwów.
Przy okazji wyszło na jaw, że w wynikach strace’a może się chować hasełko. Nie jest to może powód do bicia na alarm, ale warto to uwzględnić, udostępniając innym wyniki do celów debugowania.
Niedawno próbowałem też zbadać, co się dzieje za kulisami podczas zmiany języka na polski na systemie Mint Cinnamon.
W tamtym przypadku sprawa okazała się nieco bardziej złożona i nie znalazłem szybkiego rozwiązania, więc jeszcze do niej wrócę.
Tym niemniej: jest tam jeszcze więcej konsolowej analizy. Jak ktoś lubi, to zapraszam.