Fahrradtour am Main

Ich war mal wieder in Frankfurt und habe mir diesmal die Zeit mit einer schönen Fahrradtour vertrieben:

 








How to backdoor store-and-forward public key crypto?

So, the german and french government want to break cryptography. Now they "only" want to be able to decrypt messaging apps. If they get their law - and since there's not much sanity left in the corrupt EU this will likely happen - what will be next?

I think store and forward crypto systems are the first to come into mind, that is: PGP. Happily I am the maintainer of some nice but working play store and forward crypto software: PCP. Of course it is not PGP but uses comparable features. So, after reading the news the other day I thought to myself:

How would I implement such a backdoor in PCP, if I had to?

As it turned out the answer is hillariously simple! PCP, as GNUPG, supports encrypting data for multiple recipients. Therefore the task is easy: create a "government key pair", hardcode its public key into the encryption code and encrypt everything for this recipient as well.

Here's the backdoor patch.

The patch includes the "government's" secret key. Here's how to use it:

  1. Compile the patched pcp source as usual, install the binary as pcp1-backdoored or something like that.
  2. Create a test user on your system, say "spook".
  3. As user "spook" import said secret key, the import passphrase is "gov".
  4. As another user on the same system export your public key.
  5. Import that key as user "spook".
  6. Now as the regular user, encrypt some file asymmetrically for someone else (e.g. import one of the public key files in the tests/ directory of the source code) using the backdoored binary.
  7. As user "spook" decrypt the encrypted file as if you'd be the intended recipient.
  8. Et voilá.

Demo:

[24.Aug 17:09:05] --- [~] ---
tom@vm: % src/pcp1 -V spiedsender.vault -l
Key ID               Type             Creation Time        Owner
0x5C77C305F0BF8333   primary secret   2016-08-24T15:13:02  Freddy Victim <victim@gmail.foo>
0x616BDDA58845987B   valid public     2015-04-17T17:08:19  Bobby <bobby@local>

[24.Aug 17:15:29] --- [~] ---
tom@vm: % src/pcp1 -V backdoor.vault -l
Key ID               Type             Creation Time        Owner
0xF93E7016447D28CC   primary secret   2016-08-24T14:54:28  The Government <spooks@the.gov>
0x5C77C305F0BF8333   valid public     2016-08-24T15:13:02  Freddy Victim <victim@gmail.foo>

[24.Aug 17:15:43] --- [~] ---
tom@vm: % echo "for bobbys eyes only" | src/pcp1 -V spiedsender.vault -i 0x616BDDA58845987B -e -O encrypted-for-bobby.asc
Enter passphrase to decrypt your secret key: 
Encrypted 242 bytes for:
  0x616BDDA58845987B - Bobby <bobby@local>

[24.Aug 17:16:14] --- [~] ---
tom@vm: % src/pcp1 -V backdoor.vault -I encrypted-for-bobby.asc -d
Enter passphrase to decrypt your secret key: 
for bobbys eyes only
Decrypted 21 bytes successfully

There you go. Freddy Victim encrypted some message for Bobby, but the "government" could read it anyway, it only had to import Bobby's public key (which is the difference to PGP, but it's public and much easier to retrieve).

Also note that the "government" just uses regular PCP features, it doesn't even need to use a patched binary, the vanilla one would do. That's because the backdoor is not really a cryptographic backdoor (which is, as many cryptographers already said, impossible). Instead it just adds another recipient. The result looks pretty normal to the uninitiated, just some encrypted file decryptable by two recipients instead only one.

So, as you can see, it couldn't be easier to implement this backdoor. I could even commit this code to Github and I'm pretty sure, no one would take notice (and of course in that case I'd obfuscate it a little to disguise a casual reader). Also, the government could distribute the patched binary. That'd be pretty easy as well, since almost all Open Source systems use binary packaging.

Finally, one question remains though:

How could I determine of an encrypted file has a "hidden" recipient?

I'm not sure. In the case of PCP, I added a debug print statement to the decryption code (git commit) which tells the number of recipients during decryption if -v have been supplied on the command line. Maybe GPG already includes such a function. But of course this could be easily patched away by a backdoored version. So to check if an encrypted file contains more recipients than expected you'd need to check out the source code, compile it manually and then do the checks.

Yes, evil and scary stuff. But as the README of PCP says loud and clearly: Do not use PCP for anything productive or important. However, for real live public key crypto systems the scheme to add a government recipient to all encrypted data could be a realistic possiblity.

 








Response to Kyle Keen's "Maintainers Matter"

This is a response to the article "Maintainers Matter" by Kyle Keen, which I'm posting here, since his comment system doesn't work for me.

First of all: I agree with you that maintainers are indeed required and do matter - for users of linux distributions. But I think your world view is a little bit too focused on linux distributions:

Supposedly one of Linux's failings is that there is too much pointless choice, too many K and G versions of things and it divides developer efforts. Why have so many window managers and text editors?

This is no failing, this is good. Who is to decide which WM I'm going to use? A maintainer? You? Why? What could I do if my distribution only provides Gnome but I'm a non-mouse-user and NEED xmonad?

Linux is about choice and it's the choice of the users, not the maintainers. That's why we do have so many different distributions: because at some point maintainers went mad, excluded users with their decisions, so the users had to make a fork of the distribution.

Somehow we've gotten this idea that everyone who writes software for Linux does it for the warm fuzzies.

I am writing software. Free software. NOT software for Linux. In fact, I don't care about Linux at all. My software is free, I provide the source, it runs on most unices, including Linux. And besides it is none of your business, what I'm doing it for. Be it for the lulz, for the "warm fuzzies" or for money - as long as the software comes with a free license which enables users to use it as they wish, it is free and everything is good.

Oh, and from my point of view there's only the developer (that would be me) and users. As you see, users includes maintainers. There's no difference. I do not handle bug reports differently whether they come from an "end user" or some "ubuntu maintainer". And why should I?

More fundamentally, the maintainer is the primary line of defence and interaction between users and developers. Maintainers shield developers from uninformed users, allowing the devs to write software with less support overhead. Non-bugs are caught and filtered out. Low-quality bugs reported to the distribution's tracker often becomes a good bug when the maintainer reports it upstream.

Maintainers may do whatever they want, I don't care. But they're not a "line of defence" or some shield between me and users. Maintainers are, if any, a proxy or a filter. I don't need a "line of defense" since I don't consider users to be my enemies. And even if I would, then maintainers would be enemies as well. So where's the point?

And what is a "non-bug"? Who decides? What if I want to know about it? What if it is not a bug, but just feedback. Why in the world is this hidden from me?

Without distros the ISV would have to carry the full weight of support.

Oh, look at the young one :) Do you know, there was a time when no "distributions" were around? During that time, developing and supporting free software was no burden nevertheless.

This is why Linux doesn't have spyware, doesn't come with browser toolbars, doesn't bundle limited trials, doesn't nag you to purchase and doesn't pummel you with advertising.

Wrong. It doesn't have spyware because it's not widespread. Oh, my bad, that's wrong too. Of course there's LOTS of spyware for Linux. Every android device has it installed. Ubuntu contains spyware. Sanctioned by a "maintainer" of some kind.

For the sake of argument, let us presume that all ISVs are ethical and hold the interests of the community as their utmost ideal.

Again, that's not the point of free software. I produce free software so you can do with it whatever you want, including modifying or distributing it. I'm not interested in your ethical values, your religion, your gender, your education, your location or even your species.

And it's the same the other way around: none of those things about me is your business.

But there's another major misconception here: "the community" you say. Which one? The community of Arch Linux users? Linux Users? Unix Users? Free Software Users? Software Users? Users? In the reality (to reuse you phrasing) there's no such thing as "the community". There are a bunch of people who use Arch Linux, but this doesn't constitute automatically a community. Most of Arch Linux users are unknown to Arch Linux maintainers. They are NOT part of whatever kind of community you're dreaming of. And this is the case for all kinds of users.

As long as people just use something, whether they pay for it or not, they are just users of this thing. Take Zippo users for example. Even if there's some "Zippo Community" somewhere, I am not part of that community only because I use a Zippo lighter!

I am part of a community if I subscribe to some list, apply for a forum account, post comments or opinions, contribute code, documentation or the like. Everyone else is not part of this. Seeing it this way is communist thinking. Free people decide themselfes if they want to be part of some kind of "movement" - not some maintainer somewhere in the U.S.

Could ISVs possibly make everyone happy? They can't. It is impossible.

As maintainers can't do as well. That's why we have thousands Linux distros, a couple of BSD's, hundreds of editors, hundreds of window managers and possibly billions of different ways to combine and configure them. And that's the idea behind the whole endeavor, isn't it?

So, let them make universal packages. Who cares? I'll continue to manually compile emacs and xmonad myself whatever distro I'm running on.








Review Soupreme Die Suppenbar in Offenbach

Normalerweise schreibe ich ja keine Restaurantkritiken. Das hat den einfachen Grund, dass ich mich über die meisten Lokale, die ich besuche, sehr aufrege. Als ehemalig in der Gastronomie Tätiger fallen mir regelmäßig dutzende übler Fehler auf, kleine Patzer, diverse Vergesslichkeiten, oft genug, man muss es aussprechen wie es ist: Schlampereien, und - das deprimiert mich besonders kraftvoll und schmerzhaft - haufenweise Inkompetenz.

Heute ist daher ein besonderer Tag, weil ich nun damit anfange. Der Auslöser meines unverhofften Sinneswandels ist, wie so oft in der deutschen Servicewüste, Inkompetenz gepaart mit Herumgewurschtel erster Güte.

Auf der Suche nach Abwechslung bin ich im "Soupreme - Die Suppenbar" in Offenbach gelandet. Die gut sichtbare und einladende Speisekarte neben dem Eingang - eine mannshohe Konstruktion - hatte mich angelockt. Ein kurzer Kennerblick über das Angebot ließ mich jede Zaghaftigkeit verwerfen. Die Entscheidung war bereits gesichert, doch ein Blick ins Innere des Etablissements bekräftigte den Entschluss endgültig.



Ein doppelter Supreme-Cheese-Burger mit Cheddar sollte es werden. Mit einem schönen kühlen Pils dazu.

Ich habe Gnocchi mit Tomatensoße gegessen. Der ortskundige Leser wird an dieser Stelle einwenden wollen: "Moment mal. Das Supreme hat doch gar keine Gnocchi im Angebot!". In der Tat, denn ich aß die Gnocchi beim Italiener die Straße runter. Und das kam so:

Im Eingangsbereich des Lokals befindet sich eine Art Bar, abgeschlossen mit der Kasse, an der die Bedienung stand und irgendwas mit einem Gast besprach, als ich dort vorüber kam. Es fand Augenkontakt statt zwischen mir und der Bedienung, einer jungen Frau von der modern-dynamischen Sorte. Ich war auf dem Weg in den hinteren Bereich, wo man an einem Tisch Platz nehmen konnte.

"Kann ich mich hier hinsetzen?", fragte ich die Bedienung als sie gerade an mir vorbeilief, just in dem Moment in dem sich der zweite Blickkontakt ereignete. Freundlich, eilig, lächelnd, nickend kam die Antwort: "Aber klar!", oder so - an den Wortlaut erinnere ich mich nicht mehr. Willkommen, so fühlte ich mich jedenfalls, richtete mich häuslich ein, begann die bereit liegende Karte zu studieren und freute mich ganz ganz doll auf meinen Burger.

Sehr viel mehr Details gibt es nicht zu erzählen über meinen Aufenthalt im Supreme, der Suppenbar. Der vage Verdacht, den ich schon immer hege, unsichtbar zu werden, sobald ich in einem Lokal Platz nehme, bestätigte sich nämlich.

Während ich da so saß, nahm die Bedienung Bestellung für Bestellung entgegen und brachte Essen hinaus zu anderen Gästen. Anscheinend muss man sich in diesem "Restaurant" um sein Glück selbst bemühen, sich an der Kasse anstellen, im Hipsterstyle seine Wünsche äußern und umgehend bezahlen, nicht jedoch ohne vorher mehrmals geduzt worden zu sein. McDonaldsstyle oder so. Ganz klar geht das aus der Raumaufteilung aber nicht hervor, die Bedienung stand frei im Raum und nicht etwa hinter einem Tresen. Kein Schild wies auf diesen Umstand hin und gerade das ist es ja, was mich so verunsichert. Wenn in diesem Land kein Schild auf eine Vorschrift hiweist, gibt es die Vorschrift nicht. Dachte ich.

Ich saß also da, ich laß in meinem Buch, Kapitel um Kapitel, beobachtete das Geschehen und kratze mir mehrmals am Kopf. Es fiel niemandem auf, auch der Bedienung nicht. Wie auch - war ich doch unsichtbar. Ich packte zusammen. Keiner merkte was. Ich stand auf. Niemand wandte den Kopf. Ich zog die Jacke an. Kein dritter Blickkontakt. Ich ging. Unbehelligt.

Die Gnocchi waren übrigens sehr lecker und im nächsten Leben werde ich Restaurantbesitzer sein, diese Bedienung wird sich bewerben, ich werde sie einstellen und dann, eines Tages, ganz unverhofft, aus heiterem Himmel, mit ausgesuchter, blümeranter Höflichkeit, mit der Nuance eines subtilen Lächelns im Gesicht das sich nur anderen ehemals Unsichtbaren erschließt, werde ich ihr kündigen, sie feuern, sie rausschmeißen, auf die Straße setzen, achtkantig, fristlos, umgehend, ohne verdammten Lohnausgleich, ohne Zeugnis und ohne Tschüß. Und den Inhaber werde ich in der Spülküche knechten mit 14-Stunden-Tagen, schlechtem Lohn und ohne Lüftung.

Scheiße noch eins.








Note to self: portable pkg-* Aliases

Always bored to remember those:

  • ArchLinux

    alias pkg-search="pacman -Ss"
    alias pkg-add="sudo pacman -S"
    alias pkg-info="pacman -Qv"
    alias pkg-files="pacman -Ql"
    alias pkg-list="pacman -Sl"
    alias pkg-which="pacman -Qo"
    alias pkg-depends="pacman -Si"
    alias pkg-depends-reverse="pacman -Sii"
    alias pkg-delete="sudo pacman -Rs"
    alias pkg-upgrade="pacman -Syu"
    alias pkg-update="pacman -Sy"
    alias pkg-download="pacman -Sw"
    alias port-search="yaourt"
    alias port-add="yaourt -S"
    alias port-update="yaourt -Syua"
    
  • Ubuntu

    alias pkg-search="apt-cache search"
    alias pkg-add="sudo apt-get install"
    alias pkg-info="dpkg"
    alias pkg-depends="apt-cache --no-pre-depends --no-recommends \
                       --no-suggests --no-conflicts --no-breaks \
                       --no-replaces --no-enhances --installed depends"
    alias pkg-depends-reverse="apt-cache --no-pre-depends --no-recommends \
                               --no-suggests --no-conflicts --no-breaks \
                               --no-replaces --no-enhances --installed rdepends"
    alias pkg-delete="sudo apt-get --purge autoremove"
    alias pkg-key="sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys"
    
  • VOID Linux

    alias pkg-files="xbps-query -f"
    alias pkg-list="xbps-query -l"
    alias pkg-info="xbps-query"
    alias pkg-update="xbps-install -S"
    alias pkg-upgrade="xbps-install -Syu"
    alias pkg-add="xbps-install"
    alias pkg-search="xbps-query -Rs"
    alias pkg-which="xbps-query -Ro"
    alias pkg-delete="xbps-remove -R"
    alias pkg-depends="xbps-query -x"
    alias pkg-depends-reverse="xbps-query -X"
    

13.06.2016 22:01 CC0 opensource Server Kein Kommentar






Mein bisher bestes Brot: Mischbrot - Updated 27.05.2016 19:12

Heute habe ich wieder Brot gebacken und es ist super geworden. Das ursprüngliche Rezept war das Weizenbrot I aus dem Backbrot Nr.1. Allerdings habe ich das Rezept diesmal massiv geändert. Zum einen habe ich statt dem 12 Stunden Vorteig einfach mein Livieto Madre genommen. Dann habe ich alle möglichen Mehlsorten frei Schnauze gemischt: Roggenmehl, Weizen 1050, Weizen Vollkorn und Dinkel 1050. Das Wasser habe ich diesmal gar nicht abgemessen sondern solange welches reingemacht bis der Teig die Konsistenz hatte, die ich haben wollte.

Warum? Bei den letzten Broten habe ich  immer aufwändig die Wasserverhältnisse ausgerechnet, weil ich ja immer LM benutzen möchte. Üblicherweise hat mein LM aber eine andere Teigausbeute, wie der Brotteig haben soll. Die letzten beiden Brote waren aber eher unbefriedigend, trotz des Rechenaufwandes. Ich habe auch nirgendwo eine sichere Methode gefunden wie man das besser machen kann, ausser: kipp die Sachen nach Gusto zusammen und mach 'nen Teig. Ich fand das - insbesondere als Backanfänger - recht brachial und eher keine Garantie für Backerfolge.

Hier habe ich daher nun einen Kompromiss gewagt. Ich habe mich bei Mehlmenge, Salzgehalt usw grob ans Rezept gehalten. Bei der Wassermenge und Konsistenz aber eher an mein Gefühl. Und das ging ganz gut, muss ich sagen. 

A la Bertinet mit der Teigkarte in der Schüssel vermischt und dann geschlagen und nicht geknetet. Das Resultat nach 3 Stunden: 

Bild: Fast fertig im Ofen (auf dem Stein)
Fast fertig im Ofen (auf dem Stein) (May 27, 2016, 5:04 p.m.)
[Tags: backen ] [Album: Backdat ]
Bild: Fertig gebacken, Guckt Euch das an!
Fertig gebacken, Guckt Euch das an! (May 27, 2016, 5:04 p.m.)
[Tags: backen ] [Album: Backdat ]
Bild: Angeschnitten. Dieser Duft und diese herrliche weiche Krume, wow! Anhand der Krume sieht man übrigens auch schön den Unterschied zum Original. Diese unregelmässigen Lufteinschlüsse sind typisch für geschlagenen Teig. Ich liebe das.
Angeschnitten. Dieser Duft und diese herrliche weiche Krume, wow! Anhand der Krume sieht man übrigens auch schön den Unterschied zum Original. Diese unregelmässigen Lufteinschlüsse sind typisch für geschlagenen Teig. Ich liebe das. (May 27, 2016, 5:04 p.m.)
[Tags: backen ] [Album: Backdat ]


Update 27.05.2016 19:12:

Und hier noch das Rezept, der Vollständigkeit halber:

Hauptteig:
  • 200 g Lievito Madre (LM)
  • 100 g Weizenmehl 1050
  • 100 g Dinkelmehl 1050
  • 100 g Weizen Vollkorn
  • 50 g Roggenmehl 1150
  • 50 g Weizenmehl 550
  • Wasser nach Bertinet
  • 6 g Frischhefe
  • 10 g Salz
  • 5 g Balsamico-Essig
  • 5 g flüssiges Gerstenmalz
  • 5 g Honig

Alle Zutaten – ausser dem Salz – in eine große Schüssel geben, Hefe mit etwas Wasser aufgelöst. Mit der Teigkarte vermengen (Methode Bertinet). Nach und nach Wasser zugeben, bis der Teigklumpen die richtige Konsistenz hat (weich bis mittelfest, klebt noch, bleibt aber kompakt).

13:00

Dann rausholen und Schlagen (Methode Bertinet). Nach 1 Minute Salz hinzugeben. Etwa 10 Minuten schlagen, bis Teig glatt ist, nicht mehr klebt und keine Reste mehr auf der Arbeitsplatte beim Abheben hinterlässt.

13:05

In die Schüssel zurück (diese vorher ggf. Reinigen), luftdicht abdecken und 1,5 Stunden bei 20-22° zur Gare stellen. Je nach ca. 30 Minuten falten.

13:15

Länglichen Laib wirken, leicht bemehlen, mit Nudelholz längs mittig bis fast unten eindrücken, die beiden Hälften zusammenklappen und mit der Falte nach unten in bemehlten Gärkorb stellen. Mit bemehlten Leinen abdecken und ca. 1 Stunde bei 25° zur Stückgare stellen.

14:45

50 Minuten (wenn man 2 kleinere Laibe macht, nur 40 Minuten) bei 250° mit Schwaden fallend (nach 10 Minuten 210°) mit der Falte nach oben backen. In den letzten 5 Minuten Türe etwas öffnen und auf 250° stellen. Kruste muss dunkelbraun sein. Auf Gitter offen abkühlen lassen.

15:45

Abends zur Brotzeit verspeisen.

18:00


27.05.2016 17:00 CC0 backen Kochen Kein Kommentar






Emacs: read-only copy of current buffer

Very often I split the emacs frame into two windows with the same buffer in both. For example on the left side I have a class definition and on the right side I implement it (so that part of the buffer is below the definition). While this works like a charm, sometimes I stumble upon an obstacle: if I want to change the class definition for testing, I cannot see the old definition for comparision. It has changed after all.

So I wrote this function which creates a copy of the current buffer, names it appropriately, makes it read-only, splits the current window and places the read-only copy on the right. Now I can see the old implementation while changing the current one, I can copy parts of the old stuff back into the current (because UNDO might remove some of the new things I want to keep) and so on. I bound this to C-c C-p, which you might want to change.

Here's the code. Put into .emacs to try it out:

;; ** Make a read-only copy of the current buffer
;;
I just create a new read-only buffer and copy the contents of the
;; current one into it, which can be used as backup
(defvar copy-counter 0) (defun get-copy-buffer-name() "return unique copy buffer name" (let ( (name (concat "*COPY " (buffer-name (current-buffer)) " (RO)")) ) (if (not (get-buffer name)) (progn (setq copy-counter (1+ copy-counter)) (concat name "<" (number-to-string copy-counter) ">") ) (concat name) ))) (defun copy-buffer-read-only() "Create a read-only copy of the current buffer" (interactive) (let ( (old-buffer (current-buffer)) (new-buffer-name (get-copy-buffer-name)) ) (progn (delete-other-windows) (split-window-horizontally) (other-window 1) (if (not (eq (get-buffer new-buffer-name) nil)) (kill-buffer (get-buffer new-buffer-name)) ) (set-buffer (get-buffer-create new-buffer-name)) (insert-buffer-substring old-buffer) (read-only-mode) (switch-to-buffer new-buffer-name) (other-window 1) ))) (defalias 'cp 'copy-buffer-read-only) (global-set-key (kbd "C-c C-p") 'copy-buffer-read-only)

There's even a screenshot (the read-only copy can be seen on the right):








Emacs: copy things at point without marking

This emacs config snippet is the predecessor to viking-mode: it allows me to copy thing at point without marking it beforehand. I just press a prefix key followed by an abbreviation of the thing to copy:

  • C-c w   copy word
  • C-c l    copy line
  • C-c p   copy paragraph
  • C-c a   copy all (the whole buffer)

Like viking-mode the copied thing is being highlighted shortly for visual feedback.

Put this into your .emacs config to try it out:

;; ** Easily copy word, line, paragraph or buffer without marking
;;
with ideas from:
;; http://emacs.stackexchange.com/questions/1051/copy-region-from-emacs-without-newlines
;; https://www.emacswiki.org/emacs/CopyWithoutSelection (defun my-blink(begin end) "blink a region. used for copy and delete" (interactive) (let* ((rh (make-overlay begin end))) (progn (overlay-put rh 'face '(:background "DodgerBlue" :foreground "White")) (sit-for 0.2 t) (delete-overlay rh) ))) (defun get-point (symbol &optional arg) "get the point" (funcall symbol arg) (point) ) (defun copy-thing (begin-of-thing end-of-thing &optional arg) "Copy thing between beg & end into kill ring. Remove leading and
trailing whitespace while we're at it. Also, remove whitespace before
column, if any. Also, font-lock will be removed, if any. Also, the
copied region will be highlighted shortly (it 'blinks')."
(save-excursion (let* ((beg (get-point begin-of-thing 1)) (end (get-point end-of-thing arg))) (progn (copy-region-as-kill beg end) (with-temp-buffer (yank) (goto-char 1) (while (looking-at "[ \t\n\r]") (delete-char 1)) (delete-trailing-whitespace) (delete-whitespace-rectangle (point-min) (point-max)) ;; del column \s, hehe
(font-lock-unfontify-buffer) ;; reset font lock
(kill-region (point-min) (point-max)) ) )))) (defun copy-word (&optional arg) "Copy word at point into kill-ring" (interactive "P") (my-blink (get-point 'backward-word 1) (get-point 'forward-word 1)) (copy-thing 'backward-word 'forward-word arg) (message "word at point copied")) (defun copy-line (&optional arg) "Copy line at point into kill-ring, truncated" (interactive "P") (my-blink (get-point 'beginning-of-line 1) (get-point 'end-of-line 1)) (copy-thing 'beginning-of-line 'end-of-line arg) (message "line at point copied")) (defun copy-paragraph (&optional arg) "Copy paragraph at point into kill-ring, truncated" (interactive "P") (my-blink (get-point 'backward-paragraph 1) (get-point 'forward-paragraph 1)) (copy-thing 'backward-paragraph 'forward-paragraph arg) (message "paragraph at point copied")) (defun copy-buffer(&optional arg) "Copy the whole buffer into kill-ring, as-is" (interactive "P") (progn (my-blink (point-min) (point-max)) (copy-region-as-kill (point-min) (point-max)) (message "buffer copied"))) ;; "speaking" bindings CTRL-[c]opy [w]ord, etc...
(global-set-key (kbd "C-c w") 'copy-word)
(global-set-key (kbd "C-c l") 'copy-line) (global-set-key (kbd "C-c p") 'copy-paragraph) (global-set-key (kbd "C-c a") 'copy-buffer)







Emacs screen reader - novel mode

I'm using Xah's novel function for a couple of weeks and found myself enhancing it time and again. Today - yet another day on my way south using the train - I took the opportunity and made a separate mode of the stuff. The result is novel-mode and I'm quite satisfied with it so far.

Novel mode is a minor mode. It makes the current buffer quasi read-only, disabled all distractions (like widgets, mode-line etc), enlarges the font size, line spacing, adds a margin left and right and adds an one key key-map which makes it possible to make dynamic adjustments. There's a GIF demo on the github page. Here are some screenshots:

Bare bones emacs before novel mode is active:

Novel mode activated:

After pressing "h" or "?"

After pressing [right] a couple of times: margins increased

After pressing [+] a couple of times: font size increased

After pressing "i": video display inverted

While I wrote it mostly for myself, I published the mode on github anyway. So if you want to try it out: installation and configurations instructions can be found there.








Emacs viking mode

While I'm a long term emacs user (since 2000), I did not write much emacs lisp over the years. In fact I kept my config unchanged for more than a decade. Happy and lazy, you see.

But lately I stumbled upon a lot of emacs enthusiasts like Sacha Chua. And so, a couple of weeks ago, I started to re-organize my .emacs config. I turned it into an outshine file for better overview, added a version, made it portable (now I use the very same config on Windows, Linux and FreeBSD with various emacs versions). Also I added LOTs of convenient stuff to my emacs. Some are external modules I discovered, some developed myself.

One of the things I added was expand-region, which I love! But I also wanted to be able to delete stuff the same way: just press a key and delete something, press it again and delete more, press it again and delete even much more until finally the whole buffer gets deleted. So I started to implement it on my own. And I learned a lot about lisp in the process. 

However, the code got bigger and bigger and I decided to put it into an extra file, but don't get me wrong: viking-mode is pretty small compared to other modes. While I was at it, I made a minor mode of it. This is not the first time, I created a mode, cisco-mode is my fabrication as well, but this time I tried to make it really good, conforming to all specs and guidelines. Finally my submission to melpa have been accepted and so here it is: my first minor mode on melpa: http://melpa.org/#/viking-mode.

The code itself is hosted on Github. And here is a small demo/screencast I made so you can see how it works:

A word about the name: I choosed this name because viking-mode just deletes things, you do not have to mark them, there's no "Are you sure?" annoyances. It is even possible to disable putting deleted stuff into the kill-ring (which would make it possible to yank it back somewhere). So - it just kills. Like a Viking, hence the name.