Phantasmal MUD Lib for DGD
|
Phantasmal Site > DGD > DGD LPC Reference > DGD Calling Conventions DGD Function Calling ConventionsDate: Wed, 10 Jun 1998 17:29:34 +0200 (MET DST) From: Frank Schmidt Subject: [DGD] Re: Couple DGD questions On Tue, 9 Jun 1998, E. Harte wrote: > On Tue, 9 Jun 1998, Stephen Schmidt wrote: > > [...questions about kfuns...] > > Making a function static in the auto-object only has an effect on > call_other() type of calls to such functions. I.e: if "foobar" is a > static function in your auto-object then "someobj"->foobar() will return > 0, _unless_ "someobj" has defined its own foobar() function which isn't > static. No, as you describe it, that is the way it works for other objects BUT the auto object, and an object may access its own static functions through call_other, i.e: call_other(this_object(), "static_func") works. In the auto object, a static function behaves like a kernel function (kfun) _too_: It cannot be accessed by call_other(this_object(), "kfun_func"), _and_ calls to it in the auto object are _not_ redirected to any masked function in this_object(). This is true for ALL static functionnames in the auto object, not just the default functions specified by the driver you happen to override. > > So, to consider your write_file() and valid_write() example, I'd either > make the valid_write() nomask, or private to the auto-object, yes. > Otherwise something like the following could disable your security: > > <auto-object> > static int > valid_write(string filename) > { > } > > static void > write_file(string filename) > { > } > </auto-object> > > <other-object> > static int > valid_write(string filename) > { > return 1; /* of course ;) */ > } > </other-object> No, sorry, but this will not disable his security IF the security call is made in the auto object, but it will override the call made in an inherited program. This is ambigous, and is of course not wanted. However, I dislike overuse of nomask due to lack of knowledge about kfuns. In many situations, nomask creates a false sense of secureness, overlooking the more important holes. I set a BIG questionmark (?) to this way to deal with security too. Instead of having the valid_ functions in each and every object, make a daemon which any object may call_other() and query about security issues and similar. (An equivalent of MudOS Master object is nice, or you may split it up in several daemons. The way I deal with it is a master.c object for simple queries, and a global.c object for call_out(), heart_beat(), etc, global issues. The main point is to globalise functions and datas in sentral objects.) > > > There is another situation where kfuns are showing how they're different: > > If you are using a certain kfun in the auto-object which you have -not- > redefined, for instance you're using this_object() or previous_object(), > then no matter how hard you try to redefine those in another object, the > code in the auto-object will continue to use the -kfun- and not the > redefined version. This is true for redefines kfuns in the auto object too. > > Sometimes I wish there was a way to make static functions in the auto- > object behave the same way without having to nomask them. :-) Nomasking a function makes it impossible to overload in an inheriting program. However, that is not the same as static, private or kfun, since you can still access a nomasked function! And.. Your wishes have come true! It is possible to make the functions behave like kfuns, just declare them static in the auto object. And it is VERY convinient, flexible and elegant. :) > > > Second, and unrelated; it is now the case that when an object is > > compiled, create() is not called right away; it's called only > > when the first function is called in the object. This caused me > > a great deal of headache tonight when I couldn't figure out why > > create() was not running, which was solved when I RTFM. :) > > Question is, why was this changed? Arrgh. I didn't know this. Thanks for the information, it was new to me, a simple test showed that it was correct. When a master program is compiled (I really prefer calling them blueprint because of my Master object..) the create function is not called before the first function is called in the object, and for clones the create function is called right away. > > What makes you think this changed? As far as I remember, the 'create' > function (or whichever name you pick for this function) was for non-clones > always called just before you tried to call any other function in the > object for the first time. Maybe, but I too missed that point. Any ref. to where in the docs this is explained? > > > It seems unintuitive for > > master copies of objects not to invoke create(), I find myself > > having to code around it (not hard to do) but in general I do > > not see a way for the mudlib programmer to alter this behavior > > except to have compile_object() be redefined and call some function > > in any non-clone object it compiles. Would there be a Bad side > > effect if I did that? If it suits you, there should be no problem with that. I guess I'll implement the same thing myself. > > It would in many many cases be entirely unnecesary. For instance for > objects that are only used to make clones of, or to inherit, the usual > ones for rooms and treasure-objects, or whatever. I can't really see it nescessary in _any_ circumstance. Please name one. Of course it is perhaps better to support it than not support it at all. But why just for master objects, why not for clones too? I suspect the answer has something to do with DGD-Internals... > > Hope this helped, > > Erwin. > PS. I ALWAYS test things before making assumptions about things, never trusting documentation or others arguments. It is essential to know _all_ the details and see for yourself. Keep on DGD-ing! Frank Schmidt Date: Thu, 11 Jun 1998 11:59:27 +0200 (MET DST) From: "E. Harte" Subject: [DGD] Re: Couple DGD questions On Wed, 10 Jun 1998, Frank Schmidt wrote: [...] > Functions which you call with call_out() in DGD may be static and/or > private, as with most functions called directly from the dgd driver. Makes > security for the driver object, user object and call_outs very simple; by > use of static. Functions called from DGD itself may not be private, only static (or no additional restrictions at all, of course). That goes for functions called in the driver-object as well as functions called by the call_out() kfun. [...] > Only previous_object() check is nescessary to see if it was called > directly from the driver, and the driver alone (e.g. call_out). > Previous_object() will return 0 if the call was a call_out() or similar > call. Uhm, no. But if you replace previous_object() with previous_program() then your claim becomes truth. The problem with previous_object() is that it'll be 0 when the calloutfunction (__heart_beat() or whatever) is called directly, without call_other(), from for instance another call_out(). Erwin. From felix Fri Jun 12 18:37:34 1998 Subject: Re: [DGD] Re: Couple DGD questions E. Harte wrote: > On Wed, 10 Jun 1998, Frank Schmidt wrote: > > [...] > > In the auto object, a static function behaves like a kernel function > > (kfun) _too_: It cannot be accessed by call_other(this_object(), > > "kfun_func"), _and_ calls to it in the auto object are _not_ redirected > > to any masked function in this_object(). This is true for ALL static > > functionnames in the auto object, not just the default functions > > specified by the driver you happen to override. > > I'd like to have confirmation or denial of the last part from Dworkin, as > most definitely remember there being a difference between using a 'pure' > kfun in the auto-object and a static function that happened to be defined > in the auto-object. Frank is correct. To be yet more precise: <any> calls made to static functions in the auto object can never be redirected to a new function by masking the static function, no matter from where the calls are made. In C++ terminology, static functions in the auto object are not "virtual". > [...] > > > <auto-object> > > > static int > > > valid_write(string filename) > > > { > > > } > > > > > > static void > > > write_file(string filename) > > > { > > > } > > > </auto-object> > > > > > > <other-object> > > > static int > > > valid_write(string filename) > > > { > > > return 1; /* of course ;) */ > > > } > > > </other-object> > > > > No, sorry, but this will not disable his security IF the security call is > > made in the auto object, but it will override the call made in an > > inherited program. > > Oh? Again, I'd like confirmation of this. (Or else I'll go check the > sources myself this weekend. *grin*) Again, Frank is correct. Calls made to valid_write() from any object in the inheritance chain between the auto object and other-object will continue to use the auto object version of the function. Dworkin From felix Fri Jun 12 18:40:18 1998 Subject: Re: [DGD] Re: Couple DGD questions E. Harte wrote: > On Wed, 10 Jun 1998, Frank Schmidt wrote: > > [...] > > Functions which you call with call_out() in DGD may be static and/or > > private, as with most functions called directly from the dgd driver. Makes > > security for the driver object, user object and call_outs very simple; by > > use of static. > > Functions called from DGD itself may not be private, only static (or no > additional restrictions at all, of course). That goes for functions > called in the driver-object as well as functions called by the call_out() > kfun. They cannot be private; note that they can also not be static in the auto object. Dworkin From felix Fri Jun 12 19:26:06 1998 Subject: Re: [DGD] Re: Couple DGD questions Stephen Schmidt wrote: > On Fri, 12 Jun 1998, Felix A. Croes wrote: > > To be yet more precise: <any> calls made to static > > functions in the auto object can never be redirected to a new function > > by masking the static function, no matter from where the calls are > > made. In C++ terminology, static functions in the auto object are > > not "virtual". > > To put this in language "for the rest of us" :) this means that > in the auto object, "static nomask" is redundant? Not exactly. I think you are confused about the meaning of "nomask": a static function in the auto object <can> be masked, it just doesn't have any effect on existing calls to that function. Declaring it to be nomask would make masking it impossible: attempting to do so would result in a compile-time error. Dworkin Date: Mon, 30 Nov 1998 14:50:51 +0100 (MET) From: Mikael Lind Subject: Re: [DGD]varargs void foo(object bar) On Mon, 30 Nov 1998, Frank Schmidt wrote: > [...] > > My problem: varargs with objects as parameters, and dealing with default > values for objects. > > Example: varargs void foo(object bar) > > Now the call to this function can happen in four different scenarios: > 1) foo() > 2) foo(beer) /* when <beer> != 0 */ > 3) foo(beer) /* when <beer> == 0 */ > 4) foo(0) > > The problem in this example is that there is absolutely NO way in foo() > to detect that <bar> is a default parameter set-to-0 in 1). E.g. > according to the tracelist, scenario 1), 3) and 4) are identical. Use ellipsis, the "..." operator. This is will convert an argument list to an array or vice versa, depending on the context. varargs void foo(object bar...) { /* "bar" is an object array that is now containing all arguments supplied */ int size; size = sizeof(bar); if (size > 1) { /* too many arguments supplied */ } else if (size == 0) { /* scenario 1 */ } else if (bar[0] != 0) { /* scenario 2 */ } else { /* scenario 3 or 4 */ } } As far as I know, it's currently impossible to distinguish scenario 3 from scenario 4 from within the LPCd code. (And I don't see why you'd want to.) There's certainly more to say about the design issue of giving a function several different functionalities. Sometimes, it's more useful to split the function into two (or even more) functions: void foo1(object bar) { if (bar == 0) { /* * scenario 3 or 4; in some cases considered an incorrect call, in * some other cases a default value could be assumed, and in still * other cases nothing is known for sure ;) */ } else { /* scenario 2 */ } } void foo2() { /* scenario 1 */ } It all depends on what it is that you want to do. [Insert a lengthy discussion on the benefits of argument-based function call binding here, if you find it at all necessary.] // Mikael Date: Sun, 10 Jun 2001 23:57:41 -0400 From: Kris Van Hees Subject: Re: [DGD]Scope (::) operator and Kernel lib wiztool Functions called with the :: scope prefix call a function in the inherited objects, and because of the multiple inheritance implementation it is known that exactly one function with a given name will be visible to the calling code. If the auto object defines the functions and no other inherited class that's interposed between the auto object and your object redefines it, then it will be calling the function in the auto object of course. Kris On Sun, Jun 10, 2001 at 08:47:35PM -0700, Noah Lee Gibbs wrote: > I've got a lightly-customized Kernel lib up and running and I'm playing > around with the code in different ways. Got a DGD LPC question. > I remember from the archives that the two-colon scope operator, ::, is > used to call a kfun or (same thing, mostly) a static function in the auto > object. But in /kernel/obj/wiztool's create() function, it appears to be > calling to its parent (/kernel/lib/wiztool) with the same syntax -- if it > called straight up to auto, it would just say ::create(1) to say that it > was a clone (and it isn't) instead of saying ::create(200) to set hsize to > 200. > Does anybody know if this is just a bug in the Kernel lib or if > functions called with the scope operator call to the parent before trying > the auto object? > > -- Software Developer & Creator of Worlds From: Par Winzell Date: Fri, 22 Jun 2001 19:58:44 -0700 Subject: Re: [DGD]Arrays and call others > I'm a little worried that making call others each time will be eating up > memory. Would it be better to make one call other setting arrays in the > function: > > (2) > > Rnames = current_object->query_reference_names(); > > for (i = 0, sz = sizeof(rnames); i < sz; i++) > { > if (rnames[i] == name_test) > { > return current_object; > } > } In practice, the time consumed by the call-other itself is probably not such a big deal. But it's typically a good idea to store return values in a variable, yes, especially if you do not have absolute control over what may happen inside query_reference_names() in the future. Maybe somebody will change its internal implementation in such a way that it becomes a backwards compatiblity function going at some sluggish pace? I've seen it happen. You can obfuscate your code quite a bit if you like it small: if (sizeof(current_object->query_reference_names() & ({ name_test })) != 0) { return current_object; } Zell From DGD Mailing List Sat Oct 27 13:10:01 2001 From: DGD Mailing List (Erwin Harte) Date: Sat Oct 27 13:10:01 2001 Subject: [DGD] Another question from the DGD n00b... On Sat, Oct 27, 2001 at 07:57:22PM +0200, Troels Therkelsen wrote: > Hi all, > > I was wondering why the backend (call_out(), creator function, etc) > can't call static functions in the auto object? > > I mean, it's fully within the logic of the static modifier that > other LPC objects can't call the function. But in all other > objects (programs, I guess it is?) than the auto object/program, > the backend is perfectly capable of calling static functions. That's because in all other objects, static functions are just that, static functions, but if you define a function as static in the auto- object, you tell DGD that this is a special function, an afun or efun if you will, and one of the side-effects is that you cannot call it with a call_other() anymore, just like you can't do that for the built in kfuns. Erwin. -- Erwin Harte From DGD Mailing List Sun May 25 05:48:01 2003 From: DGD Mailing List (Felix A. Croes) Date: Sun May 25 05:48:01 2003 Subject: [DGD] Auto and Driver objects "Ben Chambers" wrote: >[...] > Then to make a specific backpack or something I would want to inherit both > the base object and the container object, but with the container object's > versions of move from and move into overriding the versions defined in the > base object. Would this be possible? Basically, the base version provides > the default 'You can't move that from that to that' behavior, while the > container provides the you can move it, and the end object is the specific > version of how this is done. By inheriting from two different objects that both define the same function, you introduce a conflict. That conflict must be resolved by masking the function in the inheriting object, like this: inherit base "/foo/bar/base"; inherit container "/foo/bar/container"; int MoveInto(object item) { return container::MoveInto(item); } int MoveFrom(object item) { return container::MoveFrom(item); } There are other ways in which this issue can be addressed. For instance, the container object could be made to inherit the base object, in which case its functions would automatically override those of the base object. Should another object then inherit both, the compiler will understand that the container functions are meant to mask those of the base object, and no conflict will ensue. Regards, Dworkin From DGD Mailing List Thu Feb 12 15:13:06 2004 From: DGD Mailing List (Robert Forshaw) Date: Thu Feb 12 15:13:06 2004 Subject: [DGD] My idea for the DGD driver - validate In my mudlib I have an object daemon, and it is responsible for just about everything regarding objects, from keeping track of inheritance to monitoring players idle status. There are many functions in my object daemon that I don't want just any object to call. In fact, just about any function that doesn't begin with 'query_' has some validation code at the beginning. I also developed a function called alert, which is kind of like a runtime error but noisier and is executed when an object tries to do something it shouldn't be doing (it sends a notification message to any admin that is logged in, for instance). So when naughty_object does OBJECTD -> hazardous_function(), hazardous_function() performs some checks on what the previous_object() or previous_program() was, and calls alert() if necessary and then error() to abort execution. This method became rather heavy-handed, so I eventually decided to have a seperate function called verify_object_daemon_function_call (the name isn't important). Basically, all other functions that need security are declared private, and any object wanting to access any of those functions must call vodfc() first. e.g. OBJECTD -> vodfc(some_function, mixed args...) This is so ugly though, that I hit upon the idea of having such a thing built in the driver. It would then be much easier to implent security of the nature I've described into an object. The idea is that there would be a keyword, for example, validate, for a function. Any function declared with this keyword can not be called by anything except the driver. Now, when naughty_object does a call_other to OBJECTD, or whatever, if there is a validate function there then that function will be called instead of the function specified. If the function bearing the validate keyword returns zero, To put that in code, lets say that we have: /* naughty_object.c */ string mysterious_function() { OBJECTD -> hazardous_function(); return ""; } /* EOF */ and then, in object_daemon.c: /* object_daemon.c */ validate int security_function(string func_name, mixed args...) { switch(func_name) { case "hazardous_function": if(previous_object() == naughty_object()) { alert("Uh-oh, naughty_object() tried to call hazardous_function, call the cops!!"); return 0; } default: return 1; } return 1; } string * hazardous_function() { /* do something hazardous */ return 0; } Here's what I propose the advantages and disadvantages to be of this method: Advantages: 1) It makes an object far more resilient than it could be using any current available feature of the driver. If a function exists in an object with the 'validate' keyword, it has many security implications for the object. There is no way on earth that any function can be called in that object by another object(except the driver of course), without calling the function bearing the 'validate' keyword first. Thus, there is no need to declare any functions as private. 2) It makes it impossible to expose a security hole even if you're the dopiest programmer on earth. There is no oppertunity for forgetting to insert a security check into every single function that you want protected. All security checks are condensed down to one function and so there is only one place to look when you need to maintain that security. 3) It saves having to type many lines of code, and much simplifies the process of implenting call_other security. 4) It saves ticks. 5) As an extention of the idea, it could be possible to have several functions with the 'validate' keyword, which are called in succession until one of them eventually returns 0 (stop execution) or they all return 1 (function is called as normal, as if it were called directly via call_other() in lieu of current behaviour. Disadvantages: 1) It transgresses the 'philosophy' of DGD that if a feature can be implented in the lib rather than the driver, it should be. I personally don't consider this valid in this case as I'd colligate it with the hallmark functions that make DGD driver to be reckoned with, like atomic functions. Okay, so atomic function behaviour can't be implented solely in the lib, and my idea can, to a degree. But not to such bullet-proof perfection. Doing it the mudlib is far messier and far more prone to security holes. That's it. Tell me what you think! _________________________________________________________________ Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo From DGD Mailing List Thu Feb 12 15:24:04 2004 From: DGD Mailing List (Robert Forshaw) Date: Thu Feb 12 15:24:04 2004 Subject: [DGD] My idea for the DGD driver - validate Something I forget to mention: the 'validate' function will return zero by default. Therefore, any function that needs call_other permission has to be deliberately given it. And you can do 'validate validate_func() { }' to immediately isolate your object from call_other's. This makes it very hard to accidently give access to an object that you didn't mean to. _________________________________________________________________ It's fast, it's easy and it's free. Get MSN Messenger today! http://www.msn.co.uk/messenger From DGD Mailing List Thu Feb 12 15:27:01 2004 From: DGD Mailing List (Robert Forshaw) Date: Thu Feb 12 15:27:01 2004 Subject: [DGD] My idea for the DGD driver - validate And here is an amendment to the following paragraph of my original post, which became truncated for some reason: The idea is that there would be a keyword, for example, validate, for a function. Any function declared with this keyword can not be called by anything except the driver. Now, when naughty_object does a call_other to OBJECTD, or whatever, if there is a validate function there then that function will be called instead of the function specified. If the function bearing the validate keyword returns zero, the execution halts and the function that was the first argument of call_other is never called. If one is returned, execution may continue as normal and the function that was the first argument of call_other is called normally and transparently. _________________________________________________________________ Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo From DGD Mailing List Thu Feb 12 15:30:01 2004 From: DGD Mailing List (Erwin Harte) Date: Thu Feb 12 15:30:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate On Thu, Feb 12, 2004 at 09:12:52PM +0000, Robert Forshaw wrote: [...] > The idea is that there would be a keyword, for example, validate, for a > function. Any function declared with this keyword can not be called by > anything except the driver. Now, when naughty_object does a call_other to > OBJECTD, or whatever, if there is a validate function there then that > function will be called instead of the function specified. If the function > bearing the validate keyword returns zero, Perhaps you've noticed 'private' and 'static' functions in other code? I believe these will allow you to do 99% of what you want, already. A private function is only callable from within the program where it was implemented. Even code inheriting it cannot access the function, similar to how private variable are not visible to inheriting code. A static function is only callable from within the object that it's in. Code inheriting the program that it was in can also use it but you cannot access it from another object. Hope that helps, Erwin. -- Erwin Harte From DGD Mailing List Thu Feb 12 15:43:01 2004 From: DGD Mailing List (Robert Forshaw) Date: Thu Feb 12 15:43:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate >From: Erwin Harte > > The idea is that there would be a keyword, for example, validate, for a > > function. Any function declared with this keyword can not be called by > > anything except the driver. Now, when naughty_object does a call_other >to > > OBJECTD, or whatever, if there is a validate function there then that > > function will be called instead of the function specified. If the >function > > bearing the validate keyword returns zero, > >Perhaps you've noticed 'private' and 'static' functions in other code? >I believe these will allow you to do 99% of what you want, already. You would know that I have if you read the entire post, as I mention these keywords. You would also know that 99% of what I want cannot be fulfilled by 'private' and 'static'. There is far more to my idea than simply privatising a function, or all functions. The feature is supposed to allow you to decide what objects can call the functions in an object, (or you can in fact decide whether the functions can be called on any expression, its entirely up to you what goes in the validate function) in a very compact way, without the need to perform individual checks at the beginning of each and every function, which is both tedious and prone to human error. So instead, these checks are implented in one function that the driver dictates is manditory to be called whenever a call_other is called with that object as the first argument. 'private' and 'static' are absolutes, because they either say 'you can call this function from another object' or 'you can't call this function from another object'. My 'validate' idea allows for far more flexibility; it says 'You can't call a function in this object from another object unless I say so by returning 1, and by default, I won't return 1, so you MUST lay down the necessary security measures in here or I'll return 0 and you can't call anything in this object from a different object!'. As you can see, it's a very different thing. The reason I described my current problem at the beginning of my post was so that you would appreciate that this feature is about letting very particular objects execute a function, or execute it under very particular conditions. None of which can be achieved using 'static' or 'private' whatsoever. Ideally, a security-conscious lib coder would use 'validate' in every object that contains functions that they don't want 'just any object' to call, but can't be private or static either. _________________________________________________________________ Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo From DGD Mailing List Thu Feb 12 15:57:01 2004 From: DGD Mailing List (Steve Foley) Date: Thu Feb 12 15:57:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate > a function, or all functions. The feature is supposed to allow you to decide > what objects can call the functions in an object, (or you can in fact decide > whether the functions can be called on any expression, its entirely up to > you what goes in the validate function) in a very compact way, without the > need to perform individual checks at the beginning of each and every > function, which is both tedious and prone to human error. Couldn't you override call_other in the AUTO to call this security function of yours and get the same result? Granted, you'd need to write that validate function in each object, and you'd be imposing a small cost on all call_others (the large majority of which likely won't be giving rise to security concerns), but this would meet your requirements, wouldn't it? From DGD Mailing List Thu Feb 12 16:14:01 2004 From: DGD Mailing List (Robert Forshaw) Date: Thu Feb 12 16:14:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate >From: "Steve Foley" >Couldn't you override call_other in the AUTO to call this security function >of yours and get the same result? Granted, you'd need to write that >validate function in each object, and you'd be imposing a small cost on all >call_others (the large majority of which likely won't be giving rise to >security concerns), but this would meet your requirements, wouldn't it? I hadn't thought of this so thanks for pointing it out. I'll give it a try and see how it works out. Incidently, by using function_name() in the override function I could detect whether the validate function is there or not, and it wouldn't be necessary to declare the validate function in each object. I still think my idea would be more convenient, but its probably too much work to implent to justify the benefits... One thing though, will overriding call_other also apply to the -> operator? _________________________________________________________________ Express yourself with cool emoticons - download MSN Messenger today! http://www.msn.co.uk/messenger From DGD Mailing List Thu Feb 12 16:25:02 2004 From: DGD Mailing List Date: Thu Feb 12 16:25:02 2004 Subject: [DGD] Re: My idea for the DGD driver - validate The call_other() override in AUTO, combinded with a function_object()call to see if the validate() function existed (default if not: allow the call) would save a lot of coding for routine objects. Validate() would then only need to be added to sensitive objects. I might be missing something, but seems like you could get 100% of what you want using the above. Kevin C. From DGD Mailing List Thu Feb 12 16:32:01 2004 From: DGD Mailing List (Steve Foley) Date: Thu Feb 12 16:32:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate > and see how it works out. Incidently, by using function_name() in the > override function I could detect whether the validate function is there or > not, and it wouldn't be necessary to declare the validate function in each > object. I still think my idea would be more convenient, but its probably too > much work to implent to justify the benefits... One thing though, will > overriding call_other also apply to the -> operator? Well, you could also leave the auto_object empty and use multiple auto objects as well (via the path_include trick discussed elsewhere) potentially. The assumption there being that the two kinds of objects (those that need this kind of security and those that don't) will likely be in different parts of your directory structure. You'd just have to be sure to declare it static and nomask, and I think that would make it function similarly to a static function declared in the AUTO. As for ->, yes. Overriding call_other has that effect. -> is just a macro for call_other. From DGD Mailing List Thu Feb 12 18:49:00 2004 From: DGD Mailing List (Michael McKiel) Date: Thu Feb 12 18:49:00 2004 Subject: [DGD] Re: My idea for the DGD driver - validate Not going to quote anything specific here... But couldn't this functionality be done by a mapping of a given object and certain security conscious functions within that object ... ie the mapping would be on the object_file_name and the function in question, and contain what is allowed to call it. and the function itself would just start with: if (!validate(previous_object()) return [0|nil]; or optionally do some logging/warnings: if (!validate(previous_object()) { alert(previous_object()); return [0|nil]; ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca From DGD Mailing List Thu Feb 12 18:58:01 2004 From: DGD Mailing List (Robert Forshaw) Date: Thu Feb 12 18:58:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate >"Robert Forshaw" wrote: > > > >From: Erwin Harte > > >Perhaps you've noticed 'private' and 'static' functions in other code? > > >I believe these will allow you to do 99% of what you want, already. > > > > You would know that I have if you read the entire post, as I mention >these > > keywords. You would also know that 99% of what I want cannot be >fulfilled by > > 'private' and 'static'. > >I read your postings, and I do not see you refer to static functions >anywhere. Perhaps that bit was also mysteriously omitted? After >reading them as they were posted, the assumption that you didn't know >about static functions is not unreasonable. Then we have a difference of opinion. Being ignorant of static and not of private seems very unlikely to me. I thought it would be obvious from my posts that I'm not so inept as to not know what they are. As to the 'static' being ommited, yes I didn't mention static. I thought I had. Not that it matters, since none of it was really applicable to my post. > >Regarding calling security, I think one mistake was made during the >inception of LPC: functions (and variables) should be private by >default. Unfortunately it is now too late to change this. This would of course require the inclusion of 'public' (like other drivers seem to possess, but dgd doesn't...). > >By masking call_other(), you are making things needlessly complex. How come? I thought it was a good point that kevinc/Steve Foley mentioned. While I definitely would not say no to my validate idea being included in DGD, as it would make the solution even easier to implent and would be less costly, the feature can still be achieved by masking call_other can it not? Here's what my masking function looks like: mixed call_other(mixed obj, string function, mixed args...) { if(function_object("verify_call_other", find_object(obj))) if(!::call_other(obj, "verify_call_other", function, args)) return nil; return ::call_other(obj, function, args...); } I >suspect that you may still not quite get the effect you are looking >for. Personally, I like the validate(); idea. Could you explain what unexpected effects I have missed? I'm glad you liked the idea. Is it useful enough to be included in the source? _________________________________________________________________ Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo From DGD Mailing List Thu Feb 12 19:08:01 2004 From: DGD Mailing List (Robert Forshaw) Date: Thu Feb 12 19:08:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate >From: Michael McKiel >Not going to quote anything specific here... >But couldn't this functionality be done by a mapping of a given object and >certain security conscious functions within that object ... >ie the mapping would be on the object_file_name and the function in >question, >and contain what is allowed to call it. > >and the function itself would just start with: > >if (!validate(previous_object()) return [0|nil]; >or optionally do some logging/warnings: >if (!validate(previous_object()) { alert(previous_object()); return >[0|nil]; Can you index nil on an array..? Anyway, the idea seems workable, but the feature I had in mind would be at a more fundamental level, to be implented by whoever is coding the lib itself. The idea you are suggesting uses variables to determine security, and the only reason to have it in variables would be to allow other people to come along and set the security with some abstract function (like one sets the daemons in the kernel lib). Its akin to the idea of not exposing people to the complicated 'innards' of the driver, and instead have them only required to know a simpler set of functions that modify a simpler set of variables (although I find the issue of security to be anything but simple, and if you're targetting mediocre coders who just want to be able to set variables via a function, the security should already be implented in the lib to avoid such a feature being necessary). Therefore, while I don't find anything particularly wrong with your idea, its a totally different thing to what I had in mind as its at a higher level. _________________________________________________________________ Find a cheaper internet access deal - choose one to suit you. http://www.msn.co.uk/internetaccess From DGD Mailing List Fri Feb 13 09:13:01 2004 From: DGD Mailing List (Robert Forshaw) Date: Fri Feb 13 09:13:01 2004 Subject: [DGD] Re: My idea for the DGD driver - validate > > >By masking call_other(), you are making things needlessly complex. > > > > How come? > >It is hard to be more specific since I have only a vague notion of >what you are trying to accomplish. I have noticed a tendency among >people who have just discovered that call_other() can be masked, to >consider it the solution to everything. So, broadly stated, I hope >that you will reconsider other ideas, should you come to the >conclusion that redefining call_other() does not suffice. What I am trying to ultimately accomplish is to have checks performed before various functions in an object are allowed to continue execution, to ensure that only the right objects are able to call it. My validate() idea, as you called it, was sufficient for this except for two things: it was more prone to error (i.e. it is in theory possible to still call a function that you aren't meant to), and the alternative way I came up with is even easier to implent. Because the 'validate' idea I had (and subsequently, the masking idea that was suggested) involves a manditory function call that will dissallow every call_other by default, it is much more difficult to make a security gap as a result of human error, and it isn't necessary to go adding code to the beginning of every function you want protected. I appreciate what you were saying about people mistakenly seeing masking call_other as a be-all-end-all solution, but in this particular case, I think it's a very good solution and I don't foresee any problems with it except for the additional overhead, which is minor. I will of course post an update if it doesn't work out how I expect it to. :) _________________________________________________________________ Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo From DGD Mailing List Sat Feb 21 09:37:01 2004 From: DGD Mailing List (Erwin Harte) Date: Sat Feb 21 09:37:01 2004 Subject: [DGD] Re: varargs int ... On Sat, Feb 21, 2004 at 03:04:16AM -0500, Michael McKiel wrote: > Is it possible to test if a varargs int parameter was passed to a given > function or not? > I was playing around with a strstr() function, and seems I want to make it > work differently if the 2nd int variable wasn't passed ie: > string strstr(string str, int start, varargs int end) { > > if I don't pass it 'end' then the function should assume end = strlen(str)-1 > if I pass it end == 0, then it should return a nil string, since it would be > a zero length string. > But it seems all I can test for is !end > and that is true if I don't pass an end variable, and IF I pass it 0... > > So what am I missing? The only way I can see to be 100% sure what parameters were provided or not, is by using the ellipsis: string strstr(string str, int start, varargs mixed extra...) { int end; if (sizeof(extra) == 0) { /* No extra parameters provided. */ } else if (sizeof(extra) == 1 && typeof(extra[0]) == T_INT) { /* Extra parameter was provided and was an integer. */ end = extra[0]; } else { error("bad argument 3 to strstr"); } ... } The next best thing is: string strstr(string str, int start, varargs mixed end) { if (end == nil) { /* Varargs parameter omitted or 'nil' value used. */ } else if (typeof(end) == T_INT) { /* Extra parameter provided and was an integer. */ } else { error("bad argument 3 to strstr"); } ... } But then you can't distinguish between strstr("foo", 1, nil) and strstr("foo", 1). If you don't care about that distinction, then by all means go ahead and use that approach. ;-) Hope that helps, Erwin. -- Erwin Harte From DGD Mailing List Sat Aug 28 11:08:01 2004 From: DGD Mailing List (Steve Wooster) Date: Sat Aug 28 11:08:01 2004 Subject: [DGD] Making my own function types At 07:48 AM 8/25/2004, you wrote: >Is there any function type that doesn't do anything special? >I've built a permission system and I want to be able to specify what >functions that can't be called by all objects, without having to create a >database of those functions. >Is there any way to check what type a function is? > >Regards, >Ludvig Lejon I don't know if this would be acceptable to you, but here's an idea... You could set it up, so that functions who's names start with _ (or secure_ or something else) require some kind of security check. EG, something like: void myfunc() { code; } void _myfunc() { code; } int valid_call( string funcname, object caller ) { return 1 or 0; } "myfunc" could be called without security restrictions, but "_myfunc" would need valid_call() to return 1. Of course, maybe instead of having a valid_call function in the object, you could put it in the master object or a security daemon. A way to do this might be: When an object is loaded, check through its function listing for functions who's names start with _. If an object has some, then call call_touch() in the object. When touch() is called in the driver, check if the function call starts with _, and if it does, call valid_call() in the object (or security daemon or whatever) to see if it's allowed. If it's not, then do error("You're not allowed to do that, you evil exploit-abuser! Go away! Shoo! Shoo!"). In any case, be sure to do call_touch() in the object again. I figure that's probably more efficient than masking call_other, since masking call_other will affect the performance of objects that don't care about security (which I presume are the majority). Unfortunately, I'm a newbie to DGD, so I don't know if this is the best way to do security. Hopefully somebody knowledgeable can back up or shoot down this idea. -Steve Wooster |