ID:132674
 
Myself and Lummox were recently discussing my latest DLL issues, which got pushed off two full pages on my browser =(. The problems are mostly two-fold.

Firstly, a library developer does not know what world security their library is running under, so they don't know the features that are available without user intervention to authorise use. In the case of Linux, those feature sets are hard and typically fast-failing. Take for example shell(). To use shell() in a library, you automatically have to assume -trusted world security on Linux of the game that is using your library, regardless of their deployment scenario. You currently have no programmatic means for graceful fallback, notifying the game developer at run-time etc if this requirement is not met. Deployment requirements on a library aren't ideal for BYOND libraries, but in the general case I don't think it's entirely unreasonable for a library to have some requirement on the environment it runs under. However, the problem comes in the case of accidental mis-configuration. Even if the developer of a game knows the library they use needs -trusted access, and relays that in documentation to hosts, the host may not implement that. The end result is a support burden on the game developer, all because he chose library X. obviously he's not going to make that mistake more than once, making libraries using -trusted features disadvantaged. In the case where it's the only way to implement some functionality, it makes that functionality practicably untenable in general BYOND games. A library that breaks your game is not a good library.

The shell() scenario described above can be handled by a read-only variable like world.security, which means you can operate some form of notification or graceful fallback for strictly -trusted features (although programmatically closing off the option for host authentication in -safe on Windows). This solution however doesn't strictly lend itself to the second bird in my DLL specific case, what if the DLL just isn't there?

So what I propose is some functionality that allows the programmer to test if a specific operation would manage to run. My ideal solution may look something like this:

/security_manager
proc
file_call_permitted(var/operation, var/filename)
proc_call_permitted(var/operation)
dll_call_permitted(var/dllname)

world
var/security_manager/security

world
New()
..()
if (world.security.dll_call_permitted("my.dll"))
call("my.dll","initialise_socket","1092")
else
world.log << "\[ERROR\] Cannot initialise auxillary socket."


As far as the API goes, it de-couples me as a developer from BYOND's internals. You could freely add new security levels of even more granular security options to DreamDaemon, and the security manager would handle the complexities of that, saving me as a developer dealing with a system potentially in flux (particularly in betas of functionality). In the case of DLLs, I can stop caring where it is on BYOND's DLL call path (trusted folder, next to the DMB, elsewhere) and thus the security consequences of that AND if you're on Windows you can trigger a prompt to the host who can accept / reject before the proc call returns to me, like currently. I always get the accurate permissions, and can handle the case where I am not permitted to call it.

shell() and company are flat procs in the sense their security model is pretty much "You need -X security", hence the proc_call_permitted() test. File operations vary depending on the path of the file, hence what is usable in -safe for one file is not in another. Hence file_call_permitted().

The security implementation can be changed with the interface mitigating most of the risk, making you as platform developers free to tweak that without making my job as a library developer unduly difficult, and without needing to notify me in advance through notices or deprecation. Plus, as a separate object, there is potential for developers to extend the security manager at some later point if you want to go that way, to add their own permitted procs for libraries in a centralised implementation, and the object of course avoids polluating the world object namespace as it grows.

Aside from maybe the interface details (I can imagine cases where it needs generalising / expanding), any questions or problems with this approach?
I rather like the idea. It makes things incredibly easier. Most of the time when I release a game to my inner circle of doom, I'm forced to make them run in trusted mode as I'm either just unsure if something will work without it, or it's a requirement from something I end up doing.

This approach would save a lot of headaches.
I also have to agree with this; my game uses a fair amount of external sources, one for parsing, and the rest for logs, mostly. I think this'd save on a lot of mental trauma (:o) and time.
I like the idea, just as long as it doesn't allow someone to include a .dll, and force clients to download said .dll.
I can imagine many developers would love to handle things via .dll, instead.
Although, I do wonder what the possibilities of this would be since I don't understand .dlls on a more advanced level.
Stephen001 wrote:
AND if you're on Windows you can trigger a prompt to the host who can accept / reject before the proc call returns to me, like currently. I always get the accurate permissions, and can handle the case where I am not permitted to call it.

So you're basically asking for it to work exactly how it works now, except with knowledge of if permission was granted or not?
I've never really had any trouble with permission issues, though I never use any DLLs. And run my games in Safe mode.
In response to Falacy
Not quite, "Exactly how it works now" means if you call a DLL and it's not there, or you don't have permissions to call it, it proc crashes.

If I write a nice high performance inter-server messaging library with a DLL and sockets (might be something you'd be interested in, not sure), you wouldn't think it was a very good library if it just silently fell over because you accidentally forgot to run trusted, or the DLL was in the wrong place. That is what happens currently, as a library developer I can't recover from that situation and for example ... push messages through world/Topic as a slow option that at least means your game isn't broken.
I'm gonna have to give a thumbs up for this as well. I use plenty of BYOND dll calls to do tasks in which I deem BYOND inefficient(Text functions are generally a lot faster in C or C++). Being able to tell the average host why something is not working is actually saves most of them a lot of pain and suffering to look around everywhere to see where they and/or the developer has went wrong.
This is an excellent idea of a much needed feature. Plenty enough people support the idea, so surely there's enough reason to implement it?