Making Sure Your Prims Belong to You
As I noted earlier, I’m going through some of the pain I dealt with in securing RPCS so would-be hackers won’t exploit the system. Of course, no system is completely secure. But I’ve done everything I can to make it so expensive and difficult to hack that no one will bother.
So.. the first challenge was this: preventing people from both listening to the internal communications of the system, and preventing them from impersonating those communications. That’s actually more difficult than it seems, for a number of reasons. First, even though every object and script in second life gets it own GUID (globally unique identifier), that can’t be used for this purpose, because the entire system gets a new GUID every time it changes ownership or is rezzed in world.
This is complicated a bit further because the system itself contains multiple scripts. So I’ll walk through the steps that were taken:
Resetting the device
First: reset the device. This happens every time it’s attached, when you log in, or when it is rezzed on the ground. Resetting the scripts clears the memory (and any data, including passwords), and forces a startup from scratch.
attach(key f_ID) { llResetScript(); } changed(integer f_Changed) { if ((f_Changed & CHANGED_OWNER)) { llResetScript(); }
Ok… so now we’ve got a clean startup. However, this doesn’t do anything with the _other_ scripts in the object. That’s fine, because just about the first thing that will be done is resetting all of the scripts.
Now, since the script is being reset when a new person gets it.. when they rez it… when they wear it… we know we’re starting from a clean slate. Next step is to start checking security. First, we ask for attach permissions, because if security checks fail, the object kills itself. Second, a password is set.
Note that the password uses an internal algorith that all the scripts know, so that they can independently arrive at the same one. We’ll need that in a minute.
What we’re trying to accomplish here is a couple of specific things.
First, one of the ways people hack objects in LSL is by replacing nonessential scripts. Second, they’ll insert their own, which listens to what’s going on inside. Third, they’ll rip the scripts out, and place them in their own prim. We’re going to address all of those things.
string securePass; default { state_entry() { llRequestPermissions(llGetOwner(),(PERMISSION_ATTACH)); // (Ask for permission to attach, because if it fails, the object will commit suicide securePass = "whatever"; llResetOtherScript("everythign"); // reset all the other scripts *except* for the security script, we'll get to that seperately checkSecurity(); llSetTimerEvent(0.3); } timer() { if ((securityOK == 1)) state load; }
Note what state_entry basically does: nothing. It calls the checksecurity function, and then chills. Unless the events in checkSecurity work out? The system never moves to loading or running states.
Next we’ll take a look at the checkSecurity() function.
checkSecurity(){ me = llGetOwner(); if ((llGetCreator() != "put GUID of creating avatar here")) {disable();} integer perms = llGetObjectPermMask(MASK_OWNER); if (me != "put my own GUID here") { if ((perms & PERM_MODIFY)) { disable(); } } llResetOtherScript("security"); }
Ok… now we’re getting to our first actual checks. Notice we’ve had .. maybe 1 millisecond pass at this point. If that. The checkSecurity function starts, the first thing it does is sets a variable for the owner of the object.
Next step: we check llGetCreator() … does it equal who the creator of the object is supposed to be?
Important point here. If you’re like me, there’s probably mod/transfer and full perm objects floating all over the place created by you. That won’t do. What I did in this case was grabbed an alt… one who’d never made anything… ever… for anyone… and _that_ account created a prim and scripts and passed them over. So that’s what I’m working with here. The only mod prim in existence created by that account belongs to me.
So.. the first check here says… if I’m running in a prim created by anyone else… then run disable() (which causes the meter to choke and die).
Then… just in case I screw up and hand out a mod version of it even once, it checks first… is the object owned by me? If not, it checks if permissions are modifiable. If they are? then it dies.
So this mostly deals with the issue of prim creator/owner. Next we move on to the tough part. We reset the script security, then sit back and wait, because that script takes control of the next phase.