Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - kriton

Pages: [1] 2
1
Drivers / Re: new driver development.
« on: January 29, 2018, 07:15:14 PM »
Well I am not saying that a noninstrumentation approach does not work but I think instrumentation is quite general and can cope with a multitude of problems if used correctly. The perhaps canonical method for doing this is to find all loop backedges and do some sort of check on each one (perhaps have a counter) and do the same for every function entry. What is __bfc() and __efc()?

__bfc/__efc (begin/end function call).  I am asserting alarm time and maintaining an object stack (for this_object / previous_object functionality and for valid_* applies).  The loop assertion does have a counter so it's not doing a full assertion on every pass through the block.

I ended up passing a handle through the block with another user-restricted identifier (__ctx) :P

I am also thinking about adding protected/private modifiers for properties and methods to be more like other languages.

Code: [Select]
    setRouterList(data) {
        let __ctx = __bfc(this, 'setRouterList'); try { var routers = { length: 0 };
        Object.keys(data).forEach(function (id) {
            let __ctx = __bfc(this, 'undefined'); try { if (id.startsWith('*')) {
                routers[id] = new I3Router(data[id]);
                routers.length++;
            } } finally { __efc(__ctx); }
        });
        this.setProtected('routerList', routers); } finally { __efc(__ctx); }
    }

2
Drivers / Re: new driver development.
« on: January 27, 2018, 10:24:36 PM »
I am relying more and more on instrumentation.  I am now trying to use it to maintain the object stack but allowing async code makes things so messy.  I really don't want to insert an actual context reference in user code but... I need to go buy a whiteboard I think.  A method is called, the current object/method are put on a stack but if there is a context while executing that method things get messy fast.

Code: [Select]
    cmd(args, cmdline) {
        __bfc(this, 'cmd'); try { let player = thisPlayer,
            dirList = [],
            options = 0,
            flags = 0;

        for (let i = 0; i < args.length; i++) {
            __ala(); let opt = args[i];
            ...
        }
        ...
        this.removeDirectories(dirList, flags, options, cmdline); <-- bunch of async stuff
        return cmdline.complete; } finally { __efc(this, 'cmd'); } <-- __efc / getContext() may or may not get right value.

Such a headache!

3
Drivers / Re: new driver development.
« on: January 20, 2018, 06:15:19 PM »
V8 itself uses multiple threads but script isolates are not.  V8 may execute multiple isolates, though, but as the name suggests they don't interact.

I decided to instrument scripts in the pipeline for now (seems like an easier solution since tripwire requires a native binary on each platform).

Code: [Select]
        while (true) {
            write(`x = ${x++}`);
        }

Transpiles into:

Code: [Select]
        while (true) {
            __ala(); write(`x = ${x++}`);
        }

__ala (assert loop alarm) and __afa (assert function alarm) are protected identifiers.  Trying to redefine them in a module will also throw an error.


4
Drivers / Re: new driver development.
« on: January 15, 2018, 04:29:07 PM »

https://github.com/tjanczuk/tripwire/tree/master/src

I've managed to get rid of the non-stop exceptions but still haven't figured out why Isolate::IsExecutionTerminating() remains false.  I really need to figure out how to enable debugging in VS so I can step into the C++.

5
Drivers / Re: new driver development.
« on: January 15, 2018, 03:52:19 AM »
I ran into a snag with tripwire not working as expected.  I am trying to get it working the way I want but my C++ is a bit rusty.

> eval while(true);
Command exceeded max execution time.
> You encountered an error:Max execution time exceeded.
    at :1:38
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)

(it keeps throwing exceptions though and doesn't yet resume the original thread).

6
Drivers / Re: new driver development.
« on: December 31, 2017, 06:52:58 AM »

I am definitely more worried about in-game users getting access to the filesystem outside the scope of the mudlib.  Mudlib development has lagged behind a bit but I hope to have the dev version of the lib up in the next couple of days.  Node makes things a bit trickier if you allow async calls.  An async write callback stack will not include the callstack entries that triggered the write in the first place so all such operations need to be handled in the driver so the context can be created and restored when the callback fires.

[Today I wrote 'ed' for telnet clients... or most of it... I am pretty proud of my little line editor so far ;-) https://github.com/kristianoye/kmud/blob/master/src/features/MUDEditor.js]

The security model is stack-based so each object on the stack is checked to ensure it has access to perform the operation so when I type "rm /log/errors/kriton"

The rm command calls efuns.rm(file) which calls driver's validWrite() which generates a list of objects to check based on the stack (/sys/cmds/creator/Rm, /v/sys/data/creators/k/kriton).  The driver then calls the validWrite() apply in the driver for each object.  If any one of the objects fails the check then the entire operation fails.

Code: [Select]
> ed /log/test.log
Starting editor.
*               This is a test.
*       .
[/log/test.log]*: w
You encountered an error.
Error: Permission denied: /log/test.log
    at EFUNProxy.writeFile ([driver]\EFUNProxy.js:1035:19)
    at EditorInstance.writeFile ([driver]\features\MUDEditor.js:519:20)
    at EditorInstance.executeCommand ([driver]\features\MUDEditor.js:280:37)
    at EFUNProxy.efunPrototype.(anonymous function) [as editorCmd] ([driver]\features\MUDEditor.js:585:42)
    at executeEditor (/base/Interactive.js:73:44)
    at CreatorWrapper.processInput (/base/Interactive.js:239:34)
    at CreatorWrapper.preprocessInput (/base/Creator.js:156:25)
    at CreatorWrapper.preprocessInput (/v/sys/data/creators/k/kriton:13:51)
    at MUDStorage.Interactive.$storage.prependListener (/base/Interactive.js:285:25)
    at MUDStorage.emit ([driver]\MUDEventEmitter.js:31:34)

Exceptions are also tricky since Node does not give you a means to intercept creation of errors at the source.  I have logic to scrub the external filesystem from most errors but someone can just do a try ... catch and display the error to get the native path.  Having the native path should not gain you much but it is more than I like.  I might just disallow exception handling in the compiler and force users to rely on the driver-based exception handler and reporting.

7
Drivers / Re: new driver development.
« on: December 27, 2017, 01:52:41 AM »
The mudlib is designed to be very MudOS like btw.  There is a file hierarchy just like any LP mud.  Each creator will have their own realm.  There are domains, special directories for commands and verbs, etc.  The MUD starts, creates the master object and simul efun object and applies optional packages (domain stats, verb support, etc).  Once initialization is done the master objects and efuns are sealed.  The game optionally does the eplog/pre-loading like MudOS and opens the configured ports.

The mudlib objects should only have access to the external functions provided by the loader and efun proxy (e.g. no direct access to the compiler or the module cache).

8
Drivers / Re: new driver development.
« on: December 27, 2017, 01:24:03 AM »
Each distinct type is created in its own sandbox.  The sandbox has an efun "proxy" which is imprinted with the filename and permissions inherent to that file.  The proxy performs security checks and passes valid requests through to the underlying external function object that does the sensitive stuff like reading files, writing files, accessing the network, etc.  Once the object is created in the sandbox then it is made available to the game.  Objects can import references to existing objects, though (permissions permitting).  This allows for inheritance, etc.

I have found and fixed one security issue already, though.  You could replace applies in the master object at runtime by altering the master's prototype (e.g. master().constructor.prototype.validRead = function() { return true; }).

The master objects and efun objects are frozen just before the game enters the running state now to prevent such a hack, now.

9
Open Chat / Re: Merry Christmas and a happy New Year!
« on: December 25, 2017, 06:25:40 AM »

Yar Merry Christmas!

10
Drivers / Re: new driver development.
« on: December 21, 2017, 03:58:04 PM »
Also worth noting: Object instances do not hold their data directly.  Each object instance has a storage object contained within the driver that they access.  The driver also uses the storage object to send important signals to the object instance via events (body switches via exec(), user input from the client, etc, are passed this way).  The storage object is only in scope within the constructor chain and again during create() so the object can wire up events.

11
Drivers / Re: new driver development.
« on: December 21, 2017, 03:27:02 PM »
I noticed there is some code in your repo for two transpilers. I do have a question and perhaps a suggestion of sorts but I am not sure I know javascript well enough to understand exactly what I am reading.

1). Is there a distinct mud library/driver code distinction in the code or is it more like a diku? If so, does the transpiler for the mudlib portion support security instrumentation?

There is a distinction between the mudlib code and the driver.  The driver is loaded in Node's native context and mudlib objects are compiled and instantiated in a vm sandbox context.  The driver has access to system resources but mudlib objects should only have access to the resources the driver provides to the sandbox (efuns, etc).  I am curious to see if some brilliant hacker can break out of the sandbox.  Hopefully the Node developers made it fairly fool-proof.

Is there some specific security concern you think I should worry about?  The current security model is heavily influenced by MudOS/FluffOS.  Regardless of which pipeline is used to create an object the resulting code can only access the mud resources through the efuns object.  Reads, writes, shutdown requests, exec, etc, all perform stack-based checks against the driver + in-game master object applies.  Oh, I should mention that important security tokens like filename, instanceId, etc, are baked and sealed into the object when they created and in theory cannot be changed.

2) If the CPU is a resource does the instrumentation check for too long executions in case of infinite loops and too deep recursions? Or is there some other means of handling this with node.js?

I currently have a max execution time on object creation but I need to add one for initial compiling as well.  I also need to add support for max command execution time and throttling to limit commands/second for any given object.  I am using a module called Tripwire to try and prevent malicious code like while(true);

3) There seems to be some preliminary LPC support added perhaps a week ago or so as well. I was thinking about doing something similar but I was a bit uncertain about how to best do this in ecmascript 6. I suspect writing this is some work.

The LPC to JS transpiler is on my to-do list but not a high priority for me.  I lost my original MUD to bad DVD media (10,000+ hours down the drain).  The LPC support is currently limited to the module I created to handle MUD socket communication for Intermud support (although I suppose it could be used to read object files, too).  The only real compat buster so far relates to how virtual objects are created.  MudOS returns an object instance and applies filename, etc, to the resullt.  In this driver the master can only tell the driver HOW to create the object (the master provides a filename to instantiate and initialization data and the driver then creates the object).

12
Drivers / Re: new driver development.
« on: December 17, 2017, 08:23:47 PM »

I am still on-track to release a Node.js "driver" / mudlib by the end of the year.  The mudlib itself is lagging behind a bit as I have spent much of my time tweaking the driver (still have to write combat logic, etc).  I would not recommend spending too much time on it yet (although git makes it really easy to keep in sync with dev).

https://github.com/kristianoye/kmud

Features:

* MudOS compatibility mode.  This will import virtually every efun name from MudOS/FluffOS into an object's context when loading (e.g. load_object, etc).  There is a master() object and simul efuns.  Objects can be re-loaded during runtime and have immediate effect.

* Extensible compiler pipeline.  Easy to add support for new transpilers (e.g. typescript and possibly LPC).

* Focus on web-based clients but with support for legacy/telnet clients (including GMCP... although I have never used this telnet extension).

* Included web client provides Monaco editor, visual file explorer, etc (still lots of work left to do here).

13
General / Re: My Renewed Interest in LPMud stuff
« on: December 07, 2017, 01:27:04 AM »

I am adding plug-able support for transpilers to my Node-based MUD.  I just added my first instance (.jsx) to allow more natural development targeting web clients.  Going from JS-like to JS is pretty easy, though. I am curious to see how well an LPC transpiler would work.

Code: [Select]
   webcmd(args, cmdline) {
        var players = users(),
            count = players.length;

        var result =
        <div className="who-results">
            <table>
                <thead>
                    <tr>
                        <td>There are currently {count} player(s) on {mud_name()}</td>
                    </tr>
                </thead>
                <tbody>
                {
                    players.map((player, i) => {
                        var lvl = player.getLevel(), status = [], color = '';
                        if (adminp(player))
                            lvl = 'ADMIN', color = 'purple';
                        else if (archp(player))
                            lvl = 'ARCH', color = 'blue';
                        else if (wizardp(player))
                            lvl = 'WIZARD', color = 'green';
                        else
                            lvl = player.getLevel();

                        if (player.idleTime > 60)
                            status.push('idle');
                        else
                            status.push('active');

                        var row = <tr style={color}>
                            <td>{lvl}</td>
                            <td>{player.getTitle()}</td>
                            <td>{status.join(',')}</td>
                        </tr>;

                        return row;
                    })
                }
                </tbody>
            </table>
        </div>;

14
General / Re: Popular Mud Clients?
« on: December 07, 2017, 01:12:37 AM »

Anyone use Pueblo back in the day?  It was cool for the time but I doubt it would hold up now!

15
General / Re: My Renewed Interest in LPMud stuff
« on: December 04, 2017, 04:17:55 AM »

I'll definitely be curious to see how your driver dev goes and will have to check it out when you release it. My client is probably a couple years away from being "ready" (especially since I've been spending the bulk of my time on lib dev this year.)

I hope to have a very basic mudlib up by the end of the month.  I am still debating on how LP like to make it.  I guess I could make compatibility a configurable option (e.g. populate global namespace with LP methods like master(), this_player(), etc).

Objects are defined much the same way, complete with create(), init(), and reset() applies.  I could probably write a transpiler to convert LPC to JavaScript :P

Debugger listening on [::]:5858
vEthernet (DockerNAT) 10.0.75.1
Ethernet 4 192.168.1.216
vEthernet (Internal Switch) 192.168.1.229
Bootstrapping in-game master
Adding http port 8080
Adding http port 8888
Adding telnet port 8000
Starting Emerald MUD
Extending EFUNS
Creating preloads...
Exporting ChatChannel
        Preload: /sys/daemon/PlayerDaemon: [OK]
Exporting GameObject
        Preload: /base/Interactive: [OK]
        Preload: /sys/lib/Login: [OK]
        Preload: /daemon/I3Router,[object Object]: [OK]
        Preload: /sys/lib/CommandShell: [OK]
        Preload: /sys/daemon/FileIndex: [OK]
        Preload: /sys/daemon/CommandResolver: [OK]
        Preload: /daemon/ChatDaemon: [OK]
        Preload: /base/GameObject: [OK]
        Preload: /base/Container: [OK]
        Preload: /base/Body: [OK]
        Preload: /base/Living: [OK]
        Preload: /base/Player: [OK]
        Preload: /base/Creator: [OK]
        Preload: /base/Command: [OK]
        Preload: /base/Room: [OK]
        Preload: /daemon/I3Daemon: [OK]
Done with startup
Startup took 0.233 seconds [233 ms]
I3 Router is running on 192.168.1.216 8787

Pages: [1] 2