Enable/disable plugins through the plugin menu

Posted by Shaun Biggs on Sat 02 Jun 2007 07:21 AM — 20 posts, 88,272 views.

USA #0
We have EnablePlugin function, but no quick interface on the plugin menu (ctl-shift-P). Could a button or two be added to toggle a plugin enabled or disabled? And perhaps a little flag on the far right part of the list showing if the plugin is enabled too. Sometimes I'd just like to pop open the list and turn off one of my plugins for a bit.
USA #1
If you're going to do that, you may or may not want to add OnPluginEnable and OnPluginDisable callbacks, I'm not sure if OnPluginInstall and OnPluginClose handle those events. To stop external programs or something, or in the case of my ClientLock plugin, to disconnect the world if somebody tries to circumvent the lock by disabling the plugin.
USA #2
Hmm. An interesting point here. If you want to make a plugin secure, then wouldn't you also need to have some way to tell the client, "I refuse to close!", not to mention something like, "OnPluginEdit", and even "OnPluginReload", which could return a "true" if you want to allow those events, or "false" if you don't want someone to do them?

I mean, those don't prevent someone from "manually" editing the plugin externally, or the world file or client default settings to "remove" the plugin or change its behavior, but you wouldn't be able to simply delete the plugin from the world, the default plugins *or* edit it using notepad, then reload it. As long as there exist ways to remove or reload a plugin, you haven't prevented anything by having callbacks to help you prevent them from simply disabling it. And I can imagine cases where someone might, as part of something specific to a mud, even want to use basic encryption on a plugin (or the code at least), then have as part of that code methods that prevented anyone from *hacking* it to change the behavior. In other words, if you can't remove/disable, etc. a plugin *without* permission, like a password, you could make more or less secure plugins.

Mind you.. It might be necessary to include an encrypted password in the plugin itself, and have it "auto-call" a text entry box to input and check against it, *if* you allow it. So, instead of simply refusing to unload, reload, etc., the behavior would be like:

if return == true {call allow} else {
  call password request
  if request_return == false {
    call warn_failure
  else
    call allow
  };


In other words, let people provide some "minimal" protection to a plugin, including something like the client lock, where disabling/enabling is done "only" through the stored password for that plugin.

Not perfect, since they could still decrypt the password hash, and some languages probable don't support *any* encryption of the script data (might require adding an encrypt/decrypt to the plugin load code to do it right). However, since its the working part that would be encrypted in such cases, and the password is done "through" callbacks to that working code, changes to aliases, etc. would do nothing at all, other than screw up the encrypted plugin.

Mind you, I can think of a way around that, like adding your "own" non-encrypted code block, then redirecting an alias to call that code instead, but that only works if there is no code dependencies and you know enough about how the "existing" code works to fudge changes into the plugin.

---

Anyway, point is, even with those callbacks suggested by Cage_fire_2000, there are still very simple ways to disable/change/remove the plugin causing you a problem, if you are someone trying to bypass the lock.

Oh, and to be clear, if you wanted to create such a means to secure the plugin, then you need an "OnPluginUnload", *as well as* an "OnPluginClose". Why? Because for something like ActiveX objects, close needs to release them, if you want to do things cleanly, as well as perform other functions. This means the logic needs to be:

1. OnPluginUnload - To determine **if** the plugin will let itself be unloaded in the first place.
2. OnPluginClose - To perform the tasks needed to close things down, assuming the Unload allowed it.

And of course, there needs to be logic in the client, so that closing the world itself, or the client, "won't" trigger "unload" function, or alternatively, the client needs to ignore a "do not unload me" value, if the client/world is closing and it "must" unload. Obviously, if you don't have them seperate, there is no way to deny the event without messing things up, and no separation between code you may "need" to have execute *only* if you do remove/reload it, from that which just determines "if" it should allow those things. You don't want to kill and ActiveX component, for example, if the very next act is to tell the client, "Oops! Don't unload me, I am still doing things." Its not re-executing OnPluginInstall in that case, so your ActiveX, or anything else that relies on staying loaded, until the plugin is unloaded entirely, would be lost, even though it is still needed.
USA #3
erm... that last post got a bit odd very quickly... Not allowing a plugin to be "unloaded" borders on the insane... of course a plugin should be able to be unloaded no matter what. The OnPluginDisable function would be a great idea to add for things like the client lock plugins, but I'd hate to have to explain to people why they can't just remove a plugin that they decide they don't want anymore.

If you really want to get picky about disabling plugins, just have a no_disable option (defaulting to "n") for the plugins which would stop the EnablePlugin function from working, and you would have to uninstall the plugin, tripping the OnPluginClose function. That solves all those problems with just a simple if statement or two instead of mucking about with encryption or limiting people's removal of a plugin.
Amended on Tue 05 Jun 2007 03:24 AM by Shaun Biggs
USA #4
Well, my point is that to unload/remove it, you would need to use the *same* password as you use to unlock it. In other words, its truly *secure* from tampering. It shouldn't be impossible to remove it, just not easy, if you get my meaning. As it is, with something like a client lock, preventing it from being "disabled" is useless, if you can't safeguard against them simply deleting it entirely.
Amended on Tue 05 Jun 2007 06:17 PM by Shadowfyr
USA #5
I can't see why you think plugins need to be secure at all, or even should be, given that they are insecure and untrusted by their very nature. Users should be able to remove/uninstall/disable a plugin at any time no matter what its doing.
USA #6
I'm not sure why I would want to install a plugin that would have password protections against removing it...?
Australia Forum Administrator #7
Quote:

If you're going to do that, you may or may not want to add OnPluginEnable and OnPluginDisable callbacks ...


They already exist.

See:

http://www.gammon.com.au/scripts/doc.php?general=plugin_callbacks
Australia Forum Administrator #8
Quote:

If you want to make a plugin secure ...


I don't, to be honest. As you say, you can always edit the plugin externally, so I think this is unnecessary extra complication.


Australia Forum Administrator #9
Quote:

Could a button or two be added to toggle a plugin enabled or disabled? And perhaps a little flag on the far right part of the list showing if the plugin is enabled too.


That is now implemented in version 4.08.
USA #10
Quote:
As it is, with something like a client lock, preventing it from being "disabled" is useless, if you can't safeguard against them simply deleting it entirely.

The post RIGHT before that:
Quote:
If you really want to get picky about disabling plugins, just have a no_disable option (defaulting to "n") for the plugins which would stop the EnablePlugin function from working, and you would have to uninstall the plugin, tripping the OnPluginClose function.

The SECOND post of the thread:
Quote:
If you're going to do that, you may or may not want to add OnPluginEnable and OnPluginDisable callbacks, I'm not sure if OnPluginInstall and OnPluginClose handle those events. To stop external programs or something, or in the case of my ClientLock plugin, to disconnect the world if somebody tries to circumvent the lock by disabling the plugin.


Now people can't mess with your character while you are gone. If you want everything to be really locked down, just pop open a utils.inputbox which will require a password to be entered before closing, which will disable and access to any plugin menus, but it will also halt a good deal of the program while the script is running, so you won't get any updates on the screen. The password could even be set per lock this way, so there is no chance of people grabbing it, even without encrypting the data... just wipe the variable afterwards.
USA #11
Wow, they already exist. I must've missed them when I was browsing the help file... I guess I'll have to add those to my ClientLock plugin... As for the whole stopping a plugin from unloading thing, I agree, it's insane. I can't think of any situations where you'd need to do that. In the case of my ClientLock plugin, disconnecting the world is secure enough as long as you don't save your username and password in the autoconnect screen. For any other purposes you could just say don't stop the plugin in the middle of such and such an action in the help file, that's what it's for.

My ClientLock plugin is secure enough I think. It stores the password in a local variable and not with SetVariable, so it can't be gotten with GetPluginVariable, it doesn't log the commands where the password is entered so it can't be found that way. I don't want it impossible for them to uninstall or disable my plugin, in case they forget their password, but if they do, I disconnect because only they should know the password to their character, if somebody else knows the password it defeats the purpose of the clientlock, because they could always connect from another computer or start another instance of MUSHclient or something. Encryption is silly since one of the good things about plugins is that other people can look to see how they're done and they can make their own.
Amended on Tue 05 Jun 2007 11:56 PM by Cage_fire_2000
Australia Forum Administrator #12
Quote:

If you really want to get picky about disabling plugins, just have a no_disable option (defaulting to "n") for the plugins which would stop the EnablePlugin function from working ...


A quick browse of the source shows that it should be possible to make an OnPluginDisable function, and in it, re-enable itself.

That way, the plugin can't be disabled. They can close it, yes. For that matter they can power the PC off.
USA #13
If you really want to encrypt it, there's the microsoft script encoder tool, I found it when I was browsing downloads.

I think this is it.
http://www.microsoft.com/downloads/details.aspx?FamilyID=e7877f67-c447-4873-b1b0-21f0626a6329&DisplayLang=en

I haven't tried it, but it sounds like what you want.
USA #14
Ah. But powering off the PC would also disconnect the world, as would closing the client, or forcing it to close, if it was locked up. But, as someone else mentioned, it may be possible to "freeze" the client, in a sense, by popping open a dialog in scripting.

Mind you, I don't think that is necessarily a good solution, since it would halt everything in the client, including display or processing of other text from the mud. And what happens if you are gone so long that the buffered input from there fills up the buffer available? You need something that can lock it *without* freezing the rest of the application, so you can leave it indefinitely, not for 2-3 minutes, while you hope too much text doesn't arrive from the other end. Having the script suspend things doesn't sound like that great of an idea imho. But that brings us back to the prior issue.

Now, if you want a *real* lock system, you also wanted to let the client still do "most" things, *but* you don't want secure plugins, then one solution would be to add something like:

world.requestpass(password_hash)

The plugin doesn't need to be secure, since all its doing is:

sub lock_me
  if mypass = "" then
    do
      temppass = messagebox("Lock code:")
    loop until temppass <> ""
    mypass = hash(temppass)
  end if
  requestpass("Unlock code:", mypass)
end sub

sub OnPluginPass(bool)
  if bool then
    exit sub
  else
    requestpass("Invalid Code!/n/nUnlock code:", mypass)
  end if
end sub


Note, this has sanity checks in it, to make sure that a password of *at least* one character is entered. It could be changed so that hitting enter would instead do "exit sub", thus bypassing the lock system. The reason for using a callback, instead of treating the password dialog, which would return a boolean directly is to "prevent" client locking in the script. Each call to the password request would exit the script *after* the dialog displays, thus the script and everything else can still work, even while input from the user is "locked" to the top level dialog.

Again, this doesn't require that the plugin be secured at all, but it **does** prevent the client from locking up for 2-3 hours you are AFK, when we really can't be sure what the client or the connection will do if the client isn't able to do anything at all, since the script, using a normal dialog, is going to be frozen. Which, as I said, is imho, a bad idea.
Amended on Thu 07 Jun 2007 01:01 AM by Shadowfyr
USA #15
OK, forget the script encoder, it doesn't work except for webpages viewed in IE.
USA #16
Quote:
Now, if you want a *real* lock system, you also wanted to let the client still do "most" things, *but* you don't want secure plugins, then one solution would be to add something like:

I think the best solution would be to have a plugin like Cage_Fire_2000 had mentioned having. If the world plugin is disabled, you can have it disconnect from the world. If you want to get really insane with all those extra client locking issues, just get a screen locking program like xlock.

Quote:
Again, this doesn't require that the plugin be secured at all, but it **does** prevent the client from locking up for 2-3 hours you are AFK, when we really can't be sure what the client or the connection will do if the client isn't able to do anything at all, since the script, using a normal dialog, is going to be frozen. Which, as I said, is imho, a bad idea.

If you are that concerned about what is going on with your client while you are gone for several hours, there is an even easier solution... close MUSHclient! I'm sure your game can get along fine without you being logged in 24/7 if it's a security issue. Setting a lock up if you, for example, are mudding from a computer lab at a university and have to run to the bathroom real quick is realistic. Being secure on your own computer should be a lot easier since you can just use other options like screen locking. WindowsXP even lets you switch out sessions where you can have programs running in the background... set up a guest account and swap into that if someone wants to use your computer.

The plugins work fine as is with the OnPluginDisable routine built in to disconnect your character. The only thing that will defeat this is being able to reconnect with an autologin, which isn't secure to begin with.
Amended on Thu 07 Jun 2007 06:00 PM by Shaun Biggs
USA #17
Sigh. Shaun, I am thinking in terms of what happens *if* you planned on only being afk for 2-3 minutes, but that turned into longer. Sure, you can lock the entire fracking computer, but maybe that **isn't** what someone wants to do. They might want it to be possible for someone to use the computer *but* also keep the client locked, in which case, you are right back to the same problem. You can't lock it, unless you are willing to risk someone getting around it, by deleting the plugin, or by freezing the client for a period of time you "can't" be 100% sure will only be a few minutes.

Sorry for being the sort of person that looks at all angles of a problem and recognizes when there are dragon sized holes in them. lol Its just the way I think.
USA #18
So you get disconnected from the world with the client lock plugin if someone tries to diable it... big deal. You obviously weren't using it at the moment anyway. Find the dragon sized hole in that...

Personally, I think you're just going about making mountains out of molehills here. Disconnecting you from your world will let people use the computer, but not muck about with your character. All your triggers/timers will still keep running until someone tries tampering with MUSHclient. They cannot log back in unless you have an autologin set or if they know your password (which means they can just connect with telnet and you're screwed anyway). All the problems you mentioned are solved with that one simple script setup.
Australia Forum Administrator #19
These "program lock" plugins - to be used during a quick absence - seem to me to be unnecessary, because under Windows XP you just hit Windows_key+L to instantly return you to the login screen. Under NT you press Ctrl+Alt+Del and hit "Lock Workstation".

Then you need to re-enter the account password before you can continue the session. Meanwhile in the background MUSHclient is still receiving data and processing it normally.

I suppose this won't work in a shared environment where everyone knows the password - although it would surprise me a bit if playing MUDs was allowed there. In that case, as someone said, you can just log out.

Another alternative for more security is to create a TrueCrypt volume:

http://www.truecrypt.org/

This can just be a file on disk. By running MUSHclient off such a volume your logs, player passwords etc., are all encrypted and safe from viewing - once you dismount the volume that is.