Seer Xingjian
Registered User
Join date: 29 Sep 2005
Posts: 35
|
11-16-2005 20:03
Ok i have worked out XML-RPC and while it uses a channel in and out i was wondering on the best quick method to secure the channel so that only selected external sources can connect in. I have been thinking about XORing all the data going over the XML-RPC as though it is not the most secure it is the fastest and the chances should be low of someone finding my channel (i think).
Does only the script that opened the channel receive the data or if you have 2 script so pening a rpc channel each on the same object will they get each others data as well? Can you open more than one rpc channel in a script?
I want to use this for a vending system that is a little more complicated that the standard ones and it will require faster communication than email and can only have one script per object.
To protect someone trying to dump another script onthe objects my scripts are on to listen to any communication i plan to check the number of scripts on the object and disable my script if there is more than 1. Is there a better way? I know about object permissions but I will not always own the object my script is on.
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
11-16-2005 21:57
Unless the object is owned by another user they can't dump a script in it.
|
Seer Xingjian
Registered User
Join date: 29 Sep 2005
Posts: 35
|
11-16-2005 23:03
True but i would like to plan for the worst which si that someone that does own the object and is using my script tries to read my secure communications. they would nto have mod on the script but may have mod on the object it is in.
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
11-17-2005 06:56
If yuo don't have a secure channel, then you have to use encryption. How strong the encryption needs to be depends on the value of the encrypted material. How strong you can make the encryption depends on the circumstances and the amount of CPU time you use on it. For example, you might be able to get by with a list of numbers and a substitution cipher, with the cipher being renewed when the user gets close enough to a key server to allow you to use listens. // horrid hack because LSL doesn't seem to have llStringToASCII or equivalent... list ascii = [ " ", "!", "\"", ... "?", "@", "A", "B", ... "Z", "[", ... "_", "`", "a", "b", "c", "d", "e", ... "z", ... "~" ]; integer ASCII_LEN = 95; // 128 ASCII characters, less 32 control, less DEL list key = [ 11, 34, 89, 61, ... 47 ]; integer key_channel = 67846738; // Keep this uber-secret
string decode(string ciphertext) { integer len = llGetStringLength(ciphertext); string plaintext = ""; integer keylen = llGetListLength(key); integer i; integer j = 0; integer charval; string chartext;
for(i = 0; i < len; i++) { charval = llListFindList(ascii, [ llGetSubString(ciphertext, i, i) ]); if(charval != -1) { charval = (charval + llList2Integer(key, j)) % ASCII_LEN; chartext = llList2String(ascii, charval); plaintext = plaintext + chartext; j = j + 1; if(j >= keylen) j = 0; } else if(chartext != " ") { plaintext = plaintext + " "; chartext = " "; } } return plaintext; }
The decode function is the same except you subtract the key (or add 96 - the key, depending on how modulus works in LSL). This code will replace all newlines and tabs and things with single spaces, which is probably what you want. If your data is numeric to begin with (like coordinates or something) it's simpler because you don't have to use the bogus ASCII conversion junk. Then have the script periodically llSay(key_channel, "magicword"  and listen for a CSV-formatted list of keys in return... or the key distributor could even push a new version of the script...
|
Seer Xingjian
Registered User
Join date: 29 Sep 2005
Posts: 35
|
11-17-2005 13:27
Argent that is one possibility but surly something that simple can easily be brokken in C# or any other language the external app is using. Remeber this is for XML-RPC so it is safe to assume you have a dedicated 1ghz proccessor connecting in atleast.
On top of that is should just be a command or 2 in most languages to do that conversion shouldn't it or did i mis read something?
So far the best option seems to be XOR or multi XOR with multiple changing keys.
Also can anyone confirm that if you have 2 scripts onthe same object do they both receive the RPC data or only the one that made the RPC channel the data is for. Also how many RPC channels can a script open?
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
11-17-2005 14:04
From: Argent Stonecutter // horrid hack because LSL doesn't seem to have llStringToASCII or equivalent...
LSL strings aren't ASCII, they are UTF-8. nice unicode functions i wrote  note the custom Base64->Integer function (to get around the delay) llEscapeURL doesn't touch valid characters, which makes getting ascii values difficult. iinteger UTF8ToUnicodeInteger(string a) { //{//Convert our data into a nice byte list; string b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; integer d = llSubStringIndex((a = llStringToBase64(a))+"=","="); integer e = 0; list f; if(d>8) d = 8; integer i = 0; while(e < d) { i = (i << 6) | (llSubStringIndex(b,llGetSubString(a,e,e)) % 64); if(!(++e % 4)) f += [(i >> 16) & 0xff,(i >> 8) & 0xff,i & 0xff]; } if(e = (6 * (e % 4))) f += [((i << 8) >> e) & 0xff,((i << 16) >> e) & 0xff,(i << (24 - e)) & 0xff]; //} i = llList2Integer(f,0); if( i < 0xC0) //11000000 { if((4 <= 3 * d) && !(i & 0x80)) return i; } else if( i < 0xFE ) //11111110 { e = llList2Integer(f,1); if( i < 0xE0) //11100000 { if((8 <= 3 * d) && (i & 0x1E) && ((e & 0xC0) == 0x80)) return ((i & 0x1F) << 6) | (e & 0x3F); } else { integer c = 6; if( i < 0xF0) //11110000 c = 3; else if( i < 0xF8) //11111000 c = 4; else if( i < 0xFC) //11111100 c = 5; if(4*c <= 3 * d && (e & (0x1F80 >> c)) != 0x80) { d = i & (0x7f >> c); integer g = 1; e = (d << 6) | (e & 0x3f); while(++g < c) { e = (e << 6) | ((d = llList2Integer(f,g)) & 0x3f); if((d & 0xC0) != 0x80) jump error; } return e; } } } @error; return i | 0x80000000; }
string byte2hex(integer x) { string hexc="0123456789ABCDEF"; integer x0 = (x & 0xF); return llGetSubString(hexc, x0 = ((x >> 4) & 0xF), x0) + llGetSubString(hexc, x0, x0); }
string UnicodeIntegerToUTF8(integer a) { if(a <= 0) return ""; integer b = 0; integer c = 0; string d; if (a >= 0x4000000) c = 5; else if (a >= 0x200000) c = 4; else if (a >= 0x10000) c = 3; else if (a >= 0x800) c = 2; else if (a >= 0x80) c = 1; while(b < c) d = "%" + byte2hex((((a >> (6 * b++)) | 0x80) & 0xBF)) + d; d = "%" + byte2hex((a >> (6 * c)) | ((0x3F80 >> c) * (0 != c))) + d; return llUnescapeURL(d); }
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Seer Xingjian
Registered User
Join date: 29 Sep 2005
Posts: 35
|
11-27-2005 18:38
for those ineterested i got the base64 encoding/decoding working perfectly and the XOR encode/decode is sort of working.
If the first string is shorter than the second string passed into the XOR encode method it is fine but if the second string is short SL does soem sort of padding of extra characters to the send of the second string before repeating hte string fromt he start. These extra characters change depending on the contects of the second sting and the amount of characters is party controlled by the characters in the string and the length of the second string.
So far i have been unable to work out the rule to generate these extra characters apart from when the second string is only 1 character long. Any information on how these characters are generated would be great! Someone has to have this information or know something about it even if it the developer that implemented the XOR in SL.
Can someone please help me.
Seer
|