Do szyfrowania partycji w systemach Linuksowych można wykorzystać dm-crypt - jest to już od dłuższego czasu w jądrze, potrzebny jest jeszcze tylko pakiet cryptsetup. W konfiguracji jądra należy włączyć szyfry (np. AES, Blowfish) i dm-crypt dla "Device mapper".
Teraz pokażę jak utworzyć szyfrowaną partycję, ja wykorzystuję LVM, ale nic nie stoi na przeszkodzie wykorzystać dowolną inną partycję.
Tworzymy partycję:
# lvcreate -n encrypted -L 2G vg Logical volume "encrypted" created
Tworzymy mapowanie szyfrujące:
# cryptsetup -v --cipher aes-cbc-plain -y create decrypted /dev/vg/encrypted Enter passphrase: Verify passphrase:
Tworzymy system plików:
# mkfs.ext3 /dev/mapper/decrypted
mke2fs 1.40.6 (09-Feb-2008)
Warning: 256-byte inodes not usable on older systems
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
131072 inodes, 524288 blocks
26214 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 31 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
Teraz już możemy zamontować naszą zaszyfrowaną partycję:
# mount /dev/mapper/decrypted /mnt/crypt
Utworzone mapowanie będzie istniało aż do wyłączenia systemu lub ręcznego usunięcia (przez cryptsetup remove). W Gentoo automatyczne tworzenie mapowań realizuje dodatek dmcrypt do baselayout, polecam przeczytać plik /etc/conf.d/dmcrypt.
Ważne: błędnie podane hasło nie jest sygnalizowane przez cryptsetup - dopiero nieudana próba zamontowania odszyfrowanej partycji może świadczyć o błędnym haśle.
Dużą zaletą dm-crypt w porównaniu z szyfrowaniem pojedynczych plików jest ukrywanie nie tylko zawartości plików ale również informacji o nich: szyfrowany jest cały system plików - uniemożliwia to nie tylko odczytanie danych z plików, ale również zorientowanie się co właściwie jest na takiej partycji. Drugą ważną zaletą jest przeźroczystość rozwiązania - odszyfrowaną partycję montujemy jak każdą inną, więc można ją wykorzystać do dowolnego celu - trzymanie tajnej poczty, szyfrowanie plików baz danych w /var/lib/postgresql, ogólnie: można z taką partycją dokładnie to samo co z normalną (niezaszyfrowaną) partycją (w odróżnieniu od encfs). Wadą jest wymaganie praw administratora do utworzenia mapowania i zamontowania partycji w odróżnieniu od wspomnianego już encfs, który działa jako moduł FUSE.
dm-crypt umożliwia również wczytywanie klucza z pliku zamiast hasła z klawiatury, daje to ciekawe możliwości:
- szyfrowanie partycji wymiany (swap) losowym kluczem z /dev/urandom - innym przy każdym starcie
- szyfrowanie partycji kluczem zapisanym na zewnętrznym nośniku: pendrive, karta SD, telefon z włączonym Bluetooth, etc...
Więcej o dm-crypt można poczytać na stronie domowej dm-crypt.
Druga część testu kompresorów, tym razem uwzględniony został dodatkowo zip i wszystkie możliwe stopnie kompresji dla gzip, bzip2 i lzma. Testy obejmowały również czas kompresji.
Zmienił się plik testowy: tym razem to archiwum zawierające zdjęcia JPEG, dokumenty (OpenOffice.org, PDF) oraz drzewko portage. Plik wejściowy ma rozmiar 281 MB (294420480 bajtów).
Wyniki testów:

lzma wypadł najlepiej pod względem wynikowego rozmiaru pliku, najgorzej pod względem czasu kompresji. Ale jak zaznaczyłem w poprzednim odcinku: dla mnie w tym przypadku nie liczy się czas kompresji. Ciekawie wypada porównanie bzip2-9 i lzma-2: lzma-2 jest lepszy zarówno pod względem czasu jak i rozmiaru pliku.
Zrobiłem dzisiaj mały test różnych metod kompresji plików. W konkursie udział brały trzy programy:
- gzip
- bzip2
- lzma
Plikiem który był archiwizowany jest md.tar - archiwum zawierające moją skrzynkę pocztową. Plik ma rozmiar 547 MB (573378560 bajtów). Ważny warunek: nie liczy się czas kompresji, najważniejszy jest jak najmniejszy rozmiar pliku wynikowego.
Wyniki wyglądają następująco (posortowane według finalnego rozmiaru pliku, im mniej tym lepiej):
| Metoda kompresji | Rozmiar pliku (MB) | Rozmiar pliku (bajty) |
| lzma -9 | 207 | 216402095 |
| lzma -7 | 223 | 233372691 |
| bzip2 -9 | 270 | 282651378 |
| bzip2 -7 | 271 | 284121394 |
| gzip -9 | 278 | 291419283 |
| gzip -7 | 279 | 291837325 |
| bzip2 -1 | 280 | 293459891 |
| lzma -1 | 282 | 295213626 |
| gzip -1 | 295 | 308516514 |
Lub w formie wykresu:
lzma wypada zaskakująco dobrze nawet przy -7 (domyślne ustawienie kompresji). Krótko podsumowując: jeśli nie liczy się czas kompresji to lzma jest najlepszym wyjściem.
Pytanie: jakie przyśpieszenie daje włączenie RC_PARALLEL_STARTUP?
RC_PARALLEL_STARTUP="no"
RC_PARALLEL_STARTUP="yes"
5 sekund różnicy :)
Pracuję nad pracą magisterską i miałem dwa problemy:
- "Bookmarks" - czyli spis treści dokumentu w Acrobat Reader
- PDF Security - czyli jak zabezpieczyć dokument PDF
Rozwiązanie pierwszego problemu jest proste:
\RequirePackage[dvipdfm]{hyperref}
\hypersetup{
bookmarks=true,
bookmarksnumbered=true,
citebordercolor={0.8 0.8 1},
linkbordercolor={0.8 0.8 1},
pdfauthor={Krzysztof Pawlik},
pdfstartview=FitH,
pdfsubject={...}
pdftitle={...},
urlbordercolor={0.8 0.8 1},
}
Więcej opcji jest opisane w dokumentacji hyperref.
Drugi problem wymagał wykorzystania innego programu: PDFBox. A oto jak go wykorzystać:
pdfencrypt -O hasło -canAssemble false -canExtractContent false -canExtractForAccessibility false -canFillInForm false -canModify false -canModifyAnnotations false -canPrint false -canPrintDegraded false -keyLength 40 plik.pdf
I teraz:

SCO announced today that it has filed for reorganization under Chapter 11 of the US Bankruptcy Code. Business operations, according to SCO, will continue as normal during the reorganization. (źródło)
Funkcja _mount odpowiedzalna za uzupełnianie arugmentów dla mount jest IMHO irytująca.
Odrobinę lepsza wersja:
# Author: Krzysiek Pawlik <nelchael@gentoo.org>
#
# Completion for sys-unneeded-distfiles
_mount() {
local cur=${COMP_WORDS[COMP_CWORD]}
local props=
for i in $(grep -v '^$' /etc/fstab | grep -v '^#' | awk '{print $1}'); do
[[ -e "${i}" ]] && props="${props} ${i}"
done
props="${props} $(grep -v '^$' /etc/fstab | grep -v '^#' | grep -v '^none' | awk '{print $2}')"
COMPREPLY=( $(compgen -W "${props}" -- $cur) )
}
complete -F _mount mount
mail() w PHP jest ciekawą funkcją: najczęściej nadużywaną, najmniej zabezpieczoną (żadnego logowania, ograniczeń - NIC). W sieci pojawiła się łatka, która ma to poprawić (tylko logowanie ;)), niestety ma parę wad. Poprawiona wersja dla PHP 5.2.2 znajduje się w bug 182187. Liczę, że w 5.2.4 znajdzie się już to w waniliowym PHP.
Co daje ta łatka? Możliwość logowania użycia funkcji mail(): logowana jest data, nazwa pliku PHP i odbiorca - akurat tyle ile potrzeba, żeby stwierdzić kogo powiesić ]:->
Jak korzystać z dobrodziejstwa Web services w Gentoo? Oto mały poradnik dotyczący JAXB.
Zaczynamy od zainstalowania JAXB:
# emerge -av jaxb-tools
Teraz potrzebujemy katalog projektu:
$ mkdir -p projekt/{bin,src,lib}
Nasz przykładowy plik XML (sample.xml):
<?xml version="1.0" encoding="UTF-8"?>
<dane>
<osoba imie="Jan" nazwisko="Kowalski">
<id pesel="00000000000"/>
</osoba>
<osoba imie="Janina" nazwisko="Kowalska">
<id pesel="00000000001" dowod="AAA00000"/>
</osoba>
</dane>
Tworzymy dla niego plik XML Schema (sample.xsd):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="dane">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="1">
<xs:element name="osoba" type="typeOsoba"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="typeOsoba">
<xs:all minOccurs="1" maxOccurs="1">
<xs:element name="id" type="typeId"/>
</xs:all>
<xs:attribute name="imie" type="xs:string" use="required"/>
<xs:attribute name="nazwisko" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="typeId">
<xs:attribute name="pesel" type="xs:string" use="required"/>
<xs:attribute name="dowod" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>
Sprawdzamy jeszcze poprawność XML Schema i przykładowego pliku XML:
$ xmllint --valid --noout sample.xsd $ xmllint --noout --schema sample.xsd sample.xml
Teraz już jesteśmy gotowi do wykorzystania XJC - kompilatora XML Schema, da on nam w rezultacie gotowe klasy Javy:
$ xjc-2 -d src/ -p net.nelchael.jaxb.generated sample.xsd
Wygenerowane pliki:
- net.nelchael.jaxb.generated.Dane
- net.nelchael.jaxb.generated.ObjectFactory
- net.nelchael.jaxb.generated.TypeId
- net.nelchael.jaxb.generated.TypeOsoba
Potrzebujemy jeszcze paru bibliotek:
$ ln -s /usr/share/codemodel-2/lib/codemodel.jar lib/ $ ln -s /usr/share/istack-commons-runtime/lib/istack-commons-runtime.jar lib/ $ ln -s /usr/share/jaxb-2/lib/jaxb-api.jar lib/ $ ln -s /usr/share/jaxb-2/lib/jaxb-impl.jar lib/ $ ln -s /usr/share/jaxb-tools-2/lib/jaxb-tools.jar lib/ $ ln -s /usr/share/jsr173/lib/jsr173.jar lib/ $ ln -s /usr/share/relaxng-datatype/lib/relaxngDatatype.jar lib/ $ ln -s /usr/share/rngom/lib/rngom.jar lib/ $ ln -s /usr/share/sun-jaf/lib/activation.jar lib/ $ ln -s /usr/share/xerces-2/lib/xercesImpl.jar lib/ $ ln -s /usr/share/xsom/lib/xsom.jar lib/
Teraz już jesteśmy gotowi do napisania klasy korzystającej z danych (src/net/nelchael/jaxb/Projekt.java):
package net.nelchael.jaxb;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import net.nelchael.jaxb.generated.Dane;
import net.nelchael.jaxb.generated.ObjectFactory;
import net.nelchael.jaxb.generated.TypeId;
import net.nelchael.jaxb.generated.TypeOsoba;
public class Projekt {
public static void main(String[] args) {
try {
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Dane dane = (Dane)unmarshaller.unmarshal(new File("sample.xml"));
for (TypeOsoba osoba : dane.getOsoba()) {
System.out.println("Osoba: " + osoba.getNazwisko() + ", " + osoba.getImie());
TypeId id = osoba.getId();
System.out.print(" Pesel: " + id.getPesel());
if (id.getDowod() != null)
System.out.print(", dowód osobisty: " + id.getDowod());
System.out.println();
}
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Na tym etapie przyda się już plik build.xml dla Ant:
<?xml version="1.0"?>
<project name="jaxb" default="compile">
<path id="globalClassPath">
<fileset dir="lib/" includes="*.jar"/>
<pathelement path="bin/"/>
</path>
<taskdef name="xjc" classname="com.sun.tools.xjc.XJC2Task" classpathref="globalClassPath"/>
<target name="xjc">
<xjc schema="sample.xsd" package="net.nelchael.jaxb.generated" destdir="src/"/>
</target>
<target name="compile">
<javac target="1.5" source="1.5" srcdir="src" destdir="bin/" encoding="UTF-8" classpathref="globalClassPath"/>
</target>
<target name="clean">
<delete verbose="true" dir="bin/net"/>
</target>
<target name="run">
<java classpathref="globalClassPath" classname="net.nelchael.jaxb.Projekt"/>
</target>
</project>
Wszystko gotowe, więc uruchamiamy XJC, ...
$ ant xjc
... kompilujemy projekt, ...
$ ant compile
... w końcu uruchamiamy:
$ ant run
Spodziewany wynik:
$ ant run
Buildfile: build.xml
run:
[java] Osoba: Kowalski, Jan
[java] Pesel: 00000000000
[java] Osoba: Kowalska, Janina
[java] Pesel: 00000000001, dowód osobisty: AAA00000
BUILD SUCCESSFUL
Total time: 2 seconds
$
Jak widać korzystanie z JAXB w Gentoo jest dość proste - wszystkie potrzebne biblioteki są już w portage, wystarczy zainstalować ;) Bardzo dobry tutorial dotyczący Web services jest na stronie Sun'a.
Niedługo postaram się umieścić podobny tutorial, ale dotyczący JiBX.


