Poetry, or Spam?

Βut the mοst chаrismatic wrestler of all the wогld.
The legаcy that Warrioг іѕ tryіng to releasе the
vіdeo, oг exρlοіt it, or otherwise gain frοm
the toр meant an end to аny match. With the
deсline оf barber shops mаnу men haνe
а bi-ωeеkly oг monthly aрpointmеntѕ at a
beаutу shοp.

It's a spam comment left on this blog. So random...

Two-factor authentication OpenID login

I had been wondering about this topic for a while and recently stumbled upon dynalogin which claims to do just that. I say "claims" because I haven't been able to figure out how to set it up, yet.
I get the following in journalctl: DYNALOGIN denied, insufficient tokens in query

Update: I figured it out after looking at the code for a while...
  1. In the SQL database, the password should be in plain text.
  2. When you login to the simpleID interface, concatenate your password with the 6-digit HOTP code (ex: password564325).
  3. Only HTTPS login works for me (digest doesn't)
  4. After realizing all this, it still wouldn't work until I deleted my profile in the dynalogin android app and re-created it. I'm not sure why but my uneducated guess would be the counters got out of sync
  1. Install dependencies: pacman -S --needed apr apr-util oath-toolkit unixodbc
  2. Configure: ./configure --prefix=
  3. Install: make CFLAGS+="-I/usr/include/apr-1 -D_LARGEFILE64_SOURCE" install
  4. Copy config file: cp dynalogind/dynalogin.conf /etc/
  5. Optional: add "php" after "<?" in "simpleid/dynalogin-filesystem.store.config.php"
  6. Copy php file: cp php/dynalogin.php /srv/http/chromic.org/simpleid/
  7. Follow instructions in simpleid folder: less simpleid/README.txt

    Note: point the "DYNALOGIN_PHP_DIR" variable to the directory where you copied dynalogin.php in previous step.

  8. Make sure PHP sockets are enabled in your php.ini (i.e.: uncomment the "extension=sockets.so" line)
  9. Create MySQL database and user:
    mysql -u root -p
    create database dynalogin;
    grant all on dynalogin.* to 'dynalogin'%'localhost' identified by 'password';
    exit
  10. Create MySQL table: mysql -u dynalogin -p dynalogin < libdynalogin/datasources/odbc/schema_mysql.sql
  11. There's no documentation on how to add dynalogin users, so I did:
    INSERT INTO dynalogin_user (userid, secret, password) VALUES('chimo', 'something secret', 'plain_text_password');
  12. Copy odbc configs (you may want to merge the sample files with your existing ones if you have important information in there):
    cp libdynalogin/datasources/odbc/odbc.ini-sample /etc/odbc.ini
    cp libdynalogin/datasources/odbc/odbcinst.ini-sample /etc/odbcinst.ini
  13. If you're on Arch, setup "odbcinst.ini" like the example on the Arch wiki (don't forget to create the 'libodbcmyS' symlink)

    Here are my files as an example:

    odbc.ini
    [ODBC Data Sources]
     
    dynalogin     = MySQL ODBC 3.51 Driver DSN
     
    [dynalogin]
    Driver       = MySQL
    Description  = MySQL ODBC 3.51 Driver DSN
    Server       = localhost
    Port         = 3306
    User         = dynalogin
    Password     = password
    Database     = dynalogin
    Option       = 3
    Socket       = /var/run/mysqld/mysqld.sock
    odbcinst.ini
    [MySQL]
    Description = ODBC for MySQL
    Driver = /usr/lib/libmyodbc.so
    Setup = /usr/lib/libodbcmyS.so
    FileUsage = 1
    UsageCount = 2
  14. Get the android app (f-droid market)
  15. Create a profile with the user id and the secret you've inserted in the database in step #11
  16. Tap "Get code"
  17. Login to simpleID under HTTPS with "password453245" (replace with your actual password and code, of course)

You can also find dynalogin on github.

Mediagoblin systemd Service File

Tags:

My old harddrive, on which my Mediagoblin was running, was spitting out I/O errors like crazy recently so I backed-up GMG, changed the harddrive, installed Arch on it and re-copied the GMG files over.

A new arch install means no rc.d scripts (I never bothered converting the old harddrive to systemd) which means my old mediagoblin rc.d script wasn't very useful to me anymore.

So I took the opportunity to create a systemd equivalent (reminder: I'm not using the celery stuff).
I (still) have no idea what I'm doing so usual "use at your own risk" disclaimers apply.

/lib/systemd/system/gmg.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit]
Description=Mediagoblin
 
[Service]
User=mediagoblin
WorkingDirectory=/srv/http/media.chromic.org/mediagoblin
Type=forking
ExecStart=/bin/sh -c 'CELERY_ALWAYS_EAGER=true \
             ./bin/paster serve paste.ini \
             --pid-file=/var/run/mediagoblin/mediagoblin.pid \
             --log-file=/var/run/mediagoblin/mediagoblin.log \
             --daemon \
             --server-name=fcgi fcgi_host=127.0.0.1 fcgi_port=26543'
ExecStop=/bin/sh -c './bin/paster serve paste.ini \
            --pid-file=/var/run/mediagoblin/mediagoblin.pid \
            stop'
PIDFile=/var/run/mediagoblin/mediagoblin.pid
[Install]
WantedBy=multi-user.target

The usual systemctl commands are available:

start:
systemctl start gmg
stop:
systemctl stop gmg
restart:
systemctl restart gmg
auto-start:
systemctl enable gmg
disable auto-start:
systemctl disable gmg

courier-imap and gamin

2013-03-22 Update: I've had this monit script disabled for the past few weeks and haven't ran into this problem since. Perhaps something got fixed somewhere.

I've got this weird thing going on with gamin and courier-imap where sometimes, for no apparent reason, I'll get "Connection dropped by IMAP server" after logging in. When that happens, I need to SSH in, kill gamin and I then can log in. ...Until it happens again. For no apparent reason. At random intervals.

This got annoying pretty quickly, but I don't have the energy to look into it at the moment. There are a couple of work-arounds (replacing gamin with FAM, replacing courier with dovecot, disabling the IDLE/gamin feature from courier-imap, etc.), but again: can't be bothered. I'm the only one using the server anyway.

At the same time, I've been wanting to play with monit for a while (I bet you can see where this is going now). So now I have monit setup to try to login to the mail server, and if we get an unexpected response (dropped connection, for example), it kills gamin.

It's a dirty, lazy work-around... but it works. And I've learned a few things about monit along the way.

Here's a simplified version of the script:

check process imap with pidfile /var/run/courier/imapd.pid
if failed host mail.example.org port 143
   expect ".*"                                             # Ignore announcement of supported protocols
   send "10 LOGIN user@example.org password\r\n"           # Login
   expect "10 OK LOGIN Ok.\r\n"                            # Expect ok
   send "c logout\r\n"                                     # Logout
then exec "/bin/bash -c 'killall -u vmailer gam_server'"   # Kill gamin if something didn't go right

You'll need to change the host, username and maybe the port, perhaps make it an ssl connection ("TCPSSL") and/or use a hash of your password instead of plain text, etc. All depending on how you have things setup.

Finding a proper fix is still on my todo list. I might get to it ...someday :)

Social Analytics – Rich Dialog Content

I've recently re-started to mess around with that Social Analytics SN plugin.

The main change this time is related to the dialogs. When it comes to notices, they look similar to those on a timeline (avatar, nickname, notice, timestamp, context...). Profiles now display avatars and the bio (if any).

To compare, here's what the old dialogs looked like:

Old dialog box

Old dialog box

And here are the new ones:

New dialogs for notices

New dialogs for notices

New dialogs for profiles

New dialogs for profiles

StatusNet Querycards

Tags:

Inspired by the Hovercards feature part of the StatusNet JavaScript API plugin, I wrote a small jQuery plugin that does a very similar thing.

There are two main reasons I wanted to write this:

  1. It's standalone (as long as you include jQuery on your page, of course).
    You don't need to install a StatusNet plugin on your instance, fiddle with OAuth, etc.
  2. It works with Remote Users
    Currently, the hovercards part of the JavaScript API only appear for users on the instance the plugin is installed on.

To use it, you need a link that has an @-mention as text. Then, target it or its container with jQuery:

1
2
3
4
5
6
<div class="hovercard">
  <a href="http://identi.ca/x11r5">@x11r5</a>
</div>
<script>
  $('.hovercard').SnHoverCard();
</script>

Will result in (hover your mouse over the link):

Now the next step is to tweak the code generated by EmbedNotice so that it works with Querycards.

In the meantime, you can always manually modify the HTML so that the mentions are in the proper format: <a href="http://example.com/username">@username</a>.

@cwebber Do they run on a dishwasher

As always, code's on Github.

Character Count for SN Instances with ‘any length’ Notices

Tags:

I have my StatusNet instance setup to allow notices of any length. Most of the time, however, I do try to limit my own notices to 140 characters or less (I tend to ramble needlessly otherwise).

One problem with this setup is that the web interface doesn't show the character count when there is no limit on length. This makes sense since the character count is intended to show the remaining number of characters allowed before truncation. This is suboptimal in my situation because I have to open up an external editor to view if I'm over 140 characters or not.

So I fixed it (well okay, it's more of a quick hack than a real fix, but still...). The following changes makes the textbox show the number of characters typed (instead of remaining number of characters) when there is no limit.

In /js/util.js, change this:

150
151
152
153
154
155
            if (MaxLength <= 0) {
                return;
            }
 
            var remaining = MaxLength - SN.U.CharacterCount(form);
            var counter = form.find('.count');

To this:

150
151
152
153
154
155
            var remaining = MaxLength - SN.U.CharacterCount(form);
            var counter = form.find('.count');
 
            if (MaxLength <= 0) {
                remaining = Math.abs(remaining);
            }

Then, run "make" in the "js" folder to minify the changes.
Alternatively, you can get the minified file here.

In /lib/noticeform.php change this:

218
219
220
221
222
            if ($contentLimit > 0) {
                 $this->out->element('span',
                                     array('class' => 'count'),
                                     $contentLimit);
            }

To this:

218
219
220
221
222
//            if ($contentLimit > 0) {
                 $this->out->element('span',
                                     array('class' => 'count'),
                                     $contentLimit);
//            }

You should have character count back in the notice forms. \o/ !

EmbedNotice

Tags: ,

I started working on a simple StatusNet plugin tonight that adds an icon to each notice. Clicking the icon allows visitors to get the necessary HTML to embed a notice on a webpage.

The code is on Github but I pretty much just started and not it's very polished. You have been warned ;)

Here's the extra icon on the timeline:

Timeline

Timeline

Here's the dialog with the HTML code to copy/paste:

Dialog

Dialog

Here's the result when pasted on this blog:

huh? It's only 21:00? Time for !coffee

Later!

Collapse StatusNet Threads

Tags:

A couple of days ago, I saw this:
Identica notice by laroquod saying: What I wouldn't give for a "collapse all threads in the Home timeline" command… I thought this:
challenge accepted And wrote this:

Bookmarklet

Drag this to your bookmark bar: Collapse threads

This is the human readable code for the above:

1
2
3
4
5
6
7
8
9
10
11
var elems = document.getElementsByClassName('threaded-replies');
for (var i=0; i<elems.length; i++) {
    var notices = elems[i].getElementsByClassName('notice');
    for (var j=0; j<notices.length; j++) {
        notices[j].style.display = 'none';
    }
    notices = elems[i].getElementsByClassName('notice-repeats');
    for (j=0; j<notices.length; j++) {
        notices[j].style.display = 'none';
    }
}

Spam fail

I don't normally talk about the spam I get (most of it gets flagged and I never see it -- with the occasional "Welcome to this random website, joshdude7834" slipping through) but this has to be the lamest scam attempt I've seen in months. Or maybe they're all like this and I just don't know. Either way here it is:

From: GMAIL <CorporateOffice@gmail.com>
Subject: .
Body:
Attachment: 9-28-2012.jpg

I won an iPad 2 from Google!

just... wow.

The stupidity... it hurts.