Category Archives: Hacking

Interactive git rebase with non-interactive editing

When working with git and especially GitHub, I often have commits on my local branch that were already submitted as a pull request. Sometimes I continue working and later notice that I have commits on the branch that have nothing to do with the next thing I am already working on. Therefore I want to remove them from the current branch.

$ git log --oneline @{upstream}..
e159d1e Commit C
70140e3 Commit B
16ed14a Commit A

Let’s say I want to get rid of Commit B. The normal way would be to use git rebase -i and then tell git to remove the commit by deleting the corresponding line or replacing pick with drop, then save the file, exit the editor and let git do the rest. However, if I already know exactly what I want to do, this seems cumbersome. Therefore I came up with the following alias:

$ git config --global alias.drop '!f() { for c in "$@"; do sha1=$(git rev-parse --short $1); [ -n "$sha1" ] && git -c rebase.abbreviateCommands=false -c sequence.editor="printf \"%s\n\" \"g/^pick $sha1 /s//drop $sha1 /\" w \"g/^#/d\" \"g/^$/d\" \"%p\" q | ed -s" rebase -i --autostash; done }; f'

I admit that maybe at some point I should have changed my plan and I should have made this into a shell script instead… But this works and requires no extra files than just ~/.gitconfig.

What does it do? This alias is not a normal alias, but as indicated by the ! at the start it is supposed to be executed in a shell. As git will append all additional arguments from the command line to the end of this shell command, I turned it into a shell function to be able to handle the arguments one after another in a loop. First, the given argument is validated as a reference to a commit and the matching sha1 is retrieved. This means it can also understand HEAD~3 and similar references. If it is not valid, git will already have printed an error message. If it is valid, this runs git rebase with some special options.

The configuration option rebase.abbreviateCommands ensures that git will show us the long command name pick and not just p in the editor. But wait, there is also sequence.editor, which will be used instead of your normal $EDITOR. This is a custom command that will get a temporary filename as an argument. As the file needs to be edited in place, I chose ed for this task. Other options like sed or awk might work as well, but as far as I know there is no standardized interface for in-place editing and I want this to work with all flavors of Linux or *BSD.

ed takes a filename as argument and then reads line-wise commands from standard input that are applied to the file. I wrapped this with a printf to avoid using lots of \n in one long string or using many echo commands instead. The first command is g/re/... which will search for a line matching the given regex and execute the commands following the second slash. As a side note, the name of the tool grep comes exactly from this ed command: g/re/p, where the p stands for print. The command executed here is s/re/replacement/ which will replace the first occurrence of the regex with the given replacement. The empty string denotes the previous match. This combination of two commands is necessary to mask errors from ed. If a s// does not replace anything, ed would return an error and exit with a non-zero status code. This behavior is masked by combining it with g//, which will only try to replace on lines that already matched.

The command w will write the file to disk. Then I also wanted to get some output of the results to quickly see what’s going on. The next two g// commands will delete comments and empty lines before %p will print the whole file to standard output. Finally, the last command q tells ed to quit.

git will then take the modified file just as if it was edited in your $EDITOR and continue with the rebase. The --autosquash option is useful to automatically stash any uncommitted changes before running the rebase and then restoring them afterwards.

Now let’s finally get to removing Commit B from the example above:

$ git drop 70140e3
pick 16ed14a Commit A
drop 70140e3 Commit B
pick e159d1e Commit C
Successfully rebased and updated refs/heads/master.

Here it goes! This was an interactive rebase, but with non-interactive editing of the sequence file using ed. Setting up a similar alias for git reword to quickly edit the commit message is left as an exercise for the reader.

How to run rsync on remote host with sudo

Sometimes I want to transfer files including ownership. This is not possible as normal user as the chown(2) system call requires special privileges, that is: uid == 0. However, I do not want to open ssh access for root, but go with the usual way to elevate my privileges: sudo.

I will go through common solutions presented on the web and explain why these do not work at all without significant modifications on the remote host and then present a working solution using X11-Forwarding that is less invasive.

Continue reading

Should we distrust Comodo after issuing a rogue SSL certificate for Windows Live?

About a year ago, I wrote an article why I no longer trust StartSSL. Back then, I said I switched to a paid certificate issued by Comodo under the PositiveSSL brand instead. A reader now brought a recent issue with a Comodo certificate erroneously issued for Microsoft’s Windows Live to my attention and asked whether I would still prefer them over StartSSL.

Arno wrote this comment (link):

Do you still trust Commodo to be more trustworthy than StartCom just because they asked for money to handle revocations? Think twice – a guy from Finland managed to get a valid certificate from Commodo for “live.fi”, (Microsoft Live in Finland), just because he was able to register “hostmaster@live.fi” as his e-mail-address:

http://arstechnica.com/security/2015/03/bogus-ssl-certificate-for-windows-live-could-allow-man-in-the-middle-hacks/

I started to type my answer as a comment as well, but soon I realized my explanation just became too long to be a comment, so I turned it into an article on its own.
Continue reading

App Updates with Hidden Features

There seems to be a recent trend for smartphone apps: hidden features are shipped in app updates without mentioning the new functionality in the changelog. Only later the feature suddenly becomes active without further notice.

Recently Threema added the ability to conduct polls in a group chat. Apparently, parts of the feature were already shipped before the feature was released to everyone. I was able to answer polls on my phone running the Android app, but I was not able to create them. One could argue that maybe their app UI is so extensible that it can display anything as provided by their API. However, once I installed the next app update—mentioning the new poll feature in the changelog—the UI for polls also changed significantly. This is a clear indication that the feature has a UI part which was already included in the previous update, but was hidden from the user until announced publicly to everyone.

Similarly WhatsApp recently added their second screen solution to the popular messaging service. The menu item to scan the bar code on the WhatsApp web site suddenly appeared in my app, without any update. The next update now mentions the feature in the changelog, but apparently it was already shipped with the previous version.

I totally understand the intentions behind these hidden updates. The companies behind the apps want to enable their users to adopt new services immediately without disruption. If Threema is not able to understand a message that starts a new poll, the user will see garbage, or an error message, or a request to update the app. For WhatsApp, users would be asked to scan the bar code, but cannot find the menu item in their app. Both examples demonstrate undesirably user experience they want to avoid.

However, this means any app update might always contain a hidden feature. Something you do not see in the UI yet, but which is included in the code. No changelog mentions this new functionality and unless someone starts to decompile and inspect every app update, nobody will notice it at all. Maybe there was already a planned feature shipped with an app update once, but it was never activated? Nobody will ever know.

For me, this was on Android, where Google basically only reacts to complaints from users to remove misbehaving apps. Did they also get these new features past the app review process for iOS by Apple? They are well-known to be very harsh in their app reviews and easily reject updates not satisfying all criteria. Did these companies tell Apple about the new features before telling everyone else? Would a small company be able to pull off the same thing and ship hidden features?

For a suspicious user this is a scary situation. Maybe they don’t want to continue to use the app with the new feature? The examples above were mostly harmless, but what if the new hidden feature is something that affects your privacy? The blue ticks for read receipts in WhatsApp already caused a lot of uproar from users a few months ago. (Fun fact: as I tried to link some reference for this, I noticed this new feature was not even worth an announcement on their blog. Well, it got enough publicity, anyway).

What if an app suddenly decides to share your current location all the time? Sure, it asked for the permission to get your current location, but it was only using it for another purpose before. You agreed to allow it for the purpose you saw in the UI. Users have to be aware that everything they allow an app to access might suddenly be used for a purpose they have not seen in the UI before—and no review of the app mentioned it.

By the way, the same has already been true for web services for a long time. Updates are inherently provided by the company running the service and you cannot use the old version anymore. You would even only know about the update beforehand, if they gave you a heads-up. Are we also heading to a continuous update model for apps now? Are we just fine with unanticipated changes being applied to the apps installed locally on our devices?

This kind of problem is tied closely to closed source software, because nobody can easily verify what it actually does behind the UI. These recent examples prove one thing to me: if you want full control over what software does on your device, you have to use open source software only.

Yes, the pessimistic haters will say that I had to expect nothing else from closed source apps, anyway. But I will not give up on closed source software now. Frankly, I cannot do that without also giving up a lot of convenience and ease of use at the moment. Nevertheless, I will watch out more closely which permission I hand out to which app. Likewise you should be aware every app on your phone might suddenly use your data and information about you for something completely different, even before the app update changelog announces any new features.

The mysterious stalled scp connections

Lately, I had some problems with stalling transfers when using scp, the file transfer tool for the SSH protocol and part of the OpenSSH suite. Here is a report on what happened, how I found the cause and how I applied the solution. Actually, this is a pretty lame story, but I just wanted to write it down anyway.

Continue reading