Shirish Agarwal: Mausaji, Samosaji

Mausaji, Never born Never died, Always in the heart.
Filed under: Miscellenous Tagged: #antics, #growing up, #holidays, #Manish Bhiaya, #Mausaji, #Sangram Colony

Mausaji, Never born Never died, Always in the heart.
| Series: | The Belgariad #2 |
| Publisher: | Del Rey |
| Copyright: | November 1982 |
| Printing: | March 1992 |
| ISBN: | 0-345-33565-1 |
| Format: | Mass market |
| Pages: | 322 |
I got tired of manually fetching installation images via either FTP or by manually transferring files to z/VM to test s390x installs. Hence it was about time to automate it. Originally I wanted to instrument an installation via vmcp from another instance on the same host but I figured that I cannot really rely on a secondary instance when I need it and went the s3270/x3270-script way instead.- unpacked the tarball
- installed the rpm from the "packages" folder
zypper install cnijfilter-common-3.70-1.x86_64.rpm cnijfilter-ip100series-3.70-1.x86_64.rpm
... and choose to ignore the missing file dependency on libtiff.so.5.
ln -s /usr/lib64/libtiff.so /usr/lib64/libtiff.so.5
- re-ran the ./install.sh which registered the printer with cups and does whatever else
magic is included in 1906 lines of shell.
To my surprise this driver still works and provides the expected quality. Though it's just
a question of time until this setup will break. Be it an incompatible ABI change in libtiff
or another lib in use by those Canon provided tools.
QGIS and gdal with ECW support
While the printer stuff is a rather common use case, having a map viewer for map files in the
ECW format is the eccentric
part. I found some hints on stackoverflow and subsequently
https://trac.osgeo.org/gdal/wiki/ECW
that a non-free library is required and a specific build of gdal.
Then QGIS should be able to work with ECW files. Lucky us there
is at least a OpenSuSE repository for gdal and QGIS. So I did the following:
zypper addrepo http://download.opensuse.org/repositories/Application:/Geo/openSUSE_Leap_42.2/Application:Geo.repo
zypper install qgis
Then I had to download the non-free ECW SDK from http://download.hexagongeospatial.com/downloads/erdas-ecw-jp2-sdk-v5.3-%28linux%29 - you'll and up with a '.bin' installer file. The installation process
left me with "ERDAS-ECW_JPEG_2000_SDK-5.3.0" folder in my $HOME. I moved that one to /opt. Next
step is adding the library to the ldconfig search path.
echo "/opt/ERDAS-ECW_JPEG_2000_SDK-5.3.0/Desktop_Read-Only/lib/x64/release/" > /etc/ld.so.conf.d/ecw.conf; ldconfig
Now it was "just" about rebuild gdal with ECW support. So I downloaded the required source packages
with "zypper source-install gdal", edited the spec somewhere in "/usr/src/" to make the following
modifications
--with-ecw=/opt/ERDAS-ECW_JPEG_2000_SDK-5.3.0/Desktop_Read-Only
added to the "./configure" invocation. And somewhere at the top we had to relax the
requirement that all installed files have to be referenced inside the package.
%define _unpackaged_files_terminate_build 0
As a last step I had to "rpmbuild -ba" the package and force the installation via zypper
once more, because this time we have a file depedency on the libecw stuff and it's obviously
not listed in the rpm database. Last but not least I tried to put the gdal build on hold with
zypper addlock gdal libgdal20
to ensure it's not removed on the next update.
Other non-free tools
Beside of those two issues I had to install a range of other non-free tools, but currently
they work without further issues or modifications. One is Teamviewer (i686 multiarch rpm) and
the other one is XnViewMP. XnView is also able to show ECW files, but only the smaller ones.
It crashes on bigger ones but that's also the case on Windows. Then there is also (required
by some Italian map related websites) the ugly Adobe Flash Plugin for Firefox, but that one
is sadly still a widespread issue. We also tried to try out the nvidia graphic drivers but
at the moment we could only get the build in Intel card to work. Usually the preferred solution
from my point of view but sometimes we see rendering glitches and I'm not sure if it's the
driver or something else.
my personal take away
I hate to admit it but it's nothing extraordinary that was requested here. But still
it took me the better part of two evenings to figure everything out. And even now it's
not properly integrated and doomed to fail any day due to various updates and changes
in the surounding ecosystem. I've full sympathy for every average user that would give
up after two hours of research and try&error on this journey.
For the printer drivers I'm happy to blame Canon. The printer situation as a whole
improved from my point of view during the last decade, but it's still a pain in the
ass with the very short shelf life you usually see with consumer models.
For the ECW case one could discuss if it would be legally possible and helpful to do
ugly dlopen() stuff to dynamcially load the shared libs. But then again someone has
to make his hands dirty during the build and discussions about the legal use of header
files will be the next chapter (hello Oracle). It's just ugly. Actually I know too little
about the world of image formats to judge if someone has a good reason to keep this
format commercial or not. From my personal point of view it's not useful and maybe
even morally wrong.
Technically one could argue if it would make sense to keep a local copy of the
gdal build in "/opt" and start QGIS with a modified library path to prefer the
private gdal build. Not sure if that is any better.
On the other hand there are evolving mechanism like flatpack that would ease the handling of
such situations. Buth then again we would be catering non-free software. It feels a lot
like giving up.
While my private working environment is except for firmware blobs free, I now created
for someone a real "FrankenSuSE" to satisfy his everyday needs. On the one hand we
now have another mostly satisfied user of a mostly free operating system. On the other
hand that was only possible by adding a vast amount of non-free software. For sure
we did not win the war, I'm not even sure if we've won a single battle here. It's
just frustrating to see what is required to get someone up and running. With my personal
attitude towards open source software it even feels wrong to invest so much time into
fiddling with non-free components.
What is still missing
We currently lack an image viewer that allows us to print only a selection of
an image, which is useful to print parts of a map. That usually works with XnView
on Windows but does not work with the Linux version at the moment. I also tried gwenview
and geeqie and had the same issue. Not sure if it's maybe a bug in XnView or one of the
Qt parts (gwenview is also Qt based). I did not research that yet.
Update: I spent quite some time looking into open bug reports for geeqie and gwenview.
Seems the feature to print only a section of an image is something new. I've created
#374299 (gwenview) and
#457 (geeqie).
For XnView I expect it's a difference between XnViewMP (the portable version) and
the Windows only XnView Classic. Needs to be clarified and it might be worth to try
XnView Classic with wine. Maybe printing with wine via cups works, I found at least
some results for it on the internet.
.buildinfo files for Stretch as Debian will not rebuild its source packages and because these binary packages currently in the archive were mostly built with dpkg > 1.18.11.
reprepro/5.0.0-1 has added support for dealing with .buildinfo files
that are included in .changes files. (Closes: #843402)
Reproducible work in other projects
The Chromium project is now working on making their build process (mostly)
deterministic.
Their motivation is to save both "[money] (less hardware is required) and
developer time (reduced latency by having less work to do on the TS and CI)".
Unreproducible bugs filed
arm64 architecture.
arm64 machines with 64GB memory, which allows us to rebuild Debian very fast!
The year 2016, which is about to end, has been full of work and contributions
to the FLOSS comunity.
Most of my focus goes to two important projects: Debian and Netfilter.
This is no coincidence, since my main interests in the IT world are
systems and networks.
Some numbers (no exhaustive count):
| Series: | The Belgariad #1 |
| Publisher: | Del Rey |
| Copyright: | April 1982 |
| Printing: | August 1990 |
| ISBN: | 0-345-33551-1 |
| Format: | Mass market |
| Pages: | 258 |
You may have noticed (but you probably did not), but on 2017-02-04, at
14:00, in room UB2.252A (aka "Lameere"), which at that point in time
will be the Virtualisation and IaaS devroom, I'll be giving a talk on
the Network Block Device protocol.
Having been involved in maintaining NBD in one way or another for over
fifteen years now, I've never seen as much activity around the concept
as I have in the past few years. The result of that has been that we've
added a number of new features to the protocol, to allow it to be used
in settings where it was not as useful or as attractive as it would have
been before. As a result, these are exciting times for those who care
about NBD, and I thought it would be about time that I'd speak about it
somewhere. The Virtualisation/IaaS devroom seemed like the right fit
today (even though I wouldn't have thought so a mere two years ago), and
so I'm happy they agreed to have me.
While I still have to start writing my slides, and therefore don't
really know (yet) exactly what I'll be talking about, the
schedule
already contains an outline.
See you there?
dzil authordeps or dzil listdeps to list dependencies.dzil authordeps --missing cpanm dzil listdeps --missing cpanmOn a Debian system, one may prefer to install Perl modules using Debian packages. Installing build dependencies can be done with
apt build-dep, but apt does not handle Dist::Zilla author dependencies.
The new authordebs Dist::Zilla sub-command was wriiten to fill this gap. When run in a directory containing the source of a Perl module that uses Dist::Zilla, you can run dzil installdebs to list the Debian packages required to run the dzil command. You can also run dzil installdebs -install to install author dependencies (using sudo under the hood).
See:
On Debian, authordebs is provided by libdist-zilla-app-command-authordebs-perl
All the best
While learning about and configuring weechat this evening, I noticed a lot
of complexity and unsatisfying tradeoffs related to its UI, its mouse
support, and its built-in window system. Got to wondering what I'd do
differently, if I wrote my own IRC client, to avoid those problems.
The first thing I realized is, it is not a good idea to think about
writing your own IRC client. Danger will robinson..
So, let's generalize. This blog post is not about designing an IRC client,
but about exploring simpler ways that something like an IRC client
might handle its UI, and perhaps designing something general-purpose that
could be used by someone else to build an IRC client, or be mashed up with
an existing IRC client.
What any modern IRC client needs to do is display various channels to the
user. Maybe more than one channel should be visible at a time in some kind
of window, but often the user will have lots of available channel and only
want to see a few of them at a time. So there needs to be an interface for
picking which channel(s) to display, and if multiple windows are shown, for
arranging the windows. Often that interface also indicates when there is
activity on a channel. The most recent messages from the channel are
displayed. There should be a way to scroll back to see messages that have
already scrolled by. There needs to be an interface for sending a message
to a channel. Finally, a list of users in the channel is often desired.
Modern IRC clients implement their own UI for channel display, windowing,
channel selection, activity notification, scrollback, message entry, and
user list. Even the IRC clients that run in a terminal include all of that.
But how much of that do they need to implement, really?
Suppose the user has a tabbed window manager, that can display virtual
terminals. The terminals can set their title, and can indicate when there
is activity in the terminal. Then an IRC client could just open a bunch of
terminals, one per channel. Let the window manager handle channel
selection, windowing (naturally), and activity notification.
For scrollback, the IRC client can use the terminal's own scrollback
buffer, so the terminal's regular scrollback interface can be used. This is
slightly tricky; can't use the terminal's alternate display, and have to
handle the UI for the message entry line at the bottom.
That's all the UI an IRC client needs (except for the user list), and most
of that is already implemented in the window manager and virtual terminal.
So that's an elegant way to make an IRC client without building much new UI
at all.
But, unfortunately, most of us don't use tabbed window managers (or tabbed
terminals). Such an IRC client, in a non-tabbed window manager, would be a
many-windowed mess. Even in a tabbed window manager, it might be annoying
to have so many windows for one program.
So we need fewer windows. Let's have one channel list window, and one
channel display window. There could also be a user list window. And there
could be a way to open additional, dedicated display windows for channels,
but that's optional. All of these windows can be seperate virtual
terminals.
A potential problem: When changing the displayed channel, it needs
to output a significant number of messages for that channel,
so that the scrollback buffer gets populated. With a large number of lines,
that can be too slow to feel snappy. In some tests, scrolling
10 thousand lines was noticiably slow, but scrolling 1 thousand lines
happens fast enough not to be noticiable.
(Terminals should really be faster at scrolling than this, but they're still
writing scrollback to unlinked temp files.. sigh!)
An IRC client that uses multiple cooperating virtual terminals, needs a way to
start up a new virtual terminal displaying the current channel. It could
run something like this:
x-terminal-emulator -e the-irc-client --display-current-channel
That would communicate with the main process via a unix socket to find out
what to display.
Or, more generally:
x-terminal-emulator -e connect-pty /dev/pts/9
connect-pty would simply connect a pty device to the terminal, relaying
IO between them. The calling program would allocate the pty and do IO to
it. This may be too general to be optimal though. For one thing, I think
that most curses libraries have a singleton terminal baked into them, so it
might be hard to have a single process control cursors on multiple pty's.
And, it might be innefficient to feed that 1 thousand lines of scrollback
through the pty and copy it to the terminal.
Less general than that, but still general enough to not involve writing an
IRC client, would be a library that handled the irc-client-like channel
display, with messages scrolling up the terminal (and into the scrollback
buffer), a input area at the bottom, and perhaps a few other fixed regions
for status bars and etc.
Oh, I already implemented that! In concurrent-output,
over a year ago: a tiling region manager for the console
I wonder what other terminal applications could be simplified/improved
by using multiple terminals? One that comes to mind is mutt, which has
a folder list, a folder view, and an email view, that all are
shoehorned, with some complexity, into a single terminal.
I am sad (but feel my duty) to inform the world that we will not be providing a Drupal 8 package in Debian.
I filed an Intent To Package bug a very long time ago, intending to ship it with Jessie; Drupal 8 was so deep a change that it took their community overly long to achieve and stabilize. Still, Drupal 8 was released over a year ago today.
I started working on debianizing the package shortly afterwards. There is also some online evidence As my call for help sent through this same blog.
I have been too busy this last year. I let the packaging process lay dormant for too long, without even touching it for even half a year. Then, around September, I started working with the very nice guys of Indava, David and Enrique, and did very good advances. They clearly understood Debian's needs when it comes to full source inclusion (as D8 ships many minified Javascript libraries), attribution (as additionally to all those, many third-party PHP projects are bundled in the infamous vendor/ directory), and system-wide dependency management (as Drupal builds on some frameworks and libraries already available within Debian, chiefly Symfony, Doctrine, Twig... Even more, most of them appeared to work at the version levels we will be shipping, so all was dandy and for some weeks, I was quite optimistic on finishing the package on time and with the needed quality and testing. Yay!
But... Reality bites.
When I started testing my precious package... It broke in horrible ways. Uncomprehensible PHP errors (and I have to add here, I am a PHP newbie and am reluctant to learn better a language that strikes me as so inconsistent, so ugly), which we spent some time tackling... Of course, configuration changes are more than expected...
But, just as we Debianers learnt some important lessons after the way-too-long Sarge freeze (ten years ago, many among you won't remember those frustrating days), Drupal learnt as well. They changed their release strategy Instead of describing it, those interested can read it at its source.
What it meant for me, sadly, is that this process does not align with the Debian maintenance model. This means: The Drupal API stays mostly-stable between 8.0.x, 8.1.x, 8.2.x, etc. However, Drupal will incorporate new versions of their bundled libraries. I understood the new versions would be incorporated at minor-level branches, but if I read correctly some of my errors, some dependencies change even at patch-level updates.
And... Well, if you update a PHP library, and the invoking PHP code (that is, Drupal) relies in this new version... Sadly, it makes it unmaintainable for Debian.
So, long story short: I have decided to drop Drupal8 support in Debian. Of course, if somebody wants to pick up the pieces, the Git repository is still there (although I do plan on erasing it in a couple of weeks, as it means useless waste of project resources otherwise), and you could probably even target unstable+backports in a weird way (as it's software that, given our constraints, shouldn't enter testing, at least during a freeze).
So... Sigh, a tear is dropped for every lost hour of work, and my depeest regrets to David and Enrique who put their work as well to make D8 happen in Debian. I will soon be closing the ITP and... Forgetting about the whole issue?
I used to rely on ifupdown to
bring up my iptables firewall
automatically using a config like this in /etc/network/interfaces:
allow-hotplug eth0
iface eth0 inet dhcp
pre-up /sbin/iptables-restore /etc/network/iptables.up.rules
pre-up /sbin/ip6tables-restore /etc/network/ip6tables.up.rules
allow-hotplug wlan0
iface wlan0 inet dhcp
pre-up /sbin/iptables-restore /etc/network/iptables.up.rules
pre-up /sbin/ip6tables-restore /etc/network/ip6tables.up.rules
but that doesn't seem to work very well in the brave new
NetworkManager
world.
What does work reliably is a "pre-up" NetworkManager script, something
that gets run before a network interface is brought up. However,
despite what the
documentation
says, a dispatcher script in /etc/NetworkManager/dispatched.d/ won't
work on my Debian and Ubuntu machines. Instead, I had to create a new
iptables script in /etc/NetworkManager/dispatcher.d/pre-up.d/:
#!/bin/sh
LOGFILE=/var/log/iptables.log
if [ "$1" = lo ]; then
echo "$0: ignoring $1 for \ $2'" >> $LOGFILE
exit 0
fi
case "$2" in
pre-up)
echo "$0: restoring iptables rules for $1" >> $LOGFILE
/sbin/iptables-restore /etc/network/iptables.up.rules >> $LOGFILE 2>&1
/sbin/ip6tables-restore /etc/network/ip6tables.up.rules >> $LOGFILE 2>&1
;;
*)
echo "$0: nothing to do with $1 for \ $2'" >> $LOGFILE
;;
esac
exit 0
and then make that script executable:
chmod a+x /etc/NetworkManager/dispatcher.d/pre-up.d/iptables
With this in place, I can put my iptables rules in the usual place
(/etc/network/iptables.up.rules and /etc/network/ip6tables.up.rules) and
use the handy iptables-apply and ip6tables-apply commands to test
any changes to my firewall rules.
| Series: | Inheritance #3 |
| Publisher: | Orbit |
| Copyright: | 2011 |
| Printing: | April 2012 |
| ISBN: | 0-316-04394-X |
| Format: | Mass market |
| Pages: | 567 |
There s a pattern that comes up from time to time in the release management of free software projects.
To allow for big, disruptive changes, a new development branch is created. Most of the developers focus moves to the development branch. However at the same time, the users focus stays on the stable branch.
As a result:
Before the 2.6 series, there was a stable branch (2.4) where only relatively minor and safe changes were merged, and an unstable branch (2.5), where bigger changes and cleanups were allowed. Both of these branches had been maintained by the same set of people, led by Torvalds. This meant that users would always have a well-tested 2.4 version with the latest security and bug fixes to use, though they would have to wait for the features which went into the 2.5 branch. The downside of this was that the stable kernel ended up so far behind that it no longer supported recent hardware and lacked needed features. In the late 2.5 kernel series, some maintainers elected to try backporting of their changes to the stable kernel series, which resulted in bugs being introduced into the 2.4 kernel series. The 2.5 branch was then eventually declared stable and renamed to 2.6. But instead of opening an unstable 2.7 branch, the kernel developers decided to continue putting major changes into the 2.6 branch, which would then be released at a pace faster than 2.4.x but slower than 2.5.x. This had the desirable effect of making new features more quickly available and getting more testing of the new code, which was added in smaller batches and easier to test. Then, in the Ruby community. In 2007, Ruby 1.8.6 was the stable version of Ruby. Ruby 1.9.0 was released on 2007-12-26, without being declared stable, as a snapshot from Ruby s trunk branch, and most of the development s attention moved to 1.9.x. On 2009-01-31, Ruby 1.9.1 was the first release of the 1.9 branch to be declared stable. But at the same time, the disruptive changes introduced in Ruby 1.9 made users stay with Ruby 1.8, as many libraries (gems) remained incompatible with Ruby 1.9.x. Debian provided packages for both branches of Ruby in Squeeze (2011) but only changed the default to 1.9 in 2012 (in a stable release with Wheezy 2013). Finally, in the Python community. Similarly to what happened with Ruby 1.9, Python 3.0 was released in December 2008. Releases from the 3.x branch have been shipped in Debian Squeeze (3.1), Wheezy (3.2), Jessie (3.4). But the python command still points to 2.7 (I don t think that there are plans to make it point to 3.x, making python 3.x essentially a different language), and there are talks about really getting rid of Python 2.7 in Buster (Stretch+1, Jessie+2). In retrospect, and looking at what those projects have been doing in recent years, it is probably a better idea to break early, break often, and fix a constant stream of breakages, on a regular basis, even if that means temporarily exposing breakage to users, and spending more time seeking strategies to limit the damage caused by introducing breakage. What also changed since the time those branches were introduced is the increased popularity of automated testing and continuous integration, which makes it easier to measure breakage caused by disruptive changes. Distributions are in a good position to help here, by being able to provide early feedback to upstream projects about potentially disruptive changes. And distributions also have good motivations to help here, because it is usually not a great solution to ship two incompatible branches of the same project. (I wonder if there are other occurrences of the same pattern?) Update: There s a discussion about this post on HN
I recently needed to get access to a DataEase database; the person I helped
was the legitimate owner of the data, but had forgotten the password,
as the database was largely from 1996. There are various companies
around the world that seem to do this, or something similar (like give
you an API), for a usually unspecified fee; they all have very 90s homepages
and in general seem like they have gone out of business a long time ago.
And I wasn't prepared to wait.
For those of you who don't know DataEase, it's a sort-of relational database
for DOS that had its heyday in the late 80s and early 90s (being sort of
the cheap cousin of dBase); this is before SQL gained traction as the
standard query language, before real multiuser database access, and before
variable-width field storage.
It is also before reasonable encryption. Let's see what we can do.
DataEase has a system where tables are mapped through the data dictionary,
which is a table on its own. (Sidenote: MySQL pre-8.0 still does not have
this.) This is the file RDRRTAAA.DBM; I don't really know what RDRR stands
for, but T is the database letter in case you wanted more than one database
in the same directory, and AAA, AAB, AAC etc. is a counter so that a table
grows to be too big for one file. (There's also .DBA files for structure of
non-system tables, and then some extra stuff for indexes.)
DBM files are pretty much the classical, fixed-length 80s-style database
files; each row has some flags (I believe these are for e.g. row is
deleted ) and then just the rows in fixed format right after each other.
For instance, here's one I created as part of testing (just the first few
lines of the hexdump are shown):
00000000: 0e 00 01 74 65 73 74 62 61 73 65 00 00 00 00 00 ...testbase..... 00000010: 00 00 00 00 00 00 00 73 46 cc 29 37 00 09 00 00 .......sF.)7.... 00000020: 00 00 00 00 00 43 3a 52 44 52 52 54 41 41 41 2e .....C:RDRRTAAA. 00000030: 44 42 4d 00 00 01 00 0e 00 52 45 50 4f 52 54 20 DBM......REPORT 00000040: 44 49 52 45 43 54 4f 52 59 00 00 00 00 00 1c bd DIRECTORY....... 00000050: d4 1a 27 00 00 00 00 00 00 00 00 00 43 3a 52 45 ..'.........C:RE 00000060: 50 4f 54 41 41 41 2e 44 42 4d 00 00 01 00 0e 00 POTAAA.DBM...... 00000070: 52 65 6c 61 74 69 6f 6e 73 68 69 70 73 00 00 00 Relationships...Even without going in-depth, we can see the structure here; there's testbase which maps to C:RDRRTAA.DBM (the RDRR itself), there's a table called REPORT DIRECTORY that maps to C:REPOTAAA.DBM, and then more stuff after that, and so on. However, other tables are not so easily read, because you can ask DataEase to encrypt a table. Let's look at such an encrypted table, like the Users table (containing usernames, passwords not password hashes and some extra information like access level), which is always encrypted:
00000000: 0c 01 9f ed 94 f7 ed 34 ba 88 9f 78 21 92 7b 34 .......4...x!. 4 00000010: ba 88 0f d9 94 05 1e 34 ba 88 a0 78 21 92 7b 34 .......4...x!. 4 00000020: e2 88 9f 78 21 92 7b 34 ba 88 9f 78 21 92 7b 34 ...x!. 4...x!. 4 00000030: ba 88 9f 78 21 92 7b 34 ba 88 9f 78 21 92 7b ...x!. 4...x!.Clearly, this isn't very good encryption; it uses a very short, repetitive key of eight bytes (64 bits). (The data is mostly zero padding, which makes it much easier to spot this.) In fact, in actual data tables, only five of these bytes are set to a non-zero value, which means we have a 40-bit key; export controls? My first assumption here was of course XOR, but through some experimentation, it turned out what you need is actually 8-bit subtraction (with wraparound). The key used is derived from both a database key and a per-table key, both stored in the RDRR; again, if you disassemble, I'm sure you can find the key derivation function, but that's annoying, too. Note, by the way, that this precludes making an attack by just copying tables between databases, since the database key is different. So let's do a plaintext attack. If you assume the plaintext of the bottom row is all padding, that's your key and here's what you end up with:
00000000: 52 79 00 75 73 65 72 00 00 00 00 00 00 00 00 00 Ry.user......... 00000010: 00 00 70 61 73 73 a3 00 00 00 01 00 00 00 00 00 ..pass.......... 00000020: 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (............... 00000030: 00 00 00 00 00 00 00 00 ........Not bad, eh? Actually the first byte of the key here is wrong as far as I know, but it didn't interfere with the fields, so we have what we need to log in. (At that point, we've won, because DataEase will helpfully decrypt everything transparent for us.) However, there's a twist; if the password is longer than four characters, the entire decryption of the Users table changes. Of course, we could run our plaintext attack against every data table and pick out the information by decoding the structure, but again; annoying. So let's see what it looks like if we choose passs instead:
00000000: 0e 01 9f 7a ae 9e 21 f5 08 63 07 6d a3 a1 17 5d ...z..!..c.m...] 00000010: 70 cb df 36 7e 7c 91 c5 d8 33 d8 3d 73 71 e7 2d p..6~ ...3.=sq.- 00000020: 7b 9b 3f a5 db d9 4f 95 a8 03 a7 0d 43 41 b7 fd .?...O.....CA.. 00000030: 10 6b 0f 75 ab a9 1f 65 78 d3 77 dd 13 11 87 .k.u...ex.w....Distinctly more confusing. At this point, of course, we know at which byte positions the username and password start, so if we wanted to, we could just try setting the start byte of the password to every possible byte in turn until we hit 0x00 (DataEase truncates fields at the first zero byte), which would allow us to get in with an empty password. However, I didn't know the username either, and trying two bytes would mean 65536 tries, and I wasn't up for automating macros through DOSBox. So an active attack wasn't too tempting. However, we can look at the last hex byte (where we know the plaintext is 0); it goes 0x5d, 0x2d, 0xfd... and some other bytes go 0x08, 0xd8, 0xa8, 0x78, and so on. So clearly there's an obfuscation here where we have a per-line offset that decreases with 0x30 per line. (Actually, the increase/decrease per line seems to be derived from the key somehow, too.) If we remove that, we end up with:
00000000: 0e 01 9f 7a ae 9e 21 f5 08 63 07 6d a3 a1 17 5d ...z..!..c.m...] 00000010: a0 fb 0f 66 ae ac c1 f5 08 63 08 6d a3 a1 17 5d ...f.....c.m...] 00000020: db fb 9f 05 3b 39 af f5 08 63 07 6d a3 a1 17 5d ....;9...c.m...] 00000030: a0 fb 9f 05 3b 39 af f5 08 63 07 6d a3 a1 17 ....;9...c.m...Well, OK, this wasn't much more complicated; our fixed key is now 16 bytes long instead of 8 bytes long, but apart from that, we can do exactly the same plaintext attack. (Also, it seems to change per-record now, but we don't see it here, since we've only added one user.) Again, assume the last line is supposed to be all 0x00 and thus use that as a key (plus the last byte from the previous line), and we get:
00000000: 6e 06 00 75 73 65 72 00 00 00 00 00 00 00 00 00 n..user......... 00000010: 00 00 70 61 73 73 12 00 00 00 01 00 00 00 00 00 ..pass.......... 00000020: 3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ;............... 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............Well, OK, it wasn't perfect; we got pass\x12 instead of passs , so we messed up somehow. I don't know exactly why the fifth character gets messed up like this; actually, it cost me half an hour of trying because the password looked very real but the database wouldn't let me in, but eventually, we just guessed at what the missing letter was supposed to be. So there you have it; practical small-scale cryptanalysis of DOS-era homegrown encryption. Nothing advanced, but the user was happy about getting the data back after a few hours of work. :-)
it's amazing how many new bugs appear; luckily in the Debian Perl Group
we're not too bad at fixing them as well. here's the list of my
contributions over the last weeks:
Next.