| Publisher: | Orbit |
| Copyright: | February 2008 |
| ISBN: | 0-316-00536-3 |
| Format: | Hardcover |
| Pages: | 593 |
Allison Lortie has provoked a lot of comment with her blog post on
a new proposal for how GTK is versioned.
Here's some more context from the discussion at the GTK hackfest that
prompted that proposal: there's actually quite a close analogy in
how new Debian versions are developed.
The problem we're trying to address here is the two sides of a trade-off:
Like each month, here comes a report about the work of paid contributors to Debian LTS.
Individual reports
In May, 166 work hours have been dispatched among 9 paid contributors. Their reports are available:
No comment Liked this article? Click here. My blog is Flattr-enabled.
Query.
Query q("SELECT * WHERE id=5");
You can then use this query like so
get(hash, getcb, donecb, filter, "SELECT * WHERE id=5");
I verified the working state of the code with the dhtnode. I have also done
some tests using our python benchmark scripts.
Query is the key part for optimizing my initial work on data persistence
on the DHT. It will enhance the DHT on more than one aspects. I have to point
out it would not have been possible to do that before our major refactoring we
introduced in
0.6.0.
As nearly anyone who's worked with me will attest to, I've long since
touted nedbat's talk
Pragmatic Unicode, or, How do I stop the pain?
as one of the most foundational talks, and required watching for all programmers.
The reason is because netbat hits on something bigger - something more
fundamental than how to handle Unicode -- it's how to handle data which is
relative.
For those who want the TL;DR, the argument is as follows:
Facts of Life:
Windows-1252, UTF-8, Latin-1, or EBCDIC. What's
a poem to me is terminal garbage to you.
Over the years, hacks have evolved. We have
magic numbers,
and plain ole' hacks to just guess based on the content. Of course, like
all good computer programs, this has lead to its fair share of hilarious
bugs,
and there's nothing stopping files from (validly!) being multiple things at the
same time.
Like many things, it's all in the eye of the beholder.
Timezones
Just like Unicode, this is a word that can put your friendly neighborhood
programmer into a series of profanity laden tirades. Go find one in the wild,
and ask them about what they think about timezone handling bugs they've seen.
I'll wait. Go ahead.
Rants are funny things. They're fun to watch. Hilarious to give. Sometimes
just getting it all out can help. They can tell you a lot about the true
nature of problems.
It's funny to consider the isomorphic nature of Unicode rants and Timezone
rants.
I don't think this is an accident.
U n i c o d e timezone Sandwich
Ned's Unicode Sandwich applies -- As early as we can, in the lowest level
we can (reading from the database, filesystem, wherever!), all datetimes
must be timezone qualified with their correct timezone. Always. If you mean
UTC, say it's in UTC.
Treat any unqualified datetimes as "bytes". They're not to be trusted.
Never, never, never trust 'em. Don't
process any datetimes until you're sure they're in the right timezone.
This lets the delicious inside of your datetime sandwich handle timezones
with grace, and finally, as late as you can, turn it back into bytes
(if at all!). Treat locations as tzdb entries, and qualify datetime
objects into their absolute timezone (EST, EDT, PST, PDT)
It's not until you want to show the datetime to the user again should you
consider how to re-encode your datetime to bytes. You should think about
what flavor of bytes, what encoding -- what timezone -- should I be
encoding into?
TEST
Just like Unicode, testing that your code works with datetimes is important.
Every time I think about how to go about doing this, I think about that
one time that mjg59 couldn't book a flight
starting Tuesday from AKL, landing in HNL on Monday night, because
United couldn't book the last leg to SFO. Do you ever assume dates only go
forward as time goes on? Remember timezones.
Construct test data, make sure someone in New Zealand's
+13:45 can correctly talk with
their friends in
Baker Island's -12:00,
and that the events sort right.
Just because it's Noon on New Years Eve in England doesn't mean it's not
1 AM the next year in New Zealand. Places a few miles apart may go on Daylight
savings different days. Indian Standard Time is not even aligned on the hour
to GMT (+05:30)!
Test early, and test often. Memorize a few timezones, and challenge
your assumptions when writing code that has to do with time. Don't use
wall clocks to mean monotonic time. Remember there's a whole world out there,
and we only deal with part of it.
It's also worth remembering, as Andrew Pendleton
pointed out to me, that it's possible that a datetime isn't even unique for a
place, since you can never know if 2016-11-06 01:00:00 in America/New_York
(in the tzdb) is the first one, or second one. Storing EST or EDT along
with your datetime may help, though!
Pitfalls
Improper handling of timezones can lead to some interesting things, and failing
to be explicit (or at least, very rigid) in what you expect will lead to an
unholy class of bugs we've all come to hate. At best, you have confused
users doing math, at worst, someone misses a critical event, or our
security code fails.
I recently found what I regard to be a pretty bad
bug in apt (which David has prepared a
fix
for and is pending upload, yay! Thank you!), which boiled down to documentation
and code expecting datetimes in a timezone, but accepting any timezone, and
silently treating it as UTC.
The solution is to hard-fail, which is an interesting choice to me (as a vocal
fan of timezone aware code), but at the least it won't fail by
misunderstanding what the server is trying to communicate, and I do understand
and empathize with the situation the apt maintainers are in.
Final Thoughts
Overall, my main point is although most modern developers know how to deal
with Unicode pain, I think there is a more general lesson to learn -- namely,
you should always know what data you have, and always remember what it is.
Understand assumptions as early as you can, and always store them with the data.
Children can use their imagination better than us because they are (still) immediately in contact
with the Whole and they represent the most pristine prototype of the human being. From birth and for the first years of life, the child is the mirror of our species, who carries in himself the primary elements and the roots of evolution, without conditions or interference.
When then education begins, especially school, his imagination is restrained and limited, everything is being done to concentrate his interests only for what is real and to let him leave the world of fantasy. In the first drawing exercises to which the children are subjected at school, their imagination or the appearance of how they perceive some elements of nature are discarded; the drawing that best fit to a photographic vision of reality is rewarded, inhibiting their own imaginative potential from the very beginning, in favour of a more reassuring homologation <Read More [by Fabio Marzocca]>
Here is my monthly update covering a large part of what I have been doing in the free software world (previously):
| Publisher: | Andrew Groen |
| Copyright: | 2015 |
| Printing: | 2016 |
| ISBN: | 0-9909724-0-2 |
| Format: | Hardcover |
| Pages: | 171 |
Github recently introduced the option to squash commits on merge, and even before then several projects requested that contributors squash their commits after review but before merge. This is a terrible idea that makes it more difficult for people to contribute to projects.
Like each month, here comes a report about the work of paid contributors to Debian LTS.
Individual reports
In April, 116.75 work hours have been dispatched among 9 paid contributors. Their reports are available:
No comment Liked this article? Click here. My blog is Flattr-enabled.
--- a/dovecot/conf.d/15-lda.conf
+++ b/dovecot/conf.d/15-lda.conf
@@ -44,5 +44,5 @@
protocol lda
# Space separated list of plugins to load (default is global mail_plugins).
- #mail_plugins = $mail_plugins
+ mail_plugins = $mail_plugins sieve
Then I had to switch from procmail to dovecot for local delivery, that
was easy, in Postfix's perennial main.cf:
#mailbox_command = /usr/bin/procmail -a "$EXTENSION"
mailbox_command = /usr/lib/dovecot/dovecot-lda -a "$RECIPIENT"
Note that dovecot takes the full recipient as an argument, not just
the extension. That's normal. It's clever, it knows that kind of
stuff.
One last tweak I did was to enable automatic mailbox creation and
subscription, so that the automatic extension filtering (below) can
create mailboxes on the fly:
--- a/dovecot/conf.d/15-lda.conf
+++ b/dovecot/conf.d/15-lda.conf
@@ -37,10 +37,10 @@
#lda_original_recipient_header =
# Should saving a mail to a nonexistent mailbox automatically create it?
-#lda_mailbox_autocreate = no
+lda_mailbox_autocreate = yes
# Should automatically created mailboxes be also automatically subscribed?
-#lda_mailbox_autosubscribe = no
+lda_mailbox_autosubscribe = yes
protocol lda
# Space separated list of plugins to load (default is global mail_plugins).
~/.dovecot.sieve, since I'm running Dovecot. Your provider may
accept an arbitrary ruleset like this, or you may need to go through a
web interface, or who knows. I'm assuming you're running Dovecot and
have a shell from now on.
The first part of the file is simply to enable a bunch of extensions,
as needed:
# Sieve Filters
# http://wiki.dovecot.org/Pigeonhole/Sieve/Examples
# https://tools.ietf.org/html/rfc5228
require "fileinto";
require "envelope";
require "variables";
require "subaddress";
require "regex";
require "vacation";
require "vnd.dovecot.debug";
Some of those are not used yet, for example I haven't tested the
vacation module yet, but I have good hopes that I can use it as a
way to announce a special "urgent" mailbox while I'm traveling. The
rationale is to have a distinct mailbox for urgent messages that is
announced in the autoreply, that hopefully won't be parsable by bots.
########################################################################
# spam
# possible improvement, server-side:
# http://wiki.dovecot.org/Pigeonhole/Sieve/Examples#Filtering_using_the_spamtest_and_virustest_extensions
if header :contains "X-Spam-Flag" "YES"
fileinto "junk";
stop;
elsif header :contains "X-Spam-Level" "***"
fileinto "greyspam";
stop;
This puts stuff into the junk or greyspam folder, based on the
severity. I am very aggressive with spam: stuff often ends up in the
greyspam folder, which I need to check from time to time, but it beats
having too much spam in my inbox.
lists folder, with some
mailing lists getting their own folder:
########################################################################
# lists
# converted from procmail
if header :contains "subject" "FreshPorts"
fileinto "freshports";
elsif header :contains "List-Id" "alternc.org"
fileinto "alternc";
elsif header :contains "List-Id" "koumbit.org"
fileinto "koumbit";
elsif header :contains ["to", "cc"] ["lists.debian.org",
"anarcat@debian.org"]
fileinto "debian";
# Debian BTS
elsif exists "X-Debian-PR-Message"
fileinto "debian";
# default lists fallback
elsif exists "List-Id"
fileinto "lists";
The idea here is that I can safely subscribe to lists without
polluting my mailbox by default. Further processing is done in
Notmuch.
+extension tag on emails. If you send email to,
say, foo+extension@example.com then the emails end up in the foo
folder. This is done with the help of the following recipe:
########################################################################
# wildcard +extension
# http://wiki.dovecot.org/Pigeonhole/Sieve/Examples#Plus_Addressed_mail_filtering
if envelope :matches :detail "to" "*"
# Save name in $ name in all lowercase except for the first letter.
# Joe, joe, jOe thus all become 'Joe'.
set :lower "name" "$ 1 ";
fileinto "$ name ";
#debug_log "filed into mailbox $ name because of extension";
stop;
This is actually very effective: any time I register to a service, I
try as much as possible to add a +extension that describe the
service. Of course, spammers and marketers (it's the same really) are
free to drop the extension and I suspect a lot of them do, but it
helps with honest providers and this actually sorts a lot of stuff out
of my inbox into topically-defined folders.
It is also a security issue: someone could flood my filesystem with
tons of mail folders, which would cripple the IMAP server and eat all
the inodes, 4 times faster than just sending emails. But I guess I'll
cross that bridge when I get there: anyone can flood my address and I
have other mechanisms to deal with this.
The trick is to then assign tags to all folders so that they appear in
the Notmuch-emacs welcome view:
echo tagging folders
for folder in $(ls -ad $HOME/Maildir/$ PREFIX */ egrep -v "Maildir/$ PREFIX (feeds.* Sent.* INBOX/ INBOX/Sent)\$"); do
tag=$(echo $folder sed 's#/$##;s#^.*/##')
notmuch tag +$tag -inbox tag:inbox and not tag:$tag and folder:$ PREFIX $tag
done
This is part of my notmuch-tag script that includes a lot more
fine-tuned filtering, detailed below.
if anyof (exists "X-Cron-Env",
header :contains ["subject"] ["security run output",
"monthly run output",
"daily run output",
"weekly run output",
"Debian Package Updates",
"Debian package update",
"daily mail stats",
"Anacron job",
"nagios",
"changes report",
"run output",
"[Systraq]",
"Undelivered mail",
"Postfix SMTP server: errors from",
"backupninja",
"DenyHosts report",
"Debian security status",
"apt-listchanges"
],
header :contains "Auto-Submitted" "auto-generated",
envelope :contains "from" ["nagios@",
"logcheck@"])
fileinto "rapports";
# imported from procmail
elsif header :comparator "i;octet" :contains "Subject" "Cron"
if header :regex :comparator "i;octet" "From" ".*root@"
fileinto "rapports";
elsif header :comparator "i;octet" :contains "To" "root@"
if header :regex :comparator "i;octet" "Subject" "\\*\\*\\* SECURITY"
fileinto "rapports";
elsif header :contains "Precedence" "bulk"
fileinto "bulk";
sieve-filter .dovecot.sieve INBOX 2>&1 less
Well, this doesn't do anything. To really execute the filters, you
need the -e flags, and to write to the INBOX for real, you need
the -w flag as well, so the real run looks something more like this:
sieve-filter -e -W -v .dovecot.sieve INBOX > refilter.log 2>&1
The funky output redirects are necessary because this outputs a lot
of crap. Also note that, unfortunately, the fake run output differs
from the real run and is actually more verbose, which makes it really
less useful than it could be.
Archive.YYYY directory. For example, now all mails from 2015 are
archived in a Archive.2015 directory. I used to do this with Mutt
tagging and it was a little slow and error-prone. Now, i simply have
this Sieve script:
require ["variables","date","fileinto","mailbox", "relational"];
# Extract date info
if currentdate :matches "year" "*" set "year" "$ 1 ";
if date :value "lt" :originalzone "date" "year" "$ year "
if date :matches "received" "year" "*"
# Archive Dovecot mailing list items by year and month.
# Create folder when it does not exist.
fileinto :create "Archive.$ 1 ";
I went from 15613 to 1040 emails in my real inbox with this process
(including refiltering with the default filters as well).
~/.notmuch-config. The gist of it is:
[new]
tags=unread;inbox;
ignore=
#[maildir]
# synchronize_flags=true
# tentative patch that was refused upstream
# http://mid.gmane.org/1310874973-28437-1-git-send-email-anarcat@koumbit.org
#reckless_trash=true
[search]
exclude_tags=deleted;spam;
I omitted the fairly trivial [user] section for privacy reasons and
[database] for declutter.
Then I have a notmuch-tag script symlinked into
~/Maildir/.notmuch/hooks/post-new. It does way too much stuff to
describe in details here, but here are a few snippets:
if hostname grep angela > /dev/null; then
PREFIX=Anarcat/
else
PREFIX=.
fi
This sets a variable that makes the script work on my laptop
(angela), where mailboxes are in Maildir/Anarcat/foo or the
server, where mailboxes are in Maildir/.foo.
I also have special rules to tag my RSS feeds, which are generated by
feed2imap, which is documented shortly below:
echo tagging feeds
( cd $HOME/Maildir/ && for feed in $ PREFIX feeds.*; do
name=$(echo $feed sed "s#$ PREFIX feeds\\.##")
notmuch tag +feeds +$name -inbox folder:$feed and not tag:feeds
done )
Another example that would be useful is how to tag mailing lists, for
example, this removes the inbox tag and adds the notmuch tags to
emails from the notmuch mailing list.
notmuch tag +lists +notmuch -inbox tag:inbox and "to:notmuch@notmuchmail.org"
Finally, I have a bunch of special keybindings in
~/.emacs.d/notmuch-config.el:
;; autocompletion
(eval-after-load "notmuch-address"
'(progn
(notmuch-address-message-insinuate)))
; use fortune for signature, config is in custom
(add-hook 'message-setup-hook 'fortune-to-signature)
; don't remember what that is
(add-hook 'notmuch-show-hook 'visual-line-mode)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; keymappings
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-key notmuch-show-mode-map "S"
(lambda ()
"mark message as spam and advance"
(interactive)
(notmuch-show-tag '("+spam" "-unread"))
(notmuch-show-next-open-message-or-pop)))
(define-key notmuch-search-mode-map "S"
(lambda (&optional beg end)
"mark message as spam and advance"
(interactive (notmuch-search-interactive-region))
(notmuch-search-tag (list "+spam" "-unread") beg end)
(anarcat/notmuch-search-next-message)))
(define-key notmuch-show-mode-map "H"
(lambda ()
"mark message as spam and advance"
(interactive)
(notmuch-show-tag '("-spam"))
(notmuch-show-next-open-message-or-pop)))
(define-key notmuch-search-mode-map "H"
(lambda (&optional beg end)
"mark message as spam and advance"
(interactive (notmuch-search-interactive-region))
(notmuch-search-tag (list "-spam") beg end)
(anarcat/notmuch-search-next-message)))
(define-key notmuch-search-mode-map "l"
(lambda (&optional beg end)
"undelete and advance"
(interactive (notmuch-search-interactive-region))
(notmuch-search-tag (list "-unread") beg end)
(anarcat/notmuch-search-next-message)))
(define-key notmuch-search-mode-map "u"
(lambda (&optional beg end)
"undelete and advance"
(interactive (notmuch-search-interactive-region))
(notmuch-search-tag (list "-deleted") beg end)
(anarcat/notmuch-search-next-message)))
(define-key notmuch-search-mode-map "d"
(lambda (&optional beg end)
"delete and advance"
(interactive (notmuch-search-interactive-region))
(notmuch-search-tag (list "+deleted" "-unread") beg end)
(anarcat/notmuch-search-next-message)))
(define-key notmuch-show-mode-map "d"
(lambda ()
"delete current message and advance"
(interactive)
(notmuch-show-tag '("+deleted" "-unread"))
(notmuch-show-next-open-message-or-pop)))
;; https://notmuchmail.org/emacstips/#index17h2
(define-key notmuch-show-mode-map "b"
(lambda (&optional address)
"Bounce the current message."
(interactive "sBounce To: ")
(notmuch-show-view-raw-message)
(message-resend address)
(kill-buffer)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; my custom notmuch functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun anarcat/notmuch-search-next-thread ()
"Skip to next message from region or point
This is necessary because notmuch-search-next-thread just starts
from point, whereas it seems to me more logical to start from the
end of the region."
;; move line before the end of region if there is one
(unless (= beg end)
(goto-char (- end 1)))
(notmuch-search-next-thread))
;; Linking to notmuch messages from org-mode
;; https://notmuchmail.org/emacstips/#index23h2
(require 'org-notmuch nil t)
(message "anarcat's custom notmuch config loaded")
This is way too long: in my opinion, a bunch of that stuff should be
factored in upstream, but some features have been hard to get in. For
example, Notmuch is
really hesitant in marking emails as deleted. The community is
also very strict about having unit tests for everything, which makes
writing new patches a significant challenge for a newcomer, which will
often need to be familiar with both Elisp and C. So for now
I just have those configs that I carry around.
Emails marked as deleted or spam are processed with the following
script named notmuch-purge which I symlink to
~/Maildir/.notmuch/hooks/pre-new:
#!/bin/sh
if hostname grep angela > /dev/null; then
PREFIX=Anarcat/
else
PREFIX=.
fi
echo moving tagged spam to the junk folder
notmuch search --output=files tag:spam \
and not folder:$ PREFIX junk \
and not folder:$ PREFIX greyspam \
and not folder:Koumbit/INBOX \
and not path:Koumbit/** \
while read file; do
mv "$file" "$HOME/Maildir/$ PREFIX junk/cur"
done
echo unconditionnally deleting deleted mails
notmuch search --output=files tag:deleted xargs -r rm
Oh, and there's also customization for Notmuch:
;; -*- mode: emacs-lisp; auto-recompile: t; -*-
(custom-set-variables
;; from https://anarc.at/sigs.fortune
'(fortune-file "/home/anarcat/.mutt/sigs.fortune")
'(message-send-hook (quote (notmuch-message-mark-replied)))
'(notmuch-address-command "notmuch-address")
'(notmuch-always-prompt-for-sender t)
'(notmuch-crypto-process-mime t)
'(notmuch-fcc-dirs
(quote
((".*@koumbit.org" . "Koumbit/INBOX.Sent")
(".*" . "Anarcat/Sent"))))
'(notmuch-hello-tag-list-make-query "tag:unread")
'(notmuch-message-headers (quote ("Subject" "To" "Cc" "Bcc" "Date" "Reply-To")))
'(notmuch-saved-searches
(quote
((:name "inbox" :query "tag:inbox and not tag:koumbit and not tag:rt")
(:name "unread inbox" :query "tag:inbox and tag:unread")
(:name "unread" :query "tag:unred")
(:name "freshports" :query "tag:freshports and tag:unread")
(:name "rapports" :query "tag:rapports and tag:unread")
(:name "sent" :query "tag:sent")
(:name "drafts" :query "tag:draft"))))
'(notmuch-search-line-faces
(quote
(("deleted" :foreground "red")
("unread" :weight bold)
("flagged" :foreground "blue"))))/
'(notmuch-search-oldest-first nil)
'(notmuch-show-all-multipart/alternative-parts nil)
'(notmuch-show-all-tags-list t)
'(notmuch-show-insert-text/plain-hook
(quote
(notmuch-wash-convert-inline-patch-to-part notmuch-wash-tidy-citations notmuch-wash-elide-blank-lines notmuch-wash-excerpt-citations)))
)
I think that covers it.
[general]
accounts = Anarcat
ui = Blinkenlights
maxsyncaccounts = 3
[Account Anarcat]
localrepository = LocalAnarcat
remoterepository = RemoteAnarcat
# refresh all mailboxes every 10 minutes
autorefresh = 10
# run notmuch after refresh
postsynchook = notmuch new
# sync only mailboxes that changed
quick = -1
## possible optimisation: ignore mails older than a year
#maxage = 365
# local mailbox location
[Repository LocalAnarcat]
type = Maildir
localfolders = ~/Maildir/Anarcat/
# remote IMAP server
[Repository RemoteAnarcat]
type = IMAP
remoteuser = anarcat
remotehost = anarc.at
ssl = yes
# without this, the cert is not verified (!)
sslcacertfile = /etc/ssl/certs/DST_Root_CA_X3.pem
# do not sync archives
folderfilter = lambda foldername: not re.search('(Sent\.20[01][0-9]\..*)', foldername) and not re.search('(Archive.*)', foldername)
# and only subscribed folders
subscribedonly = yes
# don't reconnect all the time
holdconnectionopen = yes
# get mails from INBOX immediately, doesn't trigger postsynchook
idlefolders = ['INBOX']
Critical parts are:
postsynchook: obviously, we want to run notmuch after fetching
mailidlefolders: receives emails immediately without waiting for the
longer autorefresh delay, which means that most mailboxes don't
see new emails until 10 minutes in the worst case. unfortunately,
doesn't run the postsynchook so I need to hit G in Emacs to see
new mailquick=-1, subscribedonly, holdconnectionopen: makes most runs
much, much faster as it skips unchanged or unsubscribed folders and
keeps the connection to the server---
include-images: true
target-refix: &target "maildir:///home/anarcat/Maildir/.feeds."
feeds:
- name: Planet Debian
url: http://planet.debian.org/rss20.xml
target: [ *target, 'debian-planet' ]
I have obviously more feeds, the above is just and example. This will
deliver the feeds as emails in one mailbox per feed, in
~/Maildir/.feeds.debian-planet, in the above example.
.dovecot.sieve.log file in your home directory.
I also enabled debugging on the Sieve module
--- a/dovecot/conf.d/90-sieve.conf
+++ b/dovecot/conf.d/90-sieve.conf
@@ -51,6 +51,7 @@ plugin
# deprecated imapflags extension in addition to all extensions were already
# enabled by default.
#sieve_extensions = +notify +imapflags
+ sieve_extensions = +vnd.dovecot.debug
# Which Sieve language extensions are ONLY available in global scripts. This
# can be used to restrict the use of certain Sieve extensions to administrator
This allowed me to use debug_log function in the rulesets to output
stuff directly to the logfile.
notmuch-purge hack above. Dovecot and Maildir
formats support up to 26 flags, and there were discussions about
using those flags to synchronize with notmuch tags so that
multiple notmuch clients can see the same tags on different machines
transparently.
This, however, won't make Notmuch work on my phone or webmail or any
other more generic client: for that, Sieve rules are still very
useful.
I still don't have webmail setup at all: so to read email, I need an
actual client, which is currently my phone, which means I need to have
Wifi access to read email. "Internet Caf s" or "this guy's computer"
won't work as well, although I can always use ssh to login straight
to the server and read mails with Mutt.
I am also considering using X509 client certificates to authenticate
to the mail server without a passphrase. This involves configuring
Postfix, which seems simple enough. Dovecot's configuration
seems a little more involved and less well documented. It
seems that both [OfflimeIMAP][] and K-9 mail support client-side
certs. OfflineIMAP prompts me for the password so it doesn't get
leaked anywhere. I am a little concerned about building yet another
CA, but I guess it would not be so hard...
The server side of things needs more documenting, particularly the
spam filters. This is currently spread around this wiki, mostly in
configuration.
ssh on the
server without trusting the machine too much, although that only goes
so far... Of course, sudo is then out of the question and I must
assume that everything I see is also seen by the attacker, which can
also inject keystrokes and do all sorts of nasty things.
Since I also connected my email account on my phone, someone could
steal the phone and start impersonating me. The mitigation here is
that there is a PIN for the screen lock, and the phone is
encrypted. Encryption isn't so great when the passphrase is a PIN, but
I'm working on having a better key that is required on reboot, and the
phone shuts down after 5 failed attempts. This is documented in my
phone setup.
Client-side X509 certificates further mitigates those kind of
compromises, as the X509 certificate won't give shell access.
Basically, if the phone is lost, all hell breaks loose: I need to
change the email password (or revoke the certificate), as I assume the
account is about to be compromised. I do not trust Android security to
give me protection indefinitely. In fact, one could argue that the
phone is already compromised and putting the password there already
enabled a possible state-sponsored attacker to hijack my email
address. This is why I have an OpenPGP key on my laptop to
authenticate myself for critical operations like code signatures.
The risk of identity theft from the state is, after all, a tautology:
the state is the primary owner of identities, some could say by
definition. So if a state-sponsored attacker would like to masquerade
as me, they could simply issue a passport under my name and join a
OpenPGP key signing party, and we'd have other problems to deal with,
namely, proper infiltration counter-measures and counter-snitching.
Interfacing with C
There are multiple things which make D awesome, for example interfacing with C code and to a limited degree with C++ code is really easy. Also, working with functions from C in D feels natural. Take these C functions imported into D:extern(C): nothrow: struct _mystruct alias mystruct_p = _mystruct*; mystruct_p = mystruct_create (); mystruct_load_file (mystruct_p my, const(char) *filename); mystruct_free (mystruct_p my);You can call them from D code in two ways:
auto test = mystruct_create ();
// treating "test" as function parameter
mystruct_load_file (test, "/tmp/example");
// treating the function as member of "test"
test.mystruct_load_file ("/tmp/example");
test.mystruct_free ();This allows writing logically sane code, in case the C functions can really be considered member functions of the struct they are acting on. This property of the language is a general concept, so a function which takes a string as first parameter, can also be called like a member function of string.
Writing D bindings to existing C code is also really simple, and can even be automatized using tools like dstep. Since D can also easily export C functions, calling D code from C is also possible.
Getting rid of C++ cruft
There are many things which are bad in C++, some of which are inherited from C. D kills pretty much all of the stuff I found annoying. Some cool stuff from D is now in C++ as well, which makes this point a bit less strong, but it s still valid. E.g. getting rid of the #include preprocessor dance by using symbolic import statements makes sense, and there have IMHO been huge improvements over C++ when it comes to metaprogramming.
Incredibly powerful metaprogramming
Getting into detail about that would take way too long, but the metaprogramming abilities of D must be mentioned. You can do pretty much anything at compiletime, for example compiling regular expressions to make them run faster at runtime, or mixing in additional code from string constants. The template system is also very well thought out, and never caused me headaches as much as C++ sometimes manages to do.
Built-in unit-test support
Unittesting with D is really easy: You just add one or more unittest blocks to your code, in which you write your tests. When running the tests, the D compiler will collect the unittest blocks and build a test application out of them.
The unittest scope is useful, because you can keep the actual code and the tests close together, and it encourages writing tests and keep them up-to-date. Additionally, D has built-in support for contract programming, which helps to further reduce bugs by validating input/output.
Safe D
While D gives you the whole power of a low-level system programming language, it also allows you to write safer code and have the compiler check for that, while still being able to use unsafe functions when needed.
Unfortunately, @safe is not the default for functions though.
Separate operators for addition and concatenation
D exclusively uses the + operator for addition, while the ~ operator is used for concatenation. This is likely a personal quirk, but I love it very much that this distinction exists. It s nice for things like addition of two vectors vs. concatenation of vectors, and makes the whole language much more precise in its meaning.
Optional garbage collector
D has an optional garbage collector. Developing in D without GC is currently a bit cumbersome, but these issues are being addressed. If you can live with a GC though, having it active makes programming much easier.
Built-in documentation generator
This is almost granted for most new languages, but still something I want to mention: Ddoc is a standard tool to generate code documentation for D code, with a defined syntax for describing function parameters, classes, etc. It will even take the contents of a unittest scope to generate automatic examples for the usage of a function, which is pretty cool.
Scope blocks
The scope statement allows one to execute a bit of code before the function exists, when it failed or was successful. This is incredibly useful when working with C code, where a free statement needs to be issued when the function is exited, or some arbitrary cleanup needs to be performed on error. Yes, we do have smart pointers in C++ and with some GCC/Clang extensions a similar feature in C too. But the scopes concept in D is much more powerful. See Scope Guard Statement for details.
Built-in syntax for parallel programming
Working with threads is so much more fun in D compared to C! I recommend taking a look at the parallelism chapter of the Programming in D book.
Pure functions
D allows to mark functions as purely-functional, which allows the compiler to do optimizations on them, e.g. cache their return value. See pure-functions.
D is fast!
D matches the speed of C++ in almost all occasions, so you won t lose performance when writing D code that is, unless you have the GC run often in a threaded environment.
Very active and friendly community
The D community is very active and friendly so far I only had good experience, and I basically came into the community asking some tough questions regarding distro-integration and ABI stability of D. The D community is very enthusiastic about pushing D and especially the metaprogramming features of D to its limits, and consists of very knowledgeable people. Most discussion happens at the forums/newsgroups at forum.dlang.org.
What is bad about D?
Half-proprietary reference compiler
This is probably the biggest issue. Not because the proprietary compiler is bad per se, but because of the implications this has for the D ecosystem.
For the reference D compiler, Digital Mars D (DMD), only the frontend is distributed under a free license (Boost), while the backend is proprietary. The FLOSS frontend is what the free compilers, LLVM D Compiler (LDC) and GNU D Compiler (GDC) are based on. But since DMD is the reference compiler, most features land there first, and the Phobos standard library and druntime is tuned to work with DMD first.
Since major Linux distributions can t ship with DMD, and the free compilers GDC and LDC lack behind DMD in terms of language, runtime and standard-library compatibility, this creates a split world of code that compiles with LDC, GDC or DMD, but never with all D compilers due to it relying on features not yet in e.g. GDCs Phobos.
Especially for Linux distributions, there is no way to say use this compiler to get the best and latest D compatibility . Additionally, if people can t simply apt install latest-d, they are less likely to try the language. This is probably mainly an issue on Linux, but since Linux is the place where web applications are usually written and people are likely to try out new languages, it s really bad that the proprietary reference compiler is hurting D adoption in that way.
That being said, I want to make clear DMD is a great compiler, which is very fast and build efficient code. I only criticise the fact that it is the language reference compiler.
UPDATE: To clarify the half-proprietary nature of the compiler, let me quote the D FAQ:
The front end for the dmd D compiler is open source. The back end for dmd is licensed from Symantec, and is not compatible with open-source licenses such as the GPL. Nonetheless, the complete source comes with the compiler, and all development takes place publically on github. Compilers using the DMD front end and the GCC and LLVM open source backends are also available. The runtime library is completely open source using the Boost License 1.0. The gdc and ldc D compilers are completely open sourced.Phobos (standard library) is deprecating features too quickly This basically goes hand in hand with the compiler issue mentioned above. Each D compiler ships its own version of Phobos, which it was tested against. For GDC, which I used to compile my code due to LDC having bugs at that time, this means that it is shipping with a very outdated copy of Phobos. Due to the rapid evolution of Phobos, this meant that the documentation of Phobos and the actual code I was working with were not always in sync, leading to many frustrating experiences. Furthermore, Phobos is sometimes removing deprecated bits about a year after they have been deprecated. Together with the older-Phobos situation, you might find yourself in a place where a feature was dropped, but the cool replacement is not yet available. Or you are unable to import some 3rd-party code because it uses some deprecated-and-removed feature internally. Or you are unable to use other code, because it was developed with a D compiler shipping with a newer Phobos. This is really annoying, and probably the biggest source of unhappiness I had while working with D especially the documentation not matching the actual code is a bad experience for someone new to the language. Incomplete free compilers with varying degrees of maturity LDC and GDC have bugs, and for someone new to the language it s not clear which one to choose. Both LDC and GDC have their own issues at time, but they are rapidly getting better, and I only encountered some actual compiler bugs in LDC (GDC worked fine, but with an incredibly out-of-date Phobos). All issues are fixed meanwhile, but this was a frustrating experience. Some clear advice or explanation which of the free compilers is to prefer when you are new to D would be neat. For GDC in particular, being developed outside of the main GCC project is likely a problem, because distributors need to manually add it to their GCC packaging, instead of having it readily available. I assume this is due to the DRuntime/Phobos not being subjected to the FSF CLA, but I can t actually say anything substantial about this issue. Debian adds GDC to its GCC packaging, but e.g. Fedora does not do that. No ABI compatibility D has a defined ABI too bad that in reality, the compilers are not interoperable. A binary compiled with GDC can t call a library compiled with LDC or DMD. GDC actually doesn t even support building shared libraries yet. For distributions, this is quite terrible, because it means that there must be one default D compiler, without any exception, and that users also need to use that specific compiler to link against distribution-provided D libraries. The different runtimes per compiler complicate that problem further. The D package manager, dub, does not yet play well with distro packaging This is an issue that is important to me, since I want my software to be easily packageable by Linux distributions. The issues causing packaging to be hard are reported as dub issue #838 and issue #839, with quite positive feedback so far, so this might soon be solved. The GC is sometimes an issue The garbage collector in D is quite dated (according to their own docs) and is currently being reworked. While working with asgen, which is a program creating a large amount of interconnected data structures in a threaded environment, I realized that the GC is significantly slowing down the application when threads are used (it also seems to use UNIX signals
SIGUSR1 and SIGUSR2 to stop/resume threads, which I still find odd). Also, the GC performed poorly on memory pressure, which did get asgen killed by the OOM killer on some more memory-constrained machines. Triggering a manual collection run after a large amount of these interconnected data structures wasn t needed anymore solved this problem for most systems, but it would of course have been better to not needing to give the GC any hints. The stop-the-world behavior isn t a problem for asgen, but it might be for other applications.
These issues are at time being worked on, with a GSoC project laying the foundation for further GC improvements.
version is a reserved word
Okay, that is admittedly a very tiny nitpick, but when developing an app which works with packages and versions, it s slightly annoying. The version keyword is used for conditional compilation, and needing to abbreviate it to ver in all parts of the code sucks a little (e.g. the Package interface can t have a property version , but now has ver instead).
The ecosystem is not (yet) mature
In general it can be said that the D ecosystem, while existing for almost 9 years, is not yet that mature. There are various quirks you have to deal with when working with D code on Linux. It s always nothing major, usually you can easily solve these issues and go on, but it s annoying to have these papercuts.
This is not something which can be resolved by D itself, this point will solve itself as more people start to use D and D support in Linux distributions gets more polished.
Conclusion
I like to work with D, and I consider it to be a great language the quirks it has in its toolchain are not that bad to prevent writing great things with it.
At time, if I am not writing a shared library or something which uses much existing C++ code, I would prefer D for that task. If a garbage collector is a problem (e.g. for some real-time applications, or when the target architecture can t run a GC), I would not recommend to use D. Rust seems to be the much better choice then.
In any case, D s flat learning curve (for C/C++ people) paired with the smart choices taken in language design, the powerful metaprogramming, the rich standard library and helpful community makes it great to try out and to develop software for scenarios where you would otherwise choose C++ or Java. Quite honestly, I think D could be a great language for tasks where you would usually choose Python, Java or C++, and I am seriously considering to replace quite some Python code with D code. For very low-level stuff, C is IMHO still the better choice.
As always, choosing the right programming language is only 50% technical aspects, and 50% personal taste
UPDATE: To get some idea of D, check out the D tour on the new website tour.dlang.org.
dh $@ --with buildinfo in deb/rules instead of having to
explicitly call it somewhere in an override.
Debops
I've set up initial Debian packages of Debops2, a collection of fine crafted
Ansible roles and playbooks especially for Debian servers, shipped with a couple
of convenience and wrapper scripts in Python3.
There are two binary packages, one for the toolset (debops), and the other for the
playbooks and roles of the project (debops-playbooks).
The application is easy to use, just initialize a new project with debops-init foo
and add your server(s) to foo/ansible/inventory/hosts belonging to groups representing
services and things you want to employ on them.
Like the group [debops_gitlab] automatically installs a complete running Gitlab setup
on one or a multitude of servers in the same run with the debops command4.
Use other groups like [debops_mariadb_server] accordingly in the same host inventory.
Ansible runs agent less, so you don't have to prepare freshly setup servers with nothing
special to use that tool randomly (like on localhost).
The list of things you could deploy with Debops is quite amazing and you've got dozens
of services at your hand.
The new packages are currently in experimental because they need some more fine
tuning, like there are a couple of minor error messages which recently occur using it,
but it works well.
The (early staged) documentation unfortunately couldn't be packaged because of the
scattered resp. collective nature of the project (all parts have their own Github repositories)5,
and also how to generate the upstream tarball remains a bit of a challenge (currently,
it's the outcome of debops-init)6.
I'll have this package in unstable soon. More info on Debops is coming up, then.
Hashicorp's Packer
I'm very glad to announce that Packer7 is ready being available in unstable,
and the two year old RFP bug could be finally closed8.
It's another great and much convenient devops tool which does a lot of different
things in an automated fashion using only a single "one-argument" CLI tool in combination
with a couple of lines in a configuration script (thanks to Yaroslav Halchenko for the tip).
Packer helps creating machine images for different platforms.
This is like when you use e.g. Debian installations in a Qemu box for testing or development
purposes.
Instead of setting up a new virtual machine manually like installing Debian on
another computer this process could be automated with Packer, like I've written about
in this blog entry here9.
You just need a template containing instructions for the included Qemu-builder and a preseeding
script for the Debian installer, and there you go drinking your coffee while Packer does all
the work for you: downloading the installation ISO image, creating the new virtual harddrive,
booting the emulator, running the whole installation process automatically like answering questions,
selecting things, rebooting without ISO image to complete the installation etc.
A couple of minutes and you have a new pre-baked virtual machine image like from a vendoring
machine, a fresh one everytime you need it.
Packer10 supports a number of builders for different target platforms
(desktop virtualization solutions as much as public cloud providers and private cloud software),
can build in parallel, and also the full range of common provisioners can be employed
in the process to equip the newly installed OSs.
Vagrant boxes could be generated by one of the included postprocessors.
I'll write more on Packer here on this blog, soon.
There were more then two dozens of packages missing to complete Packer11, which is
the achievement of combined forces within the pkg-go group. Much thanks esp. to Alexandre
Viau who have worked on the most of the needed new packages.
Thanks also to the FTP-masters which were always very quick in reviewing the Go packages,
so that it could be proceeded to build and package the sub dependent new ones always consecutively.
Squirrel3
I've didn't had the most work with it and just sponsored this for Fabian Wolff, but want to
highlight here that there's a new package of Squirrel12 now available in
Debian13.
Squirrel is a lightweight scripting language, somewhat comparable to Lua. It's
fully object-oriented and highly embeddable, it's used in a lot of commerical computer
games under the hood for implementing intelligence for bots next to other things14,
but also for the Internet of Things (it's embedded in hardware from Electric Imp).
Squirrel functions could be called from C++15.
I've filed an ITP bug for Squirrel already in 2011 (#651195), but always something else
got in the way, and it ended up being an RFP. I'm really glad that it got picked up
and completed.
misc
There were a couple of uploads on updated upstream tarballs and for fixing bugs,
namely afl/2.10b-1 and 2.11b-1,
python-afl/0.5.3-1, pyutilib/5.3.2-1, pyomo/4.3.11327-1,
libvigraimpex/1.10.0+git20160211.167be93dfsg-2 (fix of #820429, thanks for Tobias Frost),
and gamera/3.4.2+svn1454-1.
For the pkg-go group, I've set up a new package of github-mitchellh-ioprogress (which is
needed by the official DigitalOcean CLI tool doctl, now RFP #807956 instead of ITP
due to the lack of time - again facing a lot of missing packages),
and provided a little patch for dh-make-golang updating some standards16.
For Packer I've also updated azure-go-autorest and azure-sdk as team upload (#821938, #821832),
but it came out that the project which is currently under heavy development towards
a new official release broke a lot in the past weeks (and no Git branching have been used),
so that Packer as a matter of fact needed a vendored snapshot, although there have been only a
couple of commits in between.
Docker-registry hat the same problem with the new package of azure-sdk/2.1.1~beta1, so that it
needed to be fixed, too (#822146).
By the way, the tool ratt17 comes very handy for automatically test building down all
reverse dependencies, not only for Go packages (thanks to Tianon Gravi for the tip).
Finally, I've posted the needed reverse depencies as RFP bugs for Terraform18
(again quite a lot), Vuls19, and cve-dictionary20, which is needed for Vuls.
I'll let them rest a while waiting to get picked up before working anything down.
debops like:
$ debops -u root --private-key=~/.ssh/id_digitalocean
dh $@ --with buildinfo in deb/rules instead of having to
explicitly call it somewhere in an override.
Debops
I've set up initial Debian packages of Debops2, a collection of fine crafted
Ansible roles and playbooks especially for Debian servers (servers which run on Debian),
which are shipped with a couple of helper and wrapper scripts in Python3.
There are two binary packages, one for the toolset (debops), and the other for the
playbooks and roles of the project (debops-playbooks).
The application is easy to use, just initialize a new project with debops-init foo
and add your server(s) to foo/ansible/inventory/hosts belonging to groups representing
services and things you want to employ on them.
For example, the group [debops_gitlab] automatically installs a complete running Gitlab setup
on one or a multitude of servers in the same run with the debops command4.
Other groups like [debops_mariadb_server] could be used accordingly in the same host inventory.
Ansible works without agent, so you don't have to prepare freshly setup servers with nothing
special to use that tool randomly (like on localhost).
The list of things you could deploy with Debops is quite amazing and dozens
of services are at hand.
The new Debian packages are currently in experimental because they need some more fine
tuning, e.g. there are a couple of minor error messages which recently occur using it,
but it works well.
The (early staged) documentation unfortunately couldn't be packaged because of the
scattered resp. collective nature of the project (all parts have their own Github
repositories)5, and also how to generate the upstream tarball remains a bit of a
challenge (currently, it's the outcome of debops-init)6.
I'll have this package in unstable soon. More info on Debops is coming up, then.
HashiCorp's Packer
I'm very glad to announce that Packer7 is ready being available in unstable,
and the RFP bug could be finally closed after I've taken it over8.
It's another great and much convenient devops tool which does a lot of different
things in an automated fashion using only a single "one-argument" CLI tool in combination
with a couple of lines in a configuration script (thanks to Yaroslav Halchenko for the tip).
Packer helps creating machine images for different platforms.
This is like when you use e.g. Debian installations in a Qemu box for testing or development
purposes.
Instead of setting up a new virtual machine manually the same way as installing Debian on
another computer this process can be completely automated with Packer, like I've written about
in this blog entry here9.
You just need a template which contains instructions for the included Qemu builder and a
preseeding script for the Debian installer, and there you go drinking your coffee while
Packer does all the work:
download the ISO image for installation, create the new virtual harddrive, boot the
emulator, run the whole installation process automatically like with answering questions,
selecting things, reboot without ISO image to complete the installation etc.
A couple of minutes and you have a new pre-baked virtual machine image like from a vendoring
machine, another fresh one could be created anytime.
Packer10 supports a number of builders for different target platforms
(desktop virtualization solutions as much as public cloud providers and private cloud software),
can build in parallel, and also the full range of common provisioners can be employed
in the process to equip the newly installed OSs with services and programs.
Vagrant boxes could be generated by one of the included postprocessors.
I'll write more on Packer here on this blog, soon.
There were more then two dozens of packages missing to complete Packer11, which is
the achievement of combined forces within the pkg-go group. Much thanks esp. to Alexandre
Viau who have worked on the most of the needed new packages.
Thanks also to the FTP masters which were always very quick in reviewing the Go packages,
so that it could be proceeded to build and package the sub dependent new ones always
consecutively.
Squirrel3
I've didn't had the major work of that and just sponsored this for Fabian Wolff, but want
to highlight here that there's a new package of Squirrel12 now available in
Debian13.
Squirrel is a lightweight scripting language, somewhat comparable to Lua. It's
fully object-oriented and highly embeddable, it's used in a lot of commerical computer
games under the hood for implementing intelligence for bots next to other things14,
but also for the Internet of Things (it's embedded in hardware from Electric Imp).
Squirrel functions could be called from C++15.
I've filed an ITP bug for Squirrel already in 2011 (#651195), but always something else
had a higher priority, and it ended up being an RFP. I'm really glad that it got picked up
and completed quickly afterwards.
misc
There were a couple of uploads on updated upstream tarballs and for fixing bugs,
namely afl/2.10b-1 and 2.11b-1,
python-afl/0.5.3-1, pyutilib/5.3.2-1, pyomo/4.3.11327-1,
libvigraimpex/1.10.0+git20160211.167be93dfsg-2 (fix of #820429, thanks to Tobias Frost),
and gamera/3.4.2+svn1454-1.
For the pkg-go group, I've set up a new package of github-mitchellh-ioprogress (which is
needed by the official DigitalOcean CLI tool doctl, now RFP #807956 instead of ITP
due to the lack of time, again a lot of missing packages are missing for that),
and provided a little patch for dh-make-golang updating some standards16.
For Packer I've also updated azure-go-autorest and azure-sdk as team upload (#821938, #821832),
but it came out that the project which is currently under heavy development towards
a new official release broke a lot in the past weeks (no Git branching have been used),
so that Packer as a matter of fact needed a vendored snapshot, although there have been only
a couple of commits in between.
Docker-registry has the same problem with the new package of azure-sdk/2.1.1~beta1, so that it
needed to be fixed, too (#822146).
By the way, the tool ratt17 comes very handy for automatically test building down all
reverse dependencies, not only for Go packages (thanks to Tianon Gravi for the tip).
Finally, I've posted the needed reverse depencies as RFP bugs for Terraform18
(again quite a lot), Vuls19, and cve-dictionary20, which is needed for Vuls.
I'll let them rest a while waiting to get picked up before working anything down.
debops like:
$ debops -u root --private-key=~/.ssh/id_digitalocean
Switching from one GnuPG master key to the usage of subkeys was long on my list of things I wanted to do, but never came around. With the advent of a YubiKey NEO in my pocket I finally took the plunge: reading through lots of web pages (and adding one here for confusion), trying to understand the procedures, and above all, understanding my own requirements!
To sum up a long story, it was worth the plunge, and all over the security level of my working environment has improved considerable.
While the advantages of subkeys are well documented (e.g., Debian Wiki), at the end of the day I was like probably many Debian Developers having one master key that was used for every action: mail decryption and signing, signing of uploads, etc. Traveling a lot I always felt uncomfortable. Despite a lengthy passphrase, I still didn t want my master key to get into wrong hands in case the laptop got stolen. Furthermore, I had my master key on several computers (work, laptop, mail server), which didn t help a lot either. With all this, I started to compile a list of requirements/objectives I wanted to have:
$ gpg -K $MASTERKEY
sec 4096R/0x6CACA448860CDC13 2010-09-14
Key fingerprint = F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
uid Norbert Preining <norbert@preining.info>
uid Norbert Preining <preining@logic.at>
uid Norbert Preining <preining@debian.org>
uid Norbert Preining <preining@jaist.ac.jp>
ssb 4096R/0xD1D2BD14810F62B3 2010-09-14 |
$ gpg --expert --edit-key $MASTERKEY |
$ gpg --expert --edit-key $MASTERKEY
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: never usage: SC
trust: ultimate validity: ultimate
sub 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: never usage: E
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
gpg> expire
Changing expiration time for the primary key.
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Mon 06 Feb 2017 08:09:16 PM JST
Is this correct? (y/N) y
You need a passphrase to unlock the secret key for
user: "Norbert Preining <norbert@preining.info>"
4096-bit RSA key, ID 0x6CACA448860CDC13, created 2010-09-14
Enter passphrase:
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: never usage: E
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
gpg> key 1
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub* 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: never usage: E
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
gpg> expire
Changing expiration time for a subkey.
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Mon 06 Feb 2017 08:09:27 PM JST
Is this correct? (y/N) y
You need a passphrase to unlock the secret key for
user: "Norbert Preining <norbert@preining.info>"
4096-bit RSA key, ID 0x6CACA448860CDC13, created 2010-09-14
Enter passphrase:
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub* 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: 2017-02-06 usage: E
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp> |
gpg> addphoto
Pick an image to use for your photo ID. The image must be a JPEG file.
Remember that the image is stored within your public key. If you use a
very large picture, your key will become very large as well!
Keeping the image close to 240x288 is a good size to use.
Enter JPEG filename for photo ID: GPG/norbert-head.jpg
Is this photo correct (y/N/q)? y
You need a passphrase to unlock the secret key for
user: "Norbert Preining <norbert@preining.info>"
4096-bit RSA key, ID 0x6CACA448860CDC13, created 2010-09-14
Enter passphrase:
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub* 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: 2017-02-06 usage: E
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ unknown] (5) [jpeg image of size 4185] |
gpg> addkey
Key is protected.
You need a passphrase to unlock the secret key for
user: "Norbert Preining <norbert@preining.info>"
4096-bit RSA key, ID 0x6CACA448860CDC13, created 2010-09-14
Enter passphrase:
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Mon 06 Feb 2017 08:10:06 PM JST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
....+++++
..........+++++
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub* 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: 2017-02-06 usage: E
sub 2048R/0xEC00B8DAD32266AA created: 2016-02-07 expires: 2017-02-06 usage: S
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ unknown] (5) [jpeg image of size 4185] |
gpg> addkey
Key is protected.
You need a passphrase to unlock the secret key for
user: "Norbert Preining <norbert@preining.info>"
4096-bit RSA key, ID 0x6CACA448860CDC13, created 2010-09-14
Enter passphrase:
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Mon 06 Feb 2017 08:10:20 PM JST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
..+++++
........+++++
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub* 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: 2017-02-06 usage: E
sub 2048R/0xEC00B8DAD32266AA created: 2016-02-07 expires: 2017-02-06 usage: S
sub 2048R/0xBF361ED434425B4C created: 2016-02-07 expires: 2017-02-06 usage: E
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ unknown] (5) [jpeg image of size 4185] |
gpg> addkey
Key is protected.
You need a passphrase to unlock the secret key for
user: "Norbert Preining <norbert@preining.info>"
4096-bit RSA key, ID 0x6CACA448860CDC13, created 2010-09-14
Enter passphrase:
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
Your selection? 8
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? s
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? e
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? a
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Mon 06 Feb 2017 08:10:34 PM JST
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
......+++++
+++++
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub* 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: 2017-02-06 usage: E
sub 2048R/0xEC00B8DAD32266AA created: 2016-02-07 expires: 2017-02-06 usage: S
sub 2048R/0xBF361ED434425B4C created: 2016-02-07 expires: 2017-02-06 usage: E
sub 2048R/0x9C7CA4E294F04D49 created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ unknown] (5) [jpeg image of size 4185]
gpg> save |
$ gpg --expert --edit-key $MASTERKEY
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
gpg: checking the trustdb
gpg: public key 0x0FC3EC02FBBB8AB1 is 58138 seconds newer than the signature
gpg: 3 marginal(s) needed, 1 complete(s) needed, classic trust model
gpg: depth: 0 valid: 2 signed: 28 trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: depth: 1 valid: 28 signed: 41 trust: 28-, 0q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2016-11-02
pub 4096R/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
sub 4096R/0xD1D2BD14810F62B3 created: 2010-09-14 expires: 2017-02-06 usage: E
sub 2048R/0xEC00B8DAD32266AA created: 2016-02-07 expires: 2017-02-06 usage: S
sub 2048R/0xBF361ED434425B4C created: 2016-02-07 expires: 2017-02-06 usage: E
sub 2048R/0x9C7CA4E294F04D49 created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> |
$ gpg --gen-revoke $MASTERKEY > GPG/revoke-certificate-$MASTERKEY.txt sec 4096R/0x6CACA448860CDC13 2010-09-14 Norbert Preining <norbert@preining.info> Create a revocation certificate for this key? (y/N) y Please select the reason for the revocation: 0 = No reason specified 1 = Key has been compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel (Probably you want to select 1 here) Your decision? 1 Enter an optional description; end it with an empty line: > Reason for revocation: Key has been compromised (No description given) Is this okay? (y/N) y You need a passphrase to unlock the secret key for user: "Norbert Preining <norbert@preining.info>" 4096-bit RSA key, ID 0x6CACA448860CDC13, created 2010-09-14 Enter passphrase: ASCII armored output forced. Revocation certificate created. |
$ killall gpg-agent |
$ gpg2 -K $MASTERKEY
gpg: keyserver option 'ca-cert-file' is obsolete; please use 'hkp-cacert' in dirmngr.conf
gpg: starting migration from earlier GnuPG versions
gpg: porting secret keys from '/home/norbert/.gnupg/secring.gpg' to gpg-agent
gpg: key 0xD2BF4AA309C5B094: secret key imported
gpg: key 0x6CACA448860CDC13: secret key imported
gpg: migration succeeded
sec rsa4096/0x6CACA448860CDC13 2010-09-14 [SC] [expires: 2017-02-06]
Key fingerprint = F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
uid [ultimate] Norbert Preining <norbert@preining.info>
uid [ultimate] Norbert Preining <preining@logic.at>
uid [ultimate] Norbert Preining <preining@debian.org>
uid [ultimate] Norbert Preining <preining@jaist.ac.jp>
uid [ultimate] [jpeg image of size 4185]
ssb rsa4096/0xD1D2BD14810F62B3 2010-09-14 [E] [expires: 2017-02-06]
ssb rsa2048/0xEC00B8DAD32266AA 2016-02-07 [S] [expires: 2017-02-06]
ssb rsa2048/0xBF361ED434425B4C 2016-02-07 [E] [expires: 2017-02-06]
ssb rsa2048/0x9C7CA4E294F04D49 2016-02-07 [A] [expires: 2017-02-06] |
%Assuan% socket=/dev/shm/S.gpg-agent |
$ gpg2 --edit-key $MASTERKEY
gpg (GnuPG) 2.1.11; Copyright (C) 2016 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> key 2
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb* rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> keytocard
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb* rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> key 2
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> key 3
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb* rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb* rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> key 3
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> key 4
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb* rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> keytocard
Please select where to store the key:
(3) Authentication key
Your selection? 3
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb* rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> key 4
sec rsa4096/0x6CACA448860CDC13
created: 2010-09-14 expires: 2017-02-06 usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/0xD1D2BD14810F62B3
created: 2010-09-14 expires: 2017-02-06 usage: E
ssb rsa2048/0xEC00B8DAD32266AA
created: 2016-02-07 expires: 2017-02-06 usage: S
ssb rsa2048/0xBF361ED434425B4C
created: 2016-02-07 expires: 2017-02-06 usage: E
ssb rsa2048/0x9C7CA4E294F04D49
created: 2016-02-07 expires: 2017-02-06 usage: A
[ultimate] (1). Norbert Preining <norbert@preining.info>
[ultimate] (2) Norbert Preining <preining@logic.at>
[ultimate] (3) Norbert Preining <preining@debian.org>
[ultimate] (4) Norbert Preining <preining@jaist.ac.jp>
[ultimate] (5) [jpeg image of size 4185]
gpg> save |
$ gpg2 -K $MASTERKEY
gpg: keyserver option 'ca-cert-file' is obsolete; please use 'hkp-cacert' in dirmngr.conf
sec rsa4096/0x6CACA448860CDC13 2010-09-14 [SC] [expires: 2017-02-06]
Key fingerprint = F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
uid [ultimate] Norbert Preining <norbert@preining.info>
uid [ultimate] Norbert Preining <preining@logic.at>
uid [ultimate] Norbert Preining <preining@debian.org>
uid [ultimate] Norbert Preining <preining@jaist.ac.jp>
uid [ultimate] [jpeg image of size 4185]
ssb rsa4096/0xD1D2BD14810F62B3 2010-09-14 [E] [expires: 2017-02-06]
ssb> rsa2048/0xEC00B8DAD32266AA 2016-02-07 [S] [expires: 2017-02-06]
ssb> rsa2048/0xBF361ED434425B4C 2016-02-07 [E] [expires: 2017-02-06]
ssb> rsa2048/0x9C7CA4E294F04D49 2016-02-07 [A] [expires: 2017-02-06]
$ gpg -K $MASTERKEY
sec 4096R/0x6CACA448860CDC13 2010-09-14 [expires: 2017-02-06]
Key fingerprint = F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
uid Norbert Preining <norbert@preining.info>
uid Norbert Preining <preining@logic.at>
uid Norbert Preining <preining@debian.org>
uid Norbert Preining <preining@jaist.ac.jp>
uid [jpeg image of size 4185]
ssb 4096R/0xD1D2BD14810F62B3 2010-09-14 [expires: 2017-02-06]
ssb 2048R/0xEC00B8DAD32266AA 2016-02-07 [expires: 2017-02-06]
ssb 2048R/0xBF361ED434425B4C 2016-02-07 [expires: 2017-02-06]
ssb 2048R/0x9C7CA4E294F04D49 2016-02-07 [expires: 2017-02-06]
$ gpg2 --card-status
....
Name of cardholder: Norbert Preining
....
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: 5871 F824 2DCC 3660 2362 BE7D EC00 B8DA D322 66AA
created ....: 2016-02-07 11:10:06
Encryption key....: 2501 195C 90AB F4D2 3DEA A303 BF36 1ED4 3442 5B4C
created ....: 2016-02-07 11:10:20
Authentication key: 9CFB 3775 C164 0E99 F0C8 014C 9C7C A4E2 94F0 4D49
created ....: 2016-02-07 11:10:34
General key info..: sub rsa2048/0xEC00B8DAD32266AA 2016-02-07 Norbert Preining <norbert@preining.info>
sec rsa4096/0x6CACA448860CDC13 created: 2010-09-14 expires: 2017-02-06
ssb rsa4096/0xD1D2BD14810F62B3 created: 2010-09-14 expires: 2017-02-06
ssb> rsa2048/0xEC00B8DAD32266AA created: 2016-02-07 expires: 2017-02-06
card-no: 0006 03645719
ssb> rsa2048/0xBF361ED434425B4C created: 2016-02-07 expires: 2017-02-06
card-no: 0006 03645719
ssb> rsa2048/0x9C7CA4E294F04D49 created: 2016-02-07 expires: 2017-02-06
card-no: 0006 03645719
$ |
$ gpg2 --with-keygrip --list-key $MASTERKEY
pub rsa4096/0x6CACA448860CDC13 2010-09-14 [SC] [expires: 2017-02-06]
Key fingerprint = F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
Keygrip = 9DC1E90703856C1DE0EAC970CED7ABF5EE5EF79D
uid [ultimate] Norbert Preining <norbert@preining.info>
uid [ultimate] Norbert Preining <preining@logic.at>
uid [ultimate] Norbert Preining <preining@debian.org>
uid [ultimate] Norbert Preining <preining@jaist.ac.jp>
uid [ultimate] [jpeg image of size 4185]
sub rsa4096/0xD1D2BD14810F62B3 2010-09-14 [E] [expires: 2017-02-06]
Keygrip = 4B8FF57434DD989243666377376903281D861596
sub rsa2048/0xEC00B8DAD32266AA 2016-02-07 [S] [expires: 2017-02-06]
Keygrip = 39B14EF1392F2F251863A87AE4D44CE502755C39
sub rsa2048/0xBF361ED434425B4C 2016-02-07 [E] [expires: 2017-02-06]
Keygrip = E41C8DDB2A22976AE0DA8D7D11F586EA793203EA
sub rsa2048/0x9C7CA4E294F04D49 2016-02-07 [A] [expires: 2017-02-06]
Keygrip = A337DE390143074C6DBFEA64224359B9859B02FC
$ rm ~/.gnupg/private-keys-v1.d/9DC1E90703856C1DE0EAC970CED7ABF5EE5EF79D.key
$ |
$ gpg2 -K $MASTERKEY sec# rsa4096/0x6CACA448860CDC13 2010-09-14 [SC] [expires: 2017-02-06] ... |
$ gpg --output secret-subkeys --export-secret-subkeys $MASTERKEY $ gpg --delete-secret-keys $MASTERKEY sec 4096R/0x6CACA448860CDC13 2010-09-14 Norbert Preining <norbert@preining.info> Delete this key from the keyring? (y/N) y This is a secret key! - really delete? (y/N) y $ gpg --import secret-subkeys gpg: key 0x6CACA448860CDC13: secret key imported gpg: key 0x6CACA448860CDC13: "Norbert Preining <norbert@preining.info>" not changed gpg: Total number processed: 1 gpg: unchanged: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1 $ |
$ gpg2 -K $MASTERKEY
sec# rsa4096/0x6CACA448860CDC13 2010-09-14 [SC] [expires: 2017-02-06]
Key fingerprint = F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
uid [ultimate] Norbert Preining <norbert@preining.info>
uid [ultimate] Norbert Preining <preining@logic.at>
uid [ultimate] Norbert Preining <preining@debian.org>
uid [ultimate] Norbert Preining <preining@jaist.ac.jp>
uid [ultimate] [jpeg image of size 4185]
ssb rsa4096/0xD1D2BD14810F62B3 2010-09-14 [E] [expires: 2017-02-06]
ssb> rsa2048/0xEC00B8DAD32266AA 2016-02-07 [S] [expires: 2017-02-06]
ssb> rsa2048/0xBF361ED434425B4C 2016-02-07 [E] [expires: 2017-02-06]
ssb> rsa2048/0x9C7CA4E294F04D49 2016-02-07 [A] [expires: 2017-02-06]
$ |
$ gpg -K $MASTERKEY
sec# 4096R/0x6CACA448860CDC13 2010-09-14 [expires: 2017-02-06]
Key fingerprint = F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
uid Norbert Preining <norbert@preining.info>
uid Norbert Preining <preining@logic.at>
uid Norbert Preining <preining@debian.org>
uid Norbert Preining <preining@jaist.ac.jp>
uid [jpeg image of size 4185]
ssb 4096R/0xD1D2BD14810F62B3 2010-09-14 [expires: 2017-02-06]
ssb 2048R/0xEC00B8DAD32266AA 2016-02-07 [expires: 2017-02-06]
ssb 2048R/0xBF361ED434425B4C 2016-02-07 [expires: 2017-02-06]
ssb 2048R/0x9C7CA4E294F04D49 2016-02-07 [expires: 2017-02-06]
$ |
$ cp -a .gnupg .gnupg-mail $ cd .gnupg-mail $ rm -rf private-keys-v1.d/ pubring.gpg~ reader_0.status $ rm -rf S.gpg-agent* S.scdaemon .gpg-v21-migrated |
$ cd $HOME/.gnupg $ rm secring.gpg |
gpg --keyserver hkp://keyring.debian.org --send-key YOURMASTERKEYID |
gpg --keyserver hkp://pool.sks-keyservers.net --send-key $MASTERKEY |
With a small baby invading your lifestyle, not much time for other activities is left over, especially for gaming. Most of the times even using my computer is a one-hand-action. In these times mobile games that can be played one-handed are greatly appreciated. And if it is one like Monument Valley, full of atmosphere and incredibly stimulating game play, then the level of gratitude is near infinite.
Set in an Escherian universe where space and distance is often an illusion, the player is guiding a small princess through several levels (10+1 in the basic game, 8 more in the In-App-Purchase) of astonishing simplicity and beauty at the same time. Carefully crafted graphics, atmospheric music, calm game play (no action, don t worry), and the lovely crows sitting around and craaaahing at the little princess.
My favorite level was the first of the expansion pack Forgotten shores called The Chasm a wonderful homage to the Lord of the Rings and the descent to the Bridge of Khazad-d m. Not one of the difficult levels, but definitely one of the most funny. The middle image in the above collage is from that level.
I guess my only complain about this game is that it doesn t last long. I remember only one really difficult level where I had to play around quite some time. Most of the others are quite straight forward, but despite of that, you cannot stop playing until you are all through it.
Simply a wonderful game, that was well worth every Yen. Thanks to the developers for doing innovative things in a perfect setting.
Post scriptum: After finishing this game I also tried Evo Explores, a clone of Monument Valley. The difference cannot be more stunning: Evo Explores is mostly repetitive, with a focus on an irrelevant story, simple graphics, and riddles that miss the ingenuity of the original.
Let's Encrypt is a certificate authority (CA) that just
left beta stage, that provides domain
name-validated (DV) X.509 certificates for free and in an
automated way: users just have to run a piece of software on their
server to get and install a certificate, resulting in a valid TLS
setup.
A threat to other certificate authorities
By providing certificates for free and automatically, Let's Encrypt
is probably a threat a other CAs, a least for part of their activity.
Indeed, for people that are satisfied with DV certificates, there are
not many reasons to pay a commercial CA to get certificates in a
non-automated way. For the CAcert non-commercial CA, that may mean a slow death, as
this is their main activity .
For people that want organization-validated (OV) or extended
validation (EV) certificates, Let's Encrypt is not suitable, so
it will not change anything regarding that.
An opportunity for the most reactive
The entrance of Let's Encrypt is also a significant opportunity for
the certificate authorities that will be reactive enough to take
advantage of their innovation. Indeed, they introduced automation in
both domain name validation and certificate issuance (and revocation),
by defining an open
protocol that is meant to become an Internet standard. That
protocol, named ACME, is not tied to Let's Encrypt and has several free
software implementations, so it could be used for the same
purpose by commercial CAs.
A certification authority could, for instance:
Like each month, here comes a report about the work of paid contributors to Debian LTS.
Individual reports
In February, 111.75 work hours have been dispatched among 10 paid contributors. Their reports are available:
No comment Liked this article? Click here. My blog is Flattr-enabled.
Next.