« back to projects source on github license: GPL-2.0 Open Source

mooproxy

A smart proxy for MUD/MOO connections.

Preface

Please note that mooproxy has been unmaintained since 2011.

I'm not aware of any serious bugs, and I expect it to still work fine, but who knows.

Also please be aware that it is a network service written in C, the language of buffer overflows. At the time, I took great care to make the network code secure, but I offer no guarantees.

Finally note that the password hashing uses single-pass MD5, which is considered inadequate today.

About

Mooproxy is a smart proxy for MUD/MOO connections.

Mooproxy acts a layer between your MUD/MOO client and a MUD/MOO server, as shown below:

MUD/MOO client  <---->  Mooproxy  <---->  MUD/MOO server

The intention is that the proxy remains connected to the server, even if you disconnect your MUD/MOO client, for example, if you shutdown your computer, take your laptop to a different place, or have network problems.

Mooproxy also provides centralised logging, which is useful if you use multiple MUD/MOO clients.

Manual compiling and installing

First, you can edit the Makefile to change some options (like installation path and compiler flags), if you want to.

Next, to compile mooproxy, simply run

make

in the source directory. You need a working C compiler, and the development libraries for libc. Mooproxy also uses some functionality that may not be present on all Unices; see Portability.

You can install by running

make install

This will install the mooproxy binary (by default in /usr/local/bin), and the manpage (by default in /usr/local/share/man/man1). Alternatively, you can install by simply copying the mooproxy executable to a suitable place, such as /usr/local/bin or ~/bin. Mooproxy requires no other files (except configuration files) to run.

Installing the Debian package

Currently, an i386 Debian package is provided. You can install it with

dpkg -i mooproxy_<version>.deb

Creating a Debian package

You can create your own Debian package as well (for another architecture, for example). Follow the following steps:

The Debian package (and some other files) will be generated in the top-level mooproxy-<version> directory.

Using

Running mooproxy is simple, just invoke it like this:

mooproxy -w <wld>

where <wld> is the name of the world. Mooproxy will use the configuration file ~/.mooproxy/worlds/<wld>. See ExampleConfig for an example configuration file. The ExampleConfig file contains all configurable options, and the settings in ExampleConfig are exactly the same as the builtin defaults in mooproxy.

Mooproxy accepts commands to change a lot of its behaviour run-time. When connected to mooproxy, do /help for a brief list of commands.

Authentication

There are two situations in mooproxy that require authentication;

Mooproxy uses the same authentication string for both. In the configuration file for the world, you should put a MD5 hash of the authentication string. When the client connects to mooproxy, the client or the user supplies the authentication string to mooproxy. Mooproxy hashes the authentication string from the client, compares it to the stored MD5 hash, and if they match, the client is accepted.

At this point, mooproxy stores the literal authentication string received from the client in its memory. When mooproxy logs in to the server (for example, because autologin is enabled), mooproxy uses this literal authentication string to authenticate itself to the MUD/MOO server.

The MD5 hash can be created with the following command:

mooproxy --md5crypt

An example scenario. Assume the MUD/MOO server expects connect <username> <password>, and your MUD/MOO client sends connect Gandalf Shire.

Now, run the following command:

mooproxy --md5crypt

When mooproxy asks for your authentication string (it will ask twice, to save you from typos), you should enter:

connect Gandalf Shire

Mooproxy will print a MD5 hash of the string, e.g.:

$1$DWuIlrlu$vjiUiV7i23jNMCpSkDzDz.

You put this string in your configuration file, like so:

auth_hash = "$1$DWuIlrlu$vjiUiV7i23jNMCpSkDzDz."

Now, when your client connects to mooproxy, it is prompted for the authentication string. If your client responds with:

connect Gandalf Shire

Mooproxy will accept the client, and store connect Gandalf Shire in its memory. Now, when mooproxy connects to the MUD/MOO server, and autologin is enabled, mooproxy sends the saved string to the MUD/MOO server, logging you in, just like your MUD/MOO client would without mooproxy in the middle.

To change the authentication string from within mooproxy, you must also provide the old literal authentication string, like this:

/set auth_hash <new hash> <old literal>

So, continuing the example scenario above, if you change your password to Mirkwood, you must run mooproxy --md5crypt to generate a MD5 hash of the new authentication string:

$ mooproxy --md5crypt
Authentication string: connect Gandalf Mirkwood
MD5 hash: $1$PzGmXA.I$qmZomnNK2gBW6tR8iTJLA/

You can then set the new hash like this:

/set auth_hash $1$PzGmXA.I$qmZomnNK2gBW6tR8iTJLA/ "connect Gandalf Shire"

The MD5 hash should not be enclosed in quotes. It is recommended to enclose the old literal in quotes, to remove ambiguity. After changing auth_hash from within mooproxy, mooproxy no longer has a literal authentication string. Therefore, autologin will not work until you re-authenticate to mooproxy (for example, by disconnecting your client, and connecting again).

MCP

MUD/MOO servers and clients may use the MUD/MOO Client Protocol (MCP) to exchange some information out-of-band. Common uses include periodically showing a tip or something else in a status bar, or maintaining a userlist on the client. For more information, see http://www.moo.mud.org/mcp/index.html.

MCP is a stateful protocol; it has to be initialised and maintained properly. When a MUD/MOO client connects to the MUD/MOO server, it expects to setup a MCP session. Consider the following scenario:

Now, from the perspective of the MUD/MOO server, a MCP session still exists, but the client cannot continue this old session (due to a lack of information on the client). So the MCP session needs to be torn down and rebuilt.

Because Standard MCP doesn't provide a mechanism to re-initialise the MCP session, a MCP package has been created for this purpose. The package is called dns-nl-icecrew-mcpreset. More information can be found in mcpreset.html.

Mooproxy uses the server MCP reset. When a client connects to mooproxy, and mooproxy is already connected to a MUD/MOO server, mooproxy sends a MCP reset command to the MUD/MOO server:

#$#dns-nl-icecrew-mcpreset-reset <mcpkey>

When the MUD/MOO server receives this message, it should terminate the current MCP session for the client, and start a new one by sending the MCP handshake. Mooproxy then relays this handshake to the newly connected client, which will respond, and a new MCP session will be set up.

If working MCP is desired, mooproxy can only be used with MUD/MOO servers that support dns-nl-icecrew-mcpreset-reset.

/recall

In mooproxy 0.1.3, the recall command has received a significant update. If you invoke the recall command with just a number, it will recall that number of lines in their full glory, just like before:

/recall 50

But now recall supports the following syntax as well:

/recall [from <timespec>] [to <timespec>] [search <text>]

This will recall any lines matching <text> in the period from <from timespec> to <to timespec>.

A timespec is one or more of the following:

now
   Sets the time to the current date and time.
today
   Sets the time to 0:00 today.
yesterday
   Sets the time to 0:00 yesterday.
last/next monday/tuesday/...
   Next <weekday> sets the time to 0:00 of the first <weekday> from today.
   Last <weekday> sets it to 0:00 of the last <weekday> before today.
[YY/]MM/DD
   Set the time to 0:00 of the given day.
   If no year is specified, use MM/DD within the current year.
HH:MM[:SS]
   Set the time to HH:MM within the current day.
   If seconds are not specified, set them to 00.
-/+ <number> seconds/minutes/hours/days
   Change the time to be <number> <units> earlier or later.
-/+ <number> lines
   Search in <number> lines before/after <from timespec>.

Notes:

Examples. Assume the current date and time are Wed Aug 22, 20:42:11.

Recall all lines between 10:00:00 and 11:00:00 today:

/recall from 10:00 to 11:00

Recall all lines from 10:00 to 11:00 yesterday:

/recall from yesterday 10:00 to 11:00

Search the last half hour for any lines containing "yes" before "play":

/recall from -30 mins search yes.*play

Recall 50 lines after 10:00:00 today:

/recall from 10:00 to +50 lines

Recall the last 80 lines:

/recall to -80 lines

Recall everything from Mon 20/08 00:00 to Wed 22/08 00:00:

/recall from last monday to today.

Recall everything from Sat 18/08 00:00 to Mon 20/08 00:00:

/recall from last saturday to next monday

Recall from 11:35 to 12:35 the wednesday after 22/04 (a sunday):

/recall from 04/22 next wed 11:35 to +1 hour

When you invoke recall, it will first report what it is going to recall, so you can check if recall will actually inspect the lines you intended it to inspect:

% Recalling from Wed 2007/04/25 11:35:00 to Wed 2007/04/25 12:35:00.

Then it will produce the matching lines, with all colours stripped. Finally, it will report how many lines it considered:

% Recall end (X / Y / Z).

Here, X is the number of lines mooproxy has in its history. Y is the number of lines that matched the time criteria (i.e. from and to). Finally, Z is the number of lines actually recalled (i.e. that matched the time criteria and search criteria).

Logfiles change from 0.1.1 to 0.1.2

In mooproxy 0.1.2, the logging was changed to log into a nested hierarchy of directories, instead of all files in a single directory.

Mooproxy versions older than 0.1.2 log like this:

logs
|-- world one - 2007-01-01.log
|-- world one - 2007-02-01.log
|-- world two - 2007-02-01.log
|-- world two - 2007-03-01.log
|-- world two - 2007-03-02.log
`-- world two - 2007-03-03.log

Mooproxy 0.1.2 and later log like this:

logs
|-- world one
|   |-- 2007-01
|   |   `-- world one - 2007-01-01.log
|   `-- 2007-02
|       `-- world one - 2007-02-01.log
`-- world two
    |-- 2007-02
    |   `-- world two - 2007-02-01.log
    `-- 2007-03
        |-- world two - 2007-03-01.log
        |-- world two - 2007-03-02.log
        `-- world two - 2007-03-03.log

To move any existing logs from the old layout to the new layout, use the update-logs.sh that's provided with mooproxy 0.1.2 (in the Debian package, the shell script resides in /usr/share/doc/mooproxy).

Please make a backup of your current logfiles before running this script.

Portability

Mooproxy is designed to run on modern Unices, most notably GNU/Linux and the open source BSD variants. Mooproxy is written in ANSI C, using mostly POSIX-defined systemcalls. This section documents the additional requirements for mooproxy.

As of this writing, mooproxy is tested on Debian Unstable with Linux 2.6.

Portability pitfalls:

Copyright, license, acknowledgements

Mooproxy is copyright 2001-2011 Marcel Moreaux.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 dated June, 1991.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Thanks (for testing, reporting bugs, and suggestions) to:

Further information