At the time of this writing, data lock has been seen only once in the wild. In that instance, a widely used object (call it WUO),contained one piece of mutable state and one piece of immutable state. The object that computed new versions of WUO's mutable state needed the immutable part of the state, and requested the current version of WUO from the owner of the object. Unfortunately, the owner knew that a new version was under construction, and was only sending out promises for WUO until the update was resolved. The solution in this case was to refactor WUO. This resulted in an architecture that was cleaner even by normal object design criteria, without regard to the distributed usage behavior. Insufficient data is yet available to assess how commonly this type of solution will suffice.
E uses capability based security to supply both strong security and broad flexibility without incurring performance penalties. Capabilities might be thought of as the programming equivalent of physical keys, as described with the following metaphors.
Principle of Least Authority (POLA)
When you buy a gallon of milk at the local 7-11, do you hand the cashier your wallet and say, "take what you want and give me the rest back?" Of course not. In handing the cashier exact change rather than your wallet, you are using the Principle of Least Authority, or POLA: you are giving the cashier no more authority than he needs. POLA is a simple, obvious, crucial best-practice for secure interactions. The only people who do not understand the importance of POLA are credit card companies (who really do tell you to give that far-off Internet site all your credit, and hand back what they don't want), and computer security gurus who tell you to use more passwords.
Suppose all security in the physical world were based on ID badges and ID readers. At your home you might put an ID reader on your door, another on your CD cabinet, and another on your gun vault. Suppose further you had to depend on 4-year-old children to fetch your CDs for you when you were at the office. How would you do it? You would hand your ID badge to the child, and the child could then go through the front door and get into the CD cabinet. Of course, the child with your ID badge could also go into the gun vault. Most of the children would most of the time go to the CD cabinet, but once in a while one would pick up a gun, with lamentable results.
In the real physical world, if you had to depend on children to fetch CDs, you would not use an ID badge. Instead you would use keys. You would give the child a key to the front door, and a key to the CD cabinet. You would not give the child a key to the gun vault.
All current popular operating systems that have any security at all use the ID badge system of security. NT, Linux, and Unix share this fundamental security flaw. None come anywhere close to enabling POLA. The programming languages we use are just as bad or worse. Java at least has a security model, but it too is based on the ID badge system--an ID badge system so difficult to understand that in practice no one uses anything except the default settings (sandbox-default with mostly-no-authority, or executing-app with total-authority).
The "children" are the applications we run. In blissful unawareness, we give our ID badges to the programs automatically when we start them. The CD cabinet is the data a particular application should work on. The gun vault is the sensitive data to which that particular application should absolutely not have access. The children that always run to get a gun are computer viruses like the Love Bug.
In computerese, ID badge readers are called "access control lists". Keys are called "capabilities". The basic idea of capability security is to bring the revolutionary concept of an ordinary door key to computing.
Let us look at an example in a computing context, of how keys/capabilities would change security.
Consider the Melissa virus, now ancient but still remembered in the form of each new generation of viruses that use the same strategy the Melissa used. Melissa comes to you as an email message attachment. When you open it, it reads your address book, then sends itself - using your email system, your email address, and your good reputation - to the people listed therein. You only had to make one easy-to-make mistake to cause this sequence: you had to run the executable file found as an attachment, sent (apparently) by someone you knew well and trusted fully.
Suppose your mail system was written in a capability-secure programming language. Suppose it responded to a double-click on an attachment by trying to run the attachment as an emaker. The attachment would have to request a capability for each special power it needed. So Melissa, upon starting up, would first find itself required to ask you, "Can I read your address book?" Since you received the message from a trusted friend, perhaps you would say yes - neither Melissa nor anything else can hurt you just by reading the file. But this would be an unusual request from an email message, and should reasonably set you on guard.
Next, Melissa would have to ask you, "Can I have a direct connection to the Internet?" At this point only the most naive user would fail to realize that this email message, no matter how strong the claim that it came from a friend, is up to no good purpose. You would say "No!"
And that would be the end of Melissa, all the recent similar viruses, and all the future similar viruses yet to come. No fuss, no muss. They would never rate a mention in the news. Further discussion of locally running untrusted code as in this example can be found later under Mobile Code.
Before we get to mobile code, we first discuss securing applications in a distributed context, i.e., protecting your distributed software system from both total strangers and from questionable participants even though different parts of your program run on different machines flung widely across the Internet (or across your Intranet, as the case may be). This is the immediate topic.
There are a couple of fundamental concepts that must be gotten right by a programming language in order to use capability discipline. We mention these here.
Pointer arithmetic is, to put it bluntly, a security catastrophe. Given pointer arithmetic, random modules of code can snoop vast spaces looking for interesting objects. C and C++ could never support a capability system. Java, Smalltalk, and Scheme, on the other hand, did get this part of capability discipline right.
In a capability language you can not reach inside an object for its instance variables. Java, Smalltalk, and Scheme pass this test as well.
In JavaScript, as a counterexample, all instance variables are public. This is occasionally convenient but shatters any security hopes you might have. JavaScript is a relatively safe language only because the language as a whole is so thoroughly crippled. We consider JavaScript safe, but not secure: We consider security to require not only safety but also the power to get your work done: POLA means having enough authority, as well as not having too much. Using this definition of security, the Java applet sandbox is mostly safe, but not at all secure. And a Java applet that has been allowed to run in a weaker security regime because the applet was "signed", is neither safe nor secure.
In a capability system, the only source of positive authority for an object should be the references that the object holds.
Java fails here, along with Smalltalk and Scheme. A famous example of the trouble that static mutable state can get you appeared in Java 1.0 (corrected in 1.1, an upward compatibility break so rarely used they could get away with it). The object System.out, to which people routinely sent print messages, was replaceable. A programmer in the middle of a bad hair day could easily replace this object, reading everything everyone else was doing, and preventing anyone else from reading their own outputs.
You can make everything else right, but if the APIs for a language were designed without consideration of security, the capability nature of the system is seriously flawed. Let us consider an example in Java. Suppose you had an analysis program that would present graphs based on the contents of an existing spreadsheet. The program only needs read access on the one spreadsheet file, it needs nothing else in your file system. In Java, then, we would grant the application an InputStream.
Unfortunately, an InputStream in Java leaks authority. In this example, you could "cast down" to a FileInputStream, from which you could get the File, from which you could get a WriteStream and a whole filepath, which would give you total access and control over the entire directory system.
To fix this problem for a single object in a single application, you could write your own InputStream class that doesn't leak. This strategy does not scale, however: requiring the programmer to write replacements for every object in the API to achieve security will result in few secure programs (just as requiring the programmer to write his own bitmap handlers and gui widgets will result in few point-and-click programs). To really fix this security problem in Java, you would have to rewrite the entire java.io package, wrecking backward compatibility as a side effect. Without that kind of massive, serious repair, it is always easier to create a breach than to create a secure interaction. With an infrastructure actively trying to harm you, what chance do you really have?
E has no pointer arithmetic. E has no mutable statics. E has an API carefully thought out to prevent capability leaks. This would make it a capability secure language for single-processor applications. But E goes a step further. It takes the concept of a secure, unforgeable object reference and extends it to distributed objects:
These aspects of E protocol can be understood better by looking at the URI that identifies an E object to other objects outside its own vat.
There is no such thing as a free lunch, but this does not rule out the possibility of lunches at bargain prices. When programming in E, you are automatically working in a capability secure environment. All references are secure references. All powers are accessible only through capabilities. Making an E program secure is largely a matter of thinking about the architecture before you code, and doing a security audit after you code. When designing and auditing you use a small number of principles for scrutinizing the design:
The Principle of Least Authority (known henceforth as POLA), which has been used by human beings instinctively for thousands of years, translates to computer programs fairly straightforwardly: never give an object more authority than it needs. In particular, if an object may be running on a remote untrusted machine, think very carefully about the minimum set of authorities it needs, and give it capabilities only on facets (described later) that ensure it gets no more. A simple word processor needs read and write access to the one file it is being used to edit, and it needs read-only access on all the system fonts. It does not need any access to anything else. Do not give it access to anything else. If it asks for something else, it is lying to you, and you should not trust it.
When developing software, remember that the person who controls the hardware always, at the end of the day, controls the software.  They can modify the code you gave them, or rewrite it from scratch yet make it look from the outside like it is identical. You must therefore think carefully about what features of your system you really trust on that remote machine. A key feature of E that enhances its reliability is that objects which are manufactured in a particular vat remain resident in that vat, so that the objects remain as reliable as the objectMakers used to produce them. Only transparent immutables (immutables that don't encapsulate anything) actually move across computational boundaries.
Many people have made the error of believing this principle of hardware ownership can be circumvented. At the time of this writing, the music recording industry is throwing away truly fabulous sums of money on schemes that assume they can somehow control data after it has arrived on a user's own hardware. Microsoft is busily developing Palladium (uh, I mean, NGSCB). Intel is busily developing TCP (uh, I think they changed the name to La Grande). Their fate has already been foretold in the fate of the popular game Diablo I: authoritative representations of data were allowed to reside on user computers, assuming that the object code was too difficult to understand to be hacked and that the Diablo client code would always behave as the designers intended. They were 99% correct, which in the computer security field means they were 100% wrong. Today, 99% of the people who hack Diablo I don't understand the object code. But somewhere some single individual figured it out and posted the result on the Web. Now your grandmother can sabotage shared Diablo I games as quickly and easily as the most accomplished hacker in history. For Diablo II, the developers had learned the lesson. Authoritative information is stored only on the server, giving them the beginnings of true security.
Not only does hardware own the software, so too does the underlying operating system. As we have stated repeatedly here, E enables the construction of extremely secure computing systems. However, E systems can still be attacked from below, by viruses granted authority by the operating system underneath the E world. Such attacks can only be prevented by completing the security regime, either with capability-based operating systems, or with computers on which only capability-secure programs are allowed. There is one open-source capability-based OS under development, at www.eros-os.org.
One form of attack that even E cannot defend against is denial of service (DOS). In a denial of service, someone simply swamps your system with requests, making your system unable to operate. Such attacks take many forms, but the key limitation in such attacks is this: such an attack can never steal your secret data or gain control of your sensitive operations. If DOS were the only kind of attack possible, the world would be a vastly better place. Indeed, if only DOS attacks were possible, even most modern DOS attacks would fail, because the serious DOS attacks require that the attacker first gain control of hundreds of computers that belong to other people, by using attacks far more invasive and damaging than DOS itself.
The minChat application presented earlier as the example for a distributed system was designed with no consideration at all for security issues. This is literally true: minChat is derived from eChat, which was written by the author as his first practice exercise to learn E. However, because eChat was written in a capability secure environment, because the author used a fairly clean modular architecture, and because clean architecture in a capability-secure infrastructure makes its own luck, there were no serious security breaches in eChat. And, as we shall see, there are no serious security breaches in minChat, though there are many interesting lessons we can learn from it.
First of all, in minChat as in all E programs, the communication is all encrypted and the objects are all unfindable and unguessable. Therefore no third party can enter the conversation to either eavesdrop or forge messages. The only source of security breach will be the person at the other end of the chat system, i.e., the person with whom you planned to chat. So, right off the bat, simply by using E you have eliminated outsider attacks. But insider attacks are still possible, and indeed constitute the most serious threat to most security systems anyway. You have to be able to achieve cooperation in the presence of limited trust. Cooperation despite limited trust is something we humans achieve every day, for example when paying 3 bucks for a gallon of milk at the local QwikMart. But it is notoriously difficult to get these transactions working correctly on computer systems when using conventional languages. So we will examine minChat very closely to ensure that the person we want to chat with does not also get any inappropriate powers, like the ability to delete all our files.
Now, let us begin with a quick review of minChat's code to see what parts of the system we need to examine to do a security review. As you may recall from the chapter on Ordinary Computing, emakers come into existence with no authority whatsoever, and receive authority only via the arguments that are passed into their objects. In larger programs, one can often ascertain that the emaker receives so little authority it can be disregarded from a security perspective: if it doesn't have enough authority, it just can't be a danger (as documented in the DarpaBrowser Final Report and Security Review).
MinChat is just 2 pages of code. It does not use emakers, so this does not help in our current situation. However, what does help is that the only object accessible to the outside world is the chatController, whose reference is sent to the friend (or, in this case, perhaps the enemy) with whom we wish to chat (hey, we need to talk to our enemies too, from time to time). What unpleasantness can our friend do on our computer through the chatController interface he receives? We will reproduce the crucial lines of code here for convenience:
to send(message) { when (friend<-receive(message)) -> { chatUI.showMessage("self", message) } catch prob {chatUI.showMessage("system", "connection lost")} } to receive(message) {chatUI.showMessage("friend", message)} to receiveFriend(friendRcvr) { bind friend := friendRcvr chatUI.showMessage("system", "friend has arrived") } to save(file) {file.setText(makeURIFromObject(chatController))} to load(file) { bind friend := getObjectFromURI(file.getText()) friend <- receiveFriend(chatController) }
There are only 5 messages here. Let's go through what our friend could do with each one of them in sequence.
So, our friend can crash minChat, but can't do any serious harm: an attack whose only result is to cut off the target from the attacker's attacks hardly constitutes a winning gambit.
The upshot is, even the friend who has received the capability to talk to our chat tool doesn't get much traction. He can annoy us (by crashing minChat), but that is pretty much the only interesting thing he can do....or so it seems on first review.
Let's see if there is anything exotic an attacker could do by combining several of these unimportant attacks. First let us make the problem more concrete. Suppose Bob has a crush on Alice, who is dating Ted. Bob decides to make Alice think that Ted doesn't really like her. So he gives Alice his chat reference to Ted, and tells her that, when using this reference, Ted will think she is really Bob, and so Alice will be able to get Ted to "speak candidly" (to Bob) about her. At this point, Bob uses the "send" method on Ted's computer to send messages that Alice will read, messages that look to Alice like Ted is sending them! Bob sends cruel jokes about Alice, and Alice breaks up with Ted.
Hmmm....it looks pretty bad for Ted. Did we just find a really cool attack?
Well, sort of. First there is the risk that Ted will notice that his chat tool is, without any help from the owner sending offensive messages to Bob. Ted might then wonder what is going on. But more fundamentally, Bob has a much simpler scheme for messing with Alice's headspace, if Alice is open to this type of attack.
Far simpler for Bob would be to create 2 brand new chat capabilities, one that is Bob's FakeTed, and the other is Bob's FakeBob. He has Alice start up as FakeBob, and Bob himself starts up FakeTed. Now Ted is completely out of the loop, Bob can send any horrid thing to Alice he wants to send, without interference.
So is this a fundamental flaw with the entire E security approach? Not exactly. This attack can be made regardless of the technology being used -- Bob could have created 2 Yahoo Instant Messenger accounts and played the same game. Indeed, variations on this attack were used repeatedly by William Shakespeare throughout his career to create both high tragedy and low comedy. The fundamental problem comes when you trust a middleman as the sole validation of the authenticity of messages coming from another person. This is a human problem, not a technology problem. The best source of contact information for a person is the person him/herself; trust a third party at your own risk. Often the risk makes sense, but don't ever forget there is a risk there, whether you are using capability security or just a parchment and quill.
We have come full circle to the conclusion that minChat doesn't have any serious security breaches. Nonetheless, there are a couple of annoying things Bob may do to Ted. These annoyances can be traced directly to the presence of five messages in the chatController: there are only two messages out of the five that the friend is "supposed" to use. Even forgetting about security reviews for a moment, it is clear that, if the friend is only supposed to have two methods, he should not have five methods at his disposal. This make sense from a simple modular design point of view, it limits the number of mistakes you can make. For the security reviewers, this is an enormous win, because it reduces the number of methods to examine by 60%. This is a substantial gain, given how circuitous and complicated security analysis can become.
So how do we cut the number of methods available to the friend? By using a facet of the chatController that only has the appropriate methods:
# E syntax # Place the following object above the binding of the chatController def chatFacet { to receive(message) {chatController.receive(message)} to receiveFriend(friendRcvr) {chatController.receiveFriend(friendRcvr)} } # Now modify the chatController's save method to save the chatFacet, not the chatController: to save(file) {file.setText(makeURIFromObject(chatFacet))} # and similarly modify the load method to send the chatFacet not the chatController: to load(file) { bind friend := getObjectFromURI(file.getText()) friend <- receiveFriend(chatFacet) }
This version of minChat is more secure (only a little more secure, though, since it was pretty secure already), and vastly easier to review.
There are still a number of interesting lessons we can learn here by considering some variations on minChat. The first variation is based on the old adage, "You can write FORTRAN in any language." This is true in E as well, but the implications can be grievous.
Let's go back the minChat without the chatFacet, and consider the following small change to the program. Suppose that the save method in the chatController, instead of receiving a file object from the chatUI and creating the uri string itself, received the file path and the uri string from chatUI:
# E syntax to save(filePath :String, uri :String) { <file: filePath>.setText(uri)}
This is a fairly FORTRAN-ish way of accomplishing the goal: since FORTRAN doesn't have objects, it may seem perfectly obvious and reasonable to just send the path to the file and let the chatController figure out how to write to that file on its own.
However, in this situation, it is a disaster. Without the chatFacet, now the friend at the far end has a method he can call that allows him to write any data he wants, into any location the user can reach on his own computer:
# on the friend's machine # put the code for the SubSevenServer Trojan in a string def code :String := "@#$!...and so on, the character representations of the code bytes" # The friend's friend is our poor user # Put the trojan horse in the user's startup profile friend <- save("~/startup/sub7.exe", code)
Now we're having some fun! Every time the user logs onto his computer, the friend gets full control of all his resources.
What went wrong here? There are several ways of slicing the pie and pinning different pieces of the code with blame. One we have already identified: we failed to follow POLA in allowing the friend to call the save method in the first place. But another one is just as crucial: we failed to follow POLA twice with this revised version of the save method that gets 2 strings.
We failed first by sending the save method an insufficient amount of authority (remember, Least Authority also means Adequate Authority). We did this by sending the chatController a string describing the file's path rather than just sending him the file itself. As a consequence, the chatController had to use special powers gotten from elsewhere to translate the description into a file object.
Once the chatController had to do this translation, it became vulnerable to the Confused Deputy Attack, a classic in security literature. The Confused Deputy attack is the aikido move of computer security: the attacker persuades the target to use the target's own authority against itself. Confused Deputy attacks are very hard to pull off as long as a single reference serves as both the designation of the object and the authority to use the object (as is always the case with the objects in a capability-based programming language). But when the authority to use the object is separated from the designation, as it is when a path string is being used to describe the file, you are in deep trouble.
Simply sending the file object rather than the file description solves this problem. The friend at the far end has no way to send an object that will be interpreted by the save method as a local file, and so the friend gets no traction whatsoever as long as the save method is expecting the object not the description. This leads to the general rule:
When you must read in the descriptions of objects rather than the objects themselves, translate them into capability secure objects at the earliest possible moment. When you must write out descriptions of objects rather than the objects themselves, postpone the translation of the object into a description until the last possible moment.
This rule is not merely good for secure, capability-oriented programming. Rather, it is good for all object-oriented programming. Manipulating the descriptions of objects is much less reliable, and much more error prone, than direct manipulation of the object itself--which is both why crackers like it, and object oriented designers avoid it. This exemplifies an interesting truth: capability oriented development is often just object oriented development taken seriously.
Working directly with the object, not a description, is a rule the author learned the hard way. A security review team ripped numerous holes in a single piece of the author's software, simply because the author foolishly worked with descriptions rather than with objects. The story is told in excruciating detail in the DarpaBrowser Security Review. If you are one of the rare and lucky individuals who are able to learn from other people's mistakes, rather than having to make the mistakes firsthand yourself first before you really get it, this is a magnificent lesson to learn secondhand.
In large software systems, most objects are constructed inside emakers, rather than in the main E program body. Consequently they come to life with severely restricted, POLA-oriented authority(i.e., only the authority we send to them when we construct them, which tends to be what they need but not anything else). Let us emulate this characteristic of large systems in our little minChat by making a paranoid version of the chatFacet:
This is grossly broken syntax for eval
# E syntax def makeFacet := e` def makeFacet(chatController) { def chatFacet { to receive(message) {chatController.receive(message)} to receiveFriend(friendRcvr) {chatController.receiveFriend(friendRcvr)} } return chatFacet } `.eval(universalScope) def chatFacet := makeFacet(chatController)
The universalScope eval method creates the makeFacet function in strict confinement, identical to the confinement imposed on emakers. Consequently, the only authority the chatFacet has is the authority handed in, namely, the authority to send messages to the chatController.
Now let's assume we are running a more complex program, with a more complex component, i.e., a component that is not so simple we can just look at it and see it doesn't do anything very exciting. Now let's further assume that by some extraordinary bit of legerdemaine the attacker succeeds in completely subverting the component (the chatFacet in our little example). How terrible is the disaster?
As we have already shown, there is no disaster. Even if the attacker gets direct access to the chatController, there still isn't anything interesting he can do. We have achieved defense in depth. A typical penetration of our system gives the attacker only a limited access to other objects, which in turn must be individually penetrated.
Compare this to the situation now typical in software engineering. Even with the most modern "secure" languages like Java and C#, an attack can acquire the full authority of the program by subverting even the most inconsequential object. With tools like access control lists and firewalls, we engage in "perimeter defense", which is more correctly described as "eggshell defense".  No wonder cybercrackers laugh at our silly efforts to defend ourselves. We have thrown away most of our chances to defend ourselves before the battle even begins.
As discussed in the minChat security review, facets are objects that act as intermediaries between powerful objects and users that do not need (and should not be granted) its full power. We saw a facet in use in the audited version of the eChat program, where the chatFacet. was interposed between the chatController and the remote chat participant. Here is a little general-purpose facet maker:
# E sample /** * <param> target is the underlying powerful object * <param> allowedMethods is a map. The key is a method name, the value * is the set of allowed numbers of arguments. So ["receive" =>[0, 2].asSet()] * would allow the receive method, with either 0 or 2 arguments, to be forwarded. **/ def makeFacet(target, allowedMethods) { def filteringFacet { match [verb, args] { if (allowedMethods.maps(verb) && allowedMethods[verb].contains(args.size())) { return E.call(target, verb, args) } } } return filteringFacet } def chatController def chatFacet := makeFacet(chatController, ["receive"=>[1].asSet(), "receiveFriend"=>[1].asSet()])
Facets of this type can be retrofitted onto an existing system. We did this with very little effort for minChat with the chatFacet, but the technique works for far more complicated problems as well. The capability-secure windowing toolkits that E has placed on top of Swing and SWT uses facetization as the main tool.
Facets can be made much more sophisticated in their restrictions on access to their underlying object. You can make a facet that logs requests and sends email when certain methods are called. In an SEC-regulated stock exchange facet, you might wish to grant the capability to make a trade only from 9AM to 3PM excluding weekends and holidays.
One interesting example is the use-once facet, which allows the holder of the facet to use the facet only one time. For example, this version of a chatReceiver only allows a single message to be sent:
# E sample def onceOnlyReceiver(baseChatController) { var chatController := baseChatController def onceOnlyReceiver { to receive(text) { chatController.receive(text) chatController := null } } }
This version will throw an exception back to the sender of a second message.
It can be tempting in a facet to suppress a couple of powerful methods in the underlying powerful object and delegate the rest.
# E sample def powerfulObject { to doPowerfulOperation() { #do powerful operation } to doWeak1() {} to doWeak2() {} to doWeak3() {} #.... to doWeak99() {} } def badFacet extends powerfulObject { to doPowerfulOperation() { #do nothing, no forwarding for the powerful operation, but forward everything else } }
Avoid this. For a facet to remain secure during maintenance, it should never just delegate by default. If a new method is added to a powerful object (in this example, suppose powerfulObject is updated with a new method, doPowerful2()), it should not be exposed through the facet by default: rather, the facet must by default not expose it.
This risk can be exhausting to avoid, but it is always dangerous to accept. The first version of the capability windowing toolkit on Swing suppressed the handful of dangerous methods in the Java version 1.3 of Swing rather than explicitly allowing the safe methods, of which there were thousands. Within 30 days, the entire system was broken: the Java 1.4 Beta included hundreds of new, security-breaking methods. The only saving grace was that we had always known that the first version, thrown together in haste on weekends, was just a proof-of-principle and would have to be replaced. We just hadn't appreciated how soon replacement would be required.
If you wish to give someone restricted access to an object with facets, it is quite likely you will want to revoke access at some point as well.
The simplest way of making a capability revocable is to use a transparent forwarder that includes a revocation method:
# E sample def revocableCapabilityMaker(baseCapableObject) { var capableObject := baseCapableObject def forwarder { to revoke() {capableObject := null} match [verb, args] {E.call(capableObject, verb, args)} } return forwarder }
Note that, even though the forwarder is nominally delegating all method invocations (except revoke()) to the capableObject, we cannot use the extends keyword to capture the behavior. "Extends" creates an immutable reference, so the fact that the capableObject is a var wouldn't allow you to revoke the delegating behavior. Instead we use the match[verb, args] pattern.
Capability revocation, like facet forwarding, can be based on complex sets of conditions: revoke after a certain number of uses, revoke after a certain number of days. This example uses a simple manual revocation. Indeed, this version is too simple to work reliably during system maintenance and upgrade, and a more sophisticated pattern is generally recommended:
# E sample def makeCapabilityRevokerPair(baseCapableObject) { var capableObject := baseCapableObject def revoker { to revoke() {capableObject := null} } def forwarder {match[verb, args] {E.call(capableObject, verb, args)}} return [forwarder, revoker] } def powerfulObject { #...big powers } def [power, revoker] := makeCapabilityRevokerPair(powerfulObject)
In this pattern, the authority of the object and the authority to revoke are separated: you can hand the power to revoke to an object you would not trust with the authority itself. Also, the separate revoker can itself be made revocable.
A sealer/unsealer pair makes it possible to use untrusted intermediaries to pass objects safely. Use the sealer to make a sealed box that can only be opened by the matching unsealer. E has built-in support for sealer/unsealer pairs:
? def makeBrandPair := <elib:sealing.makeBrand> # value: <makeBrand> ? def [sealer, unsealer] := makeBrandPair("BrandNickName") # value: [<BrandNickName sealer>, <BrandNickName unsealer>] ? def sealedBox := sealer.seal("secret data") # value: <sealed by BrandNickName> ? unsealer.unseal(sealedBox) # value: "secret data"
If you hold the unsealer private, and give the sealer away publicly, everyone can send messages that only you can read. If you hold the sealer private, but give the unsealer away publicly, then you can send messages that recipients know you created, i.e., you can use it as a signature. If you are thinking that this is much like a public/private key pair from public key cryptography, you are correct, though in E no actual encryption is required if the sender, recipient, brand maker, and sent object all reside in the same vat.
While the Brand is built-in, it is possible to construct a sealer/unsealer pair maker in E without special privileges. The "shared variable" technique for making the maker is interesting, and because the same pattern appears in other places (such as the Notary/Inspector, coming up next), we demonstrate it here:
# E sample def makeBrandPair(nickname) { def noObject{} var shared := noObject def makeSealedBox(obj) { def box { to shareContent() {shared := obj} } return box } def sealer { to seal(obj) {return makeSealedBox(obj)} } def unsealer { to unseal(box) { shared := noObject box.shareContent() if (shared == noObject) {throw("invalid box")} def contents := shared shared := noObject return contents } } return [sealer, unsealer] }
The variable "shared" normally contains the value "noObject", which is private to a particular sealer/unsealer pair and so could never the the actual value that someone wanted to pass in a sealed box. The unsealer tells the box to shareContent, which puts the content into the shared variable, from which the unsealer then extracts the value for the invoker of the unseal method. In a conventional language that used threads for concurrency control, this pattern would be a disaster: different unseal requests could rumble through, overwriting each others' shared content. But by exploiting the atomicity of operational sequences enabled by promise pipelining, this peculiar pattern becomes a clean solution for this, and several other security-related operations.
Suppose Bob is the salesman for Widget Inc. He persuades Alice to buy a widget. Bob hands Alice a Widget Order Form with a money-receiving capability. It is important to Bob that Alice use the form he gives her, because this particular form (which Bob got from Widget Inc.) remembers that Bob is the salesman who should get the commission. It is important to Alice that she know for sure that, even though she got the order-form from Bob, this is really a Widget Inc. order form, and not something Bob whipped up that will transfer her money directly to his own account. In this case, Alice wants to have Widget Inc. vouch for the order-form she received from Bob. She does this using an Inspector that she gets directly from Widget Inc. The Inspector is the public part of a notary/inspector pair of objects that provide verification of the originator of an object. To be vouchable, the orderForm must implement the startVouch method as shown here:
# E sample ####### Widget Inc. software ##### #vouching system #returns a private notary that offers a public inspector #throws problem if the object being vouched is not vouchable def makeNotary() { def nonObject {} def unvouchedException(obj) {throw(`Object not vouchable: $obj`)} var vouchableObject := nonObject def inspector { to vouch(obj) { vouchableObject := nonObject try { obj.startVouch() if (vouchableObject == nonObject) { return unvouchedException(obj) } else { def vouchedObject := vouchableObject vouchableObject := nonObject return vouchedObject } } catch err {unvouchedException(obj)} } } def notary { to startVouch(obj) { vouchableObject := obj} to getInspector() {return inspector} } return notary } #create Widget Inc's notary def widgetNotary := makeNotary() #Order form maker def makeOrderForm(salesPerson) { def orderForm { # .... methods for implementing orderForm to startVouch() {widgetNotary.startVouch(orderForm)} } return orderForm } #publicly available inspector object #(accessible through a uri posted on Widget Inc's web site) def WidgetInspectionService { to getInspector() {return widgetNotary.getInspector()} } ##### bob software ##### #scaffold for sample def getOrderFormFromBob() {return makeOrderForm("scaffold")} ########## Alice's software to vouch for the order form she received from Bob ##### def untrustedOrderForm := getOrderFormFromBob() def inspector := WidgetInspectionService.getInspector() def trustedOrderForm := inspector.vouch(untrustedOrderForm)
"Proof of Purchase" is the simplest of a series of capability patterns in which the goal is not to transfer an authority, but rather to show someone that you have the authority so that they can comfortably proceed to use the authority on your behalf. In Proof of Purchase, the requester of a service is demonstrating to the server that the client already has capability that the server is being asked to use. Unlike the more sophisticated upcoming Claim Check patterns, the proof of purchase client is not concerned about giving the server an excess authority.
An interesting example of Proof of Purchase is Component.transferFocus(fromComponentsList, toComponent) found in the tamed Swing package. In standard Swing, the holder of any panel reference can steal the focus (with component.requestFocus()). Hence any keystrokes, including passwords, can be swiped from wherever the focus happens to be by sneaking in a focus change. This is a clear violation of POLA. You should be able to transfer focus from one panel to another panel only if you have references to both panels. If you have a reference to the panel that currently has the focus, then you can never steal the focus from anyone but yourself.
A natural-seeming replacement for component.requestFocus() would be requestFocus(currentFocusHolder). It was decided during the taming of Swing, however, that this would be breach-prone. If Alice transferred to Bob, not a panel itself, but rather a simple transparent forwarder on that panel, Alice could collect authorities to other panels whenever Bob changed focus.
Since we had a convenient trusted third party available that already had authority over all the panels anyway (the javax.swing.Component class object), we used the "proof of purchase" pattern instead. The globally available Component.transferFocus method accepts two arguments:
In the common case where a whole window lies inside a single trust realm, the client can simply present a reference to the whole window and be confident that the focus will be transferred.
The interesting thing about Component.transferFocus is that the recipient does not actually need the client's authority to reach the component that already has the focus. The Component class already has that authority. The client must send the authority merely to prove he has it, too.
A common activity that brings security concerns into sharp focus is the delicate dance we perform when we use a car valet service. In this situation, we are handing the authority over our most precious and costly possession to a teenager with no more sense of responsibility than a stray cat. The whole valet system is a toothsome exercise in POLA.
In this example, we focus on the sequence of events and trust relationships involved in reclaiming our car at the end of the evening. The participants include the car owner, the valet service itself, and the random new attendant who is now on duty.
We have already chosen, for better or for worse, to trust the valet service with a key to the car. As the random new attendant comes running up to us, we are reluctant to hand over yet another key to the vehicle. After all, this new attendant might actually be an imposter, eager to grab that new Ferrari and cruise out over the desert. And besides, we already handed the valet service a key to the car. They should be able to use the key they already have, right?
Meanwhile, the attendant also has a trust problem. It would be a career catastrophe to serve up the Ferrari from his parking lot if I actually own the dented 23-year-old Chevy Nova sitting next to it.
In the physical world, we use a claim check to solve the problem. We present to the attendant, not a second set of car keys, but rather, a proof that we have the authority that we are asking the attendant to use on our behalf.
# E sample def claimMgr := { def carKeys := [].asMap().diverge() def claimMgr { to makeClaim(car) :any { # the claim object has no interesting # properties except it has # a unique unforgeable identity def claim {} carKeys[claim] := car return claim } to reclaim(claim) :any { def car := carKeys[claim] carKeys.removeKey(claim) return car } } } def attendant { #return a claim check when car is parked to parkCar(car) :any { # ...code to park the car... return claimMgr.makeClaim(car) } to retrieveCar(claim) :void { def car := claimMgr.reclaim(claim) # ...code to retrieve car... # no need to return the car reference, the owner of the claim # presumably already has such a reference } } def car {} def carOwner := { var claim := null def carOwner { to letAttendantParkCar() :void { claim := attendant.parkCar(car) println(claim) } to getCarFromAttendant() :void { println(attendant.retrieveCar(claim)) } } } carOwner.letAttendantParkCar() carOwner.getCarFromAttendant()
Suppose the owner of the car loses the claim check. He can still prove he owns the car by presenting another key. In software, this situation would be comparable to the situation in which the owner hands the attendant a direct reference rather than handing the attendant merely the claim check. The car owner has violated his own security, but it is hard to visualize situations in which this is not a reasonable argument to pass to express his desire. We can cover this case with a small modification to the claimMgr's reclaim method:
to reclaim(claim) :any { try { def car := carKeys[claim] carKeys.removeKey(claim) return car } catch prob { if (carKeys.contains(claim)) { return claim } else {throw(prob)} } }
What should the claimMgr return if the carOwner hands in a car reference for reclaim, if the car is not actually in the claimMgr's parking lot? The answer depends on the application, but such a situation violates the expectations of all the participants sufficiently that throwing an exception seems the safest choice.
We are far from done with claim checks. A careful car owner will not actually hand his claim check to the parking lot attendant. Rather, he will merely show the claim check to the attendant. After all, if you hand the claim check over to an imposter, the imposter can turn around and hand the claim check to a real attendant, pretending that he is the owner of the car.
The problem is somewhat different in cyberspace. The good news is, in cyberspace the attendant doesn't return a reference to the car just because you hand him the claim check. Instead, he merely performs the action you ask of him with the car. This set of actions is limited by the attendant's willing behavior. So the claim check is not as powerful a capability as the car itself. But it can still be a powerful capability. And the bad news is, in cyberspace, you can't just "show" it to the attendant. You have to give it to him.
Here we demonstrate a "nontransferable" claim check. This claim check can be handed out at random to a thousand car thieves, and it does them no good. The trick is, before handing over the claim check, the owner inserts into the claim check a reference to the individual he is treating as an attendant. The ClaimMgr compares the person to whom the owner handed the claim, with the attendant who eventually hands the claim to the claimMgr . If these two people are the same, then the owner handed the claim directly to the attendant. Otherwise, there was an intermediary party, and the request should not be honored.
# E sample def makeBrandPair := <elib:sealing.makeBrand> def valetService := { def [claimSealer, claimUnsealer] := makeBrandPair("claim") def claimMgr { to makeClaim(car) :any { def transferableClaim { to makeNontransferableClaim(intendedRecipient) :any { return claimSealer.seal([car, intendedRecipient]) } } return transferableClaim } to reclaim(claim, actualRecipient) :any { def [car, intendedRecipient] := claimUnsealer.unseal(claim) if (actualRecipient == intendedRecipient) { return car } else {throw("claim not transferable, invalid attendant")} } } def valetService { to authorizeAttendant(attendant) :void { attendant.setClaimMgr(claimMgr) } } } def makeAttendant() :any { def claimMgr def attendant { to setClaimMgr(mgr) :void {bind claimMgr := mgr} to parkCar(car) :any { # ...code to park the car... return claimMgr.makeClaim(car) } to retrieveCar(claim) :void { def car := claimMgr.reclaim(claim, attendant) # ...code to retrieve car... # no need to return the car reference, the owner of the claim # presumably already has such a reference } } return attendant } def legitAttendant := makeAttendant() valetService.authorizeAttendant(legitAttendant) def carThief { to parkCar(car) :any { return println ("Ha! stole the car") } to retrieveCar(claim) :void { try { legitAttendant.retrieveCar(claim) println("Ha! didn't get car, but got control") } catch prob {println(`rats! foiled again: $prob`)} } } def carOwner := { def car{} var claim := null def carOwner { to letValetPark(attendant) :void { claim := attendant.parkCar(car) println(claim) } to letValetRetrieve(attendant) :void { def noTransferClaim := claim.makeNontransferableClaim(attendant) println(attendant.retrieveCar(noTransferClaim)) } } } carOwner.letValetPark(legitAttendant) carOwner.letValetRetrieve(carThief) carOwner.letValetRetrieve(legitAttendant)
Note an important implication in this pattern: the ClaimMgr winds up in a position to accumulate references to all the entities a claim check holder treats as an attendant. In this example, the ClaimMgr gets a reference to the carThief as a result of the carOwner's casual handing out of claim checks. It seems unlikely that the ClaimMgr can harm the carOwner's interests with this reference, but in other circumstances the reference may not be so harmless. To reduce our risk exposure to the alleged attendants to whom we hand the claim check, we have increased our risk exposure to the ClaimMgr.
Note also the limitations on the nontransferability of this pattern. The carOwner can still transfer authority, either by handing someone a reference to the car, or by handing out the transferableClaim from which nontransferableClaims can be made. The nontransferability is voluntarily chosen by the carOwner. You can't prevent people from delegating their authority, and even this pattern doesn't change that fact.
Let us consider a somewhat different problem. Suppose that different attendants are trusted to handle different cars by the valet service. One valet has a motorcycle license and parks all the Harleys. Another has a multi-engine pilot's license and parks all the Boeing 747s. Of course, the one with the motorcycle license is a teenager who has always wanted to try his hand at parking a 747, and knows his lack of experience is not a problem. In this situation, each attendant has a different set of authorities at his command; just because you hand your claim check to a legit attendant doesn't mean the valet service thinks it would be a good idea to let that attendant drive your vehicle. A more generalized way of stating the problem is, in this case the authorities of the individual receivers of the claim checks vary, and management of the individual receiver's authorities is beyond the scope of what the ClaimManager should be trying to figure out. After all, the individuals know all their own authorities; it would be poor design (and unmaintainable at scale) for the ClaimManager to try to duplicate this information.
This situation, while not a part of the real-world valet service problem, has a significant area of application in cyberspace. This area is Voluntary Oblivious Compliance, or VOC. Let us consider a more sensible example. Alice works for HPM, and Bob works for Intil. HPM and Intil are often competitors, but Alice and Bob are working on a joint project from which both companies expect to profit handsomely. The Official Policy Makers of HPM have identified a number of documents which can be shared with Intil, and indeed have forwarded to Intil references to the allowed docs. Alice wants to refer Bob to a particular HPM document, but only if sharing the document is allowed under the HPM policy. In this case, the VOCclaimCheck that Alice sends to Bob demands that Bob demonstrate to HPM's ClaimMgr that he already has authority on the document before fulfilling the claim. To prove his authority, Bob sends to the ClaimMgr all the HPM doc authorities he has (i.e., the list of docs HPM handed to Intil). Only if both Alice and Bob already have authority on the object does Bob get the document. This is sometimes called the Loan Officer Protocol, in reference to the old adage that a loan officer will not give you the loan unless you first prove that you don't need it.
Since bob can't get the reference unless he proves he doesn't need it, we can now see why this is a pattern of Voluntary Oblivious Compliance. It is voluntary, because Alice could just send Bob the document and circumvent the system. And it is oblivious, because Alice doesn't need to know whether a document can be shared with Bob before sending it.
Going back to the parking lot attendant who wants to park the 747, he has to demonstrate to the ClaimManager that he has the keys to the 747 before the Claim Manager will let him go for it. The owner of the 747 is much relieved.
Humorous as the 747 example might be, we will now switch to the scenario with Alice, Bob, HPM, and Intil for our sample code. The basic strategy is that the ClaimMgr not only examines the claim check from Alice, it also examines the list of authorities that Bob hands over to see if any of Bob's authorities match the one inside Alice's claim.
# E sample def makeBrandPair := <elib:sealing.makeBrand> def [claimSealer, claimUnsealer] := makeBrandPair("claim") def HPMDocClaimMgr { to makeClaim(doc) :any { return claimSealer.seal(doc) } to matchClaim(claim, listOfCandidates) :any { def doc := claimUnsealer.unseal(claim) for each in listOfCandidates { if (doc == each) {return each} } throw("No match from claimCheck to candidate auths") } } def intilSharedDocs := [def doc1{}, def doc2{}, def doc3{}] def bob { to lookAtHPMDoc(claim) :void { try { def doc := HPMDocClaimMgr.matchClaim(claim, intilSharedDocs) println(`reading doc: $doc`) } catch prob { println(`can't read: $claim`) } } } def alice { to sendDoc(doc, recipient) :void { def claim := HPMDocClaimMgr.makeClaim(doc) recipient.lookAtHPMDoc(claim) } } alice.sendDoc(doc2, bob) alice.sendDoc(def doc4{}, bob)
The oblivious claim check pattern can require scattering even more authority to the winds than the nontransferable claim check. The recipient of the claim check (bob) needs to have all the authorities that alice might give to him, rather than merely the ones she actually does give to him. And the trusted third party who matches the claim check against the list of possibilities (the HPMDocClaimMgr) gets to accumulate authority to everything that bob thinks alice might be trying to send him. In the example scenario, this is just fine. But some care is required.
An elegant style of using VOC claim checks is to set up the pattern as a pair of guards. Alice would use the ClaimCheck guard to send a reference to Bob, and Bob would use the CheckedClaim guard, with the list of candidate references, to receive the authority. We will show the implementation of the ClaimCheck and CheckedClaim guards in Advanced Topics when we talk about writing your own guards, but their usage would appear as follows:
# E syntax def bob { to lookAtHPMDoc(doc :CheckedClaim[intilSharedDocs]) :void { if (!E.isBroken(doc)) { println(`reading doc: $doc`) } else {println(`can't read: $claim`)} } } def alice { to sendDoc(doc, recipient) :void { recipient.lookAtHPMDoc(doc :ClaimCheck) } }
The ClaimCheck guard coerces the doc into a sealed representation of itself. The CheckedClaim guard unseals the claim and matches it against the authorities in the intilSharedDocs list. As a guard, it is better style to return a broken reference than to throw an exception if something goes wrong. In the parameter guard, if an exception were thrown, the recipient would have no chance to do anything with the problem, the exception would be thrown directly back to the sender before the recipient was even aware there was an issue.
It is possible to make nontransferable oblivious claim checks as well. We leave the code as an exercise for the reader.
The powerbox pattern collects diverse elements of authority management into a single object. That object, the powerbox, then becomes the arbiter of authority transfers across a complex trust boundary. One of the powerbox's most distinctive features is that it may be used for dynamic negotiations for authority during operation. The less trusted subsystem may, during execution, request new authorities. The powerbox owner may, in response to the request, depending on other context that it alone may have, decide to confer that authority, deny the authority, or even grant the request authority after revoking other authorities previously granted.
The powerbox is particularly useful in situations where the object in the less trusted realm does not always get the same authorities, and when those authorities may change during operation. If the authority grant is static, a simple emaker-style authorization step suffices, and a powerbox is not necessary. If the situation is more complex, however, collecting all the authority management into a single place can make it much easier to review and maintain the extremely security-sensitive authority management code.
Key aspects of the powerbox pattern include:
Not all kinds of objects in the Java API can be made directly revokable at this time, because an E revokable forwarder cannot be used in all the places where an actual authority-carrying Java object is required. For example, the untrusted object may want to create a new image from an url. The natural way of doing this would be to call the Java Icon class constructor with (url) as the argument. But if an E forwarder were handed to this class constructor, the constructor would throw a type exception.
Because of this anomally, different solutions are required in different situation. For the icon maker, it might be acceptable to require that the untrusted object read the bits of the image from the url (through a revokable forwarder) and then convert the bits into an icon.
In the following example, the less trusted object may be granted a Timer, a FileMaker that makes new files, and a url. The object may request a different url in the course of operations, in which case the powerbox will ask the user for authorization on the objects's behalf; the old url is revoked, and the new one substituted, so that the object never has authority for more than one url at a time. The object that operates the powerbox may revoke all authorities at any time, or it may choose to revoke the Timer alone. Finally, the operator of this powerbox may, for reasons external to the powerbox's knowledge, decide to grant an additional authority during operations, an authority whose nature is not known to the powerbox.
# E sample # The authorized url may change during operations, so it is a var def makePowerboxController(optTimer, optMakeFile, var optUrl, optMakeUrl, makeDialogVow) { # In the revokers map, the object being revoked is the key, the revoker # is the value. Note it is the actual object, not the forwarder to the # object, that is the key. var revokers := [].asMap() # when a revokable forwarder is made, the revoker is automatically # placed in the map of revokers def makeRevokableForwarder(object) :near { var innerObject := object def revoker { to revoke() {innerObject := null} } revokers with= (object, revoker) def forwarder {match [verb, args] {return E.call(innerObject, verb, args)}} return forwarder } # makeFileFacet is exposed to less trusted realm; guard the path it receives # This simple file facet only supplies 2 methods that return immutables # If the file handed out mutable objects, such as streams, these would have # to be wrapped with revokableForwarders as well. def makeFileFacet(path :String) :near { def theFile := optMakeFile(path) def fileFacet { to getText() :String {theFile.getText()} to setText(text :String) {theFile.setText(text)} } return makeRevokableForwarder(fileFacet) } # makeFile is actually handed to the less trusted object # It is either null or a revokable forwarder for makeFileFacet # In other words, makeFile is a revokable maker of revokable file facets def makeFile if (optMakeFile == null) { bind makeFile := null } else { bind makeFile := makeRevokableForwarder(makeFileFacet) } # Like the file facet, this url facet only supports methods that return # immutables. def makeRevokableUrlFacet(optUrl) :near { if (optUrl == null) { return null } else { def urlFacet { to getBytes() :pbc {optUrl.getBytes()} } return makeRevokableForwarder(urlFacet) } } # Return a vow for a new url # Use dialog with user to determine if new url should be granted # Vow resolves to null if anything goes wrong def makeRevokableUrlVow := { def makeUrlVow(requestedUrl :String, why :String) :vow { def urlDialogVow := makeDialogVow("Url Request", `<html> Confined Object requesting url for this reason:<p>$why </html>`, requestedUrl, ["Grant", "Refuse"]) return when (urlDialogVow) -> { if (urlDialogVow.getButton() == "Grant") { optUrl := optMakeUrl(urlDialogVow.getText()) makeRevokableUrlFacet(optUrl) } else {null} } catch prob {null} } return makeRevokableForwarder(makeUrlVow) } var caps := [].asMap() caps with= ("TIMER", makeRevokableForwarder(timer)) caps with= ("FILEMAKER", makeFile) caps with= ("URL", makeRevokableUrlFacet(optUrl)) def powerbox { # any of these capabilities may be null, i.e., all are optional # in a powerbox, strictly at the whim of the powerbox operator # who created the powerboxcontroller and the powerbox to optCap(key :String) :any {return caps.get(key, null)} # When the less trusted object requests a new url, the # old url is immediately revoked, and the promise for the # new url is substituted # If the powerbox has revokedAll, any attempt to requestUrl # will throw an exception back to the untrusted object # The "why" parameter is the less trusted object's justification # for needing the url to requestUrl(requestedUrl :String, why :String):vow { if (optUrl != null) {revokers[optUrl].revoke()} def revokableUrlVow := makeRevokableUrlVow(requestedUrl, why) caps with= ("URL", revokableUrlVow) return revokableUrlVow } } def powerboxController { to revokeAll() { for each in revokers {each.revoke()} } to revokeTimer() {revokers[timer].revoke()} # Confer an additional capability during execution to conferCap(key, cap) { caps with= (key, makeRevokableForwarder(cap)) } to getPowerbox() {return powerbox} } } # now, show how to create a powerbox and hand it to an untrusted object def makeUntrustedObject(powerbox) { def timer := powerbox.optCap("TIMER") def urlVow := powerbox.requestUrl("http://www.skyhunter.com") def untrustedObject { #... } return untrustedObject } def powerboxOperator() { def makeDialogVow {#...construct dialog vow } # use real objects, not nulls, in typical operation, though nulls are valid arguments def controller := makePowerboxController(null, null, null, null, makeDialogVow) def powerbox := controller.getPowerbox() def untrusted := makeUntrustedObject(powerbox) # later, confer an additional authority def special controller.conferCap("SPECIAL", special) # when done with the untrusted object, revoke its powers controller.revokeAll() }
Both the file facet and the url facet restrict the user to methods that return immutables. If these facets returned mutables, like streams, then those mutables would also have to be wrapped in revokable forwarders. In the general case, this requires the use of a membrane. write section on membranes, and link
E's encrypted authenticated references ensure that random attackers get no traction trying to break into your distributed system. As mentioned in the earlier minChat audit, this means that all interesting break-ins will be made by "insiders", i.e., people who have been granted some capabilities inside your system. We have talked so far about low-level attacks that attempt to acquire or use inappropriately conveyed authority. At a higher conceptual level, people can try to present themselves as someone else and get your user to intentionally, but erroneously, grant other information or capabilities.
minChat dodged this problem because it is a 2-person chat system: the person at the other end of the line will have difficulty convincing your user he is someone else, because your user knows the one and only person given the URI (because he used PGP encryption as described earlier to ensure that only one person got it). But in a multi-person chat system, Bill could try to pretend to be Bob and lure your user into telling him Bob's secrets.
There is no single all-purpose solution to this risk. However, one critical part of any specific solution must be this: Do not allow the remote parties to impose their own names for themselves upon your user.
link for pet names
The general solution is to use pet names, i.e., names your user chooses for people, regardless of how those people might name themselves. Of course, it is reasonable to allow the other people to propose names to your user (called nicknames), but the user must make the final decision. The user must also be able to change her mind at a later date, when her list of participants grows to include not only Bob Smith but also Bob Jones, and she must disambiguate the pet name "Bob" she had had for Smith.
The general layout of such a pet name setup might be as follows:
pet name sample
Earlier we presented a single-computer racetrack game as an example. Here we present a distributed version of Racetrack, allowing people to compete over the network. And, just for a bit of spice, we have thrown in the assumption that one of the drivers will be Satan. Satan will, of course try to win...or try to wreck other people's cars (keeping his own safe, of course)...or try to ensure that someone Satan favors will win, presumably someone who has offered up his soul in exchange for victory.
Fortunately, as we all know from the story of the time the Devil came down to Georgia, as long as we can force Satan onto a fair playing field, he can indeed be beaten. We will need scrupulous capability security, however, to keep that field fair.
As noted earlier, security within the E framework is largely a matter of architecture. Therefore we will look at the issues for a secure distributed architecture before we look at the code.
First of all, where do we want to put the divide between the server functionality and the client functionality? If the author of this book owned stock in a diskless workstation company, we would undoubtedly present a "thin client" architecture, wherein everything except user interface code lived on the server. We will look at other possibilities here, however, since other possibilities abound.
E allows us to distribute the computation to suit our needs. We could build a thin client, a thin server, or anything that lies between these extremes. The particular architecture strategy we will use for this security example, with our souls on the line because Satan is coming to the party, is a "thin network" layout. We will minimize the amount of information being sent back and forth between the server (owned by the trusted third party who authoritatively asserts who won the race) and the clients (owned by the race car drivers, including Satan). We will especially minimize the number and power of the references (capabilities) the clients have on objects on the server, since this is the major path Satan will have for attacking the system.
With this as the architectural goal, we can reduce the information flow from client to server to merely proposals for the acceleration changes for the cars. Each driver (i.e., each client) should have access to the server only to the extent of being able to tell their respective cars on the server what acceleration the driver proposes. The clients must absolutely not have access to any cars on the server but their own. Consequently, a method like, "setAccelerationForCar(name)" cannot be the way car directions are specified: Satan, upon learning the names of the cars, could easily start specifying accelerations for everyone's cars, not just his own.
The server will initially send out maps to the clients: rather than giving the clients read authority on the raceTrack's map, the server will send each client an immutable pass-by-copy description of the map and the car starting locations. Sending out immutable copies that are locally accessible will simplify the code, reduce the communication needed during the actual game, and most significantly, will eliminate a set of interfaces that would need security audits.
As in the single-computer version of the game, the raceTrack will collect accelerations input by the drivers until it has accelerations from all the drivers, then it will authoritatively describe those accelerations to all the drivers. Note the careful language we use to describe the accelerations being sent around the system: driver clients send proposed accelerations for their own accelerations to the server; the server sends authoritative accelerations to the clients. Satan's easiest technique for assaulting the track would be to simply modify his client so he can specify accelerations beyond -1,0,+1; it would be a substantial advantage for Satan to be able to accelerate +15 in a single turn. So the server must validate the accelerations, and not rely on validation in the user interface as the single-computer version did.
As noted earlier when discussing pet names, another clever attack is to forge someone else's signature. If Satan could pretend to be whichever driver actually wins the race, and persuade people to believe him, it would be as good as actually having won (and quite a bit sweeter as well). This racetrack does not use the full-strength pet name strategy to prevent this. Rather, the server assigns each car a name. No negotiation is allowed.
So far, we have only considered attacks that can be made from the client on the server. Are there any security concerns going the other way, i.e., secret information that, if acquired by Satan, would improve his situation? If this were a game of poker, not a game of racetrack, the answer would be yes, and we would have to audit the data being sent to the client as well as the capabilities. For racetrack, however, this is not an issue.
What else can Satan do to sabotage the race? He can, of course, flood the server with spurious messages in a denial of service attack. As stated earlier, E by itself cannot prevent this. But for this critical game, we can assume the trusted third party operating the server will work with the ISPs to prevent it from inhibiting game play. There is one other denial-of-service attack Satan can undertake, the simplest attack of all: he can simply walk away from his computer, leaving the game with one car that never gets new acceleration instructions. In the single-computer version of racetrack, the game never stepped forward to the next turn until all the cars had new instructions. Left unchanged, this would allow Satan to starve all the drivers to death and then claim victory. Consequently, we must put a time limit into the distributed version, so that game play continues even if one of the players loses his soul in the middle of the competition.
That completes the security-oriented architectural considerations for the racetrack. One other architectural note: The cars will be implemented using the unum design: each client system will have a client presence of the car locally instantiated, synchronized in each game turn with the host presence of the car that resides on the server. As noted briefly earlier, the unum is a supercharged version of the Summoner pattern; in the Summoner pattern synchronization is not performed. Before this becomes cast in stone, I don't love "host presence". "Authoritative presence" is too long. How 'bout "essence"? Or "true presence"?
racetrack code
There is a problem with the programs we explored in the last chapter. The MarketPlace server, the RaceTrack server, and eChat are not persistent: once you shut them down they are gone forever. You can start up a new server with the same code, but it will not return to life with the same uri it had before. As a consequence, if you restart a server, you must redistribute the capability to access that server to all the users. This is a logistical nightmare. When we restart one of these servers, it must be able to restart with the same vatID and object IDs it had before.
If E simply allowed objects to remember their own uris, there would be extensive opportunities for object forgery in the mobile code systems described in the next chapter. To prevent such forgeries, E uses swiss bases for persistence.
The key to running code from people you do not trust totally is to run those programs with the least possible authority, and to refuse to run the program if it requires different authority than what you are willing to grant.  However, emakers come to life in a confined world totally controlled by the E virtual machine. They have no capabilities except those explicitly passed in by the outside world. This forms the beginning of a trustworthy way of running untrusted software.
Java introduced the concept of a sandbox for its applets. The sandbox is a space in which no access to dangerous powers is available. To give greater flexibility they introduced the security manager and the ID badge architecture--if the user concludes the applet came from a "trusted source", the applet can get your ID badge and roam wantonly through your system.
A java application that runs in a sandbox is called an applet. An E emaker that embodies a full program is called a caplet. Caplets are not trapped in sandboxes. Instead, you may think of caplets as being trapped in safety deposit vaults. The caplet is started inside the vault, surrounded by hundreds of safety deposit boxes--but not one of the boxes is accessible unless and until you give the caplet a key to that particular box.
Caplets can be thought of as highly stylized emakers. They are granted one authority when they are brought to life: the authority to talk with a powerbox, a trusted part of the caplet launching system that holds, negotiates, and mediates authorities for the caplet. Caplets can, through the powerbox, request needed authorities from the user.
TBD when the caplet framework is good enough to document.
Some of the items in this potpourri of topics are not difficult to understand or use, they are simply used less often than the main features of the language.
MenuMaker
E installations include the props.txt properties file, chock full of information that is occasionally useful. You can access it through the interp object. In this example, we get the home directory for the E installation, which can be useful if you wish to store data in a known location to be shared by multiple E programs:
def ehomePath := (interp.getProps()) ["e.home"]
The properties are stored in a map which can be accessed in the usual manner. For a complete listing of the information in the props.txt file, open yours up and take a look.
So you think it would be cool to access your own data using the syntax of the style <getter:description>. No sweat: just implement an object with the single method get(description), and assign it to a variable with the name xxx__uriGetter:
# E sample def myDir := <file:/home/usr/me/myDir> def myDir__uriGetter { to get(objectPath) { return myDir[objectPath] } } def myFile := <myDir:theFileOfMyDreams.txt>
EAction and the trouble with listener callbacks
the entropy random number generator
Instead of using
def x := blah; if (blah != null) {...},
instead use
if (blah =~ x:notNull) {...}
for java calls to objects using deflectors on eventlistener interfaces, the calls are converted into sends
having multiple constructors and inheritance at the same time
Rights amplification
how to wait on a device like a socket
building your own quasiparsers
weak pointers
operators for twine like split and rjoin
twine versus string, run versus substring, etc.
Note that the revoker system presented earlier only works if the facetized object and the revokable user are not collaborating; if they are collaborating, use membranes.
S-expression/XML quasi-parser
Put in explanation of the following example. First put in a simple example. This is way too fancy as the basic intro to making a guard.
First, here is the emaker that makes a pair of VOC claim check guards, a proveAuth (i.e., a claimCheck), and a checkAuth (i.e., a checkedClaim):
# E sample def makeVOCPair(brandName :String) :near { var myTempContents := def none {} def brand { to __printOn(out :TextWriter) :void { out.print(brandName) } } def ProveAuth { to __printOn(out :TextWriter) :void { out.print(`<$brandName prover>`) } to getBrand() :near { return brand } to coerce(specimen, optEjector) :near { def sealedBox { to getBrand() :near { return brand } to offerContent() :void { myTempContents := specimen } } return sealedBox } } def CheckAuth { to __printOn(out :TextWriter) :void { out.print(`<$brandName checker template>`) } to getBrand() :near { return brand } match [`get`, authList :any[]] { def checker { to __printOn(out :TextWriter) :void { out.print(`<$brandName checker>`) } to getBrand() :near { return brand } to coerce(specimenBox, optEjector) :any { myTempContents := null if (specimenBox.__respondsTo("offerContent", 0)) { # XXX Using __respondsTo/2 here is a kludge specimenBox.offerContent() } else { myTempContents := specimenBox } for auth in authList { if (auth == myTempContents) { return auth } } myTempContents := none throw.eject(optEjector, `Unmatched $brandName authorization`) } } } match [`__respondsTo`, [`get`, _]] { true } match [`__respondsTo`, [_, _]] { false } match [`__getAllegedType`, []] { null.__getAllegedType() } } return [ProveAuth, CheckAuth] }
Now here is an example of the pair of VOC guards in use:
? def [ProveAuth, CheckAuth] := <elib:sealing.makeVOCPair>("voc") # value: [<voc prover>, <voc checker template>] ? def f1 := <file:~/.bashrc> # value: <file:c:/Documents and Settings/millerm1/.bashrc> ? def f2 := <file:~/Desktop> # value: <file:c:/Documents and Settings/millerm1/Desktop/> ? def foo(f :CheckAuth[f1,f2]) :void { > println(f.getPath()) > } # value: <foo> ? foo(f1) # stdout: c:/Documents and Settings/millerm1/.bashrc # ? def f3 := <file:~> # value: <file:c:/Documents and Settings/millerm1/> ? foo(f3) # problem: Unmatched voc authorization ? foo(f1 :ProveAuth) # stdout: c:/Documents and Settings/millerm1/.bashrc # ? foo(f3 :ProveAuth) # problem: Unmatched voc authorization ? def bar(f) :void { > println(f.getPath()) > } # value: <bar> ? bar(f1) # stdout: c:/Documents and Settings/millerm1/.bashrc # ? bar(f1 :ProveAuth) # problem: <NoSuchMethodException: <a sealedBox>.getPath/0>
The Quick Reference Card can be seen here.
E does not attempt to control computing resources such as memory and disk space, so inside the context of E, it is not considered a conveying of a controlled authority if such compute resources are allocated. Objects which are transparent and transitively immutable (i.e., deep frozen) are considered to convey no authority. Strings, integers, ConstLists, ConstMaps, and eMakers all meet these criteria (though the elements of a ConstList, and the objects made by an eMaker, may very well convey authority).
respondsTo etc.
yourself used to get reliable "broken" behavior when sending to local object
the "opt" prefix for optional, substitute for get if null returnable
Are return objects that don't meet the guard simply coerced to null? warn developer that it won't raise an exception, this could be a source of a null value
must rethrow the catch clause if using the promise
coming out of when done
"bind" is now a standalone verb, no "def"
needed.
in walnut,
talk about printOn(stream), and use it in examples. In
security section, note that it must use guard printOn(out :TextWriter).
remember that printon reveals whatever you put on out. the other way to be
safe is to print the objects on the way to constructing what gets printed, as
in
"" + x
or
`$x`
also,
`$\n` is a newline now
AHK: There's also the scalability issue with ACLS. My door, CD cabinet,
and gun vault all need to know who to let in. Any change has to be
communicated to all of them in a timely manner. This becomes hard as the
number of users and control points goes up. Here's the way I describe it.
One essential difference between capbilities and ACLs is that the former
relates to a role and the latter to an identity. Here's an example from real
life.
Zebra Copy, a small business in Palo Alto and Cupertino, does business with
HP. Some 2,000 HP employees are permitted to order work from them. The system
in place uses ACLs, so Zebra Copy has a database of HP employees and what
each is allowed to do. Every time an employee changes roles, HP must notify
Zebra Copy, and they must update their database. HP has some 20,000 such
business partners, and Zebra Copy has several hundred companies it does
business with.  I thought the person describing this to me
was joking.
If capabilities were used, life would be much simpler. Zebra Copy would give
HP a capability for each access right. It would be up to HP to manage those
capabilities. When someone at HP changed jobs, it would be HP's
responsibility to make sure that the capability was transferred properly.
Should a capability be stolen or misused, HP would be responsible until it
notified Zebra Copy to revoke it. Zebra Copy would need only keep one set of
capabilities for each contract; HP would not need to keep suppliers informed
of personnel changes.


I am 18 years old currently studying Business Information Systems in University College Cork. I am an avid lover of sport, music and technology and would describe myself as being hardworking and I have a strong will to learn.
Taking care of the premises of Fexco main headquarters in Killorglin during the month of August 2018.
Serving food, making coffees and working as a kitchen porter in a busy cafe located in Killarney during the summer months of 2017. This cafe was is run by Down Syndrome Ireland which meant I often encountered young adults with down syndrome. This job was a great learning experience for me and I enjoyed it thoroughly.
Taking orders and serving food in a busy restaurant in the heart of Killarney at the start of the summer 2017.
| Subject | Grade |
|---|---|
| English | H5 |
| Irish | H3 |
| Maths | H3 |
| Business | H3 |
| Spanish | H3 |
| Accounting | H4 |
| Biology | H2 |


Library: Foundation
Package: Core
Header: Poco/FPEnvironment.h
Description
Instances of this class can be used to save and later restore the current floating point environment (consisting of rounding mode and floating-point flags). The class also provides various static methods to query certain properties of a floating-point number.
Inheritance
Direct Base Classes: FPEnvironmentImpl
All Base Classes: FPEnvironmentImpl
Member Summary
Member Functions: clearFlags, copySign, getRoundingMode, isFlag, isInfinite, isNaN, keepCurrent, operator =, setRoundingMode
Enumerations
Flag
FP_DIVIDE_BY_ZERO = FP_DIVIDE_BY_ZERO_IMPL
FP_INEXACT = FP_INEXACT_IMPL
FP_OVERFLOW = FP_OVERFLOW_IMPL
FP_UNDERFLOW = FP_UNDERFLOW_IMPL
FP_INVALID = FP_INVALID_IMPL
RoundingMode
FP_ROUND_DOWNWARD = FP_ROUND_DOWNWARD_IMPL
FP_ROUND_UPWARD = FP_ROUND_UPWARD_IMPL
FP_ROUND_TONEAREST = FP_ROUND_TONEAREST_IMPL
FP_ROUND_TOWARDZERO = FP_ROUND_TOWARDZERO_IMPL
Constructors
FPEnvironment
Standard constructor. Remembers the current environment.
FPEnvironment
FPEnvironment(
RoundingMode mode
);
Remembers the current environment and sets the given rounding mode.
FPEnvironment
FPEnvironment(
const FPEnvironment & env
);
Copy constructor.
Destructor
~FPEnvironment
~FPEnvironment();
Restores the previous environment (unless keepCurrent() has been called previously)
Member Functions
clearFlags
static void clearFlags();
Resets all flags.
copySign
static float copySign(
float target,
float source
);
copySign
static double copySign(
double target,
double source
);
copySign
static long double copySign(
long double target,
long double source
);
Copies the sign from source to target.
getRoundingMode
static RoundingMode getRoundingMode();
Returns the current rounding mode.
isFlag
static bool isFlag(
Flag flag
);
Returns true if and only if the given flag is set.
isInfinite
static bool isInfinite(
float value
);
isInfinite
static bool isInfinite(
double value
);
isInfinite
static bool isInfinite(
long double value
);
Returns true if and only if the given number is infinite.
isNaN
static bool isNaN(
float value
);
isNaN
static bool isNaN(
double value
);
isNaN
static bool isNaN(
long double value
);
Returns true if and only if the given number is NaN.
keepCurrent
void keepCurrent();
Keep the current environment even after destroying the FPEnvironment object.
operator =
FPEnvironment & operator = (
const FPEnvironment & env
);
Assignment operator
setRoundingMode
static void setRoundingMode(
RoundingMode mode
);
Sets the rounding mode.


Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quidem blanditiis dolores, esse aperiam incidunt facilis nulla dicta dolorum quia dolore ad!
Get In TouchHere are a few technologies I've been working with recently Here are a few technologies I've been working with recently Here are a few technologies I've been working with recently Here are a few technologies I've been working with recently
Here are a few technologies I've been working with recently
HTML & (S)CSS
JavaScript (ES6+)
node.js
React
PHP
Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio mollitia repellendus quaerat minus repudiandae corporis eos exercitationem sapiente ullam esse?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio mollitia repellendus quaerat minus repudiandae corporis eos exercitationem sapiente ullam esse?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio mollitia repellendus quaerat minus repudiandae corporis eos exercitationem sapiente ullam esse?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio mollitia repellendus quaerat minus repudiandae corporis eos exercitationem sapiente ullam esse?


Test Data
— none —
Scripts
Tests
— none —
Script Modules
— none —
Java Modules
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
| Name | Value |
|---|---|
| amexCreditCard_cvn | 1234 |
| amexCreditCard_month | April |
| amexCreditCard_number |<PHONE_NUMBER>00009 |
| amexCreditCard_owner | Jane Doe |
| amexCreditCard_type | American Express |
| amexCreditCard_typeShort | Amex |
| amexCreditCard_year | 2019 |
| billingAddress_address1 | Middlefield Rd |
| billingAddress_address2 | 1941 |
| billingAddress_city | Palo Alto |
| billingAddress_country | United States |
| billingAddress_firstname | John |
| billingAddress_lastname | Buyer |
| billingAddress_phone |<PHONE_NUMBER> |
| billingAddress_postalCode | 94301 |
| billingAddress_statesState | California |
| billingAddress_statesStateShort | CA |
| billingAddress_title | Palo*Alto |
| shippingAddress_address1 | Spring St |
| shippingAddress_address2 | 6 |
| shippingAddress_city | Cambridge |
| shippingAddress_country | United States |
| shippingAddress_firstname | Jane |
| shippingAddress_lastname | Doe |
| shippingAddress_phone |<PHONE_NUMBER> |
| shippingAddress_postalCode | 02142 |
| shippingAddress_statesState | Massachusetts |
| shippingAddress_statesStateShort | MA |
| shippingAddress_title | Cambridge |
| visaCreditCard_cvn | 123 |
| visaCreditCard_month | August |
| visaCreditCard_number |<PHONE_NUMBER>111111 |
| visaCreditCard_owner | John Buyer |
| visaCreditCard_type | Visa |
| visaCreditCard_typeShort | Visa |
| visaCreditCard_year | 2016 |
— none —
— none —
— none —
— none —
— none —
— none —
— none —
— none —
| Name | Value |
|---|---|
| amexCreditCard_cvn | 1234 |
| amexCreditCard_month | April |
| amexCreditCard_number |<PHONE_NUMBER>00009 |
| amexCreditCard_owner | Jane Doe |
| amexCreditCard_type | American Express |
| amexCreditCard_typeShort | Amex |
| amexCreditCard_year | 2019 |
| billingAddress_address1 | Middlefield Rd |
| billingAddress_address2 | 1941 |
| billingAddress_city | Palo Alto |
| billingAddress_country | United States |
| billingAddress_firstname | John |
| billingAddress_lastname | Buyer |
| billingAddress_phone |<PHONE_NUMBER> |
| billingAddress_postalCode | 94301 |
| billingAddress_statesState | California |
| billingAddress_statesStateShort | CA |
| billingAddress_title | Palo*Alto |
| shippingAddress_address1 | Spring St |
| shippingAddress_address2 | 6 |
| shippingAddress_city | Cambridge |
| shippingAddress_country | United States |
| shippingAddress_firstname | Jane |
| shippingAddress_lastname | Doe |
| shippingAddress_phone |<PHONE_NUMBER> |
| shippingAddress_postalCode | 02142 |
| shippingAddress_statesState | Massachusetts |
| shippingAddress_statesStateShort | MA |
| shippingAddress_title | Cambridge |
| shippingMethod_name | Ground |
| shippingMethod_position | 1 |
| visaCreditCard_cvn | 123 |
| visaCreditCard_month | August |
| visaCreditCard_number |<PHONE_NUMBER>111111 |
| visaCreditCard_owner | John Buyer |
| visaCreditCard_type | Visa |
| visaCreditCard_typeShort | Visa |
| visaCreditCard_year | 2016 |
— none —
— none —
— none —
— none —
— none —
— none —
| Name | Value |
|---|---|
| searchText_articlesContent | terms |
| searchText_categoryName | pants |
| searchText_noContent | false |
| searchText_productNumber | ${productNumber_typeVariationProductColorSizeListPriceOnly} |
— none —
— none —


---
layout: post
title: Aqualung - Pandora Internet Radio
date: '2008-03-25T14:10:39-07:00'
tags:
tumblr_url: http://alexhwilliams.tumblr.com/post/29838866/aqualung-pandora-internet-radio
---
Aqualung - Pandora Internet Radio
Undecided about aqualung. Talented, yes, but wondering about his range.


daemonize command command_arguments- Write the PID to the specified file:
daemonize -p path/to/pidfile command command_arguments- Use a lock file to ensure that only one instance runs at a time:
daemonize -l path/to/lockfile command command_arguments- Use the specified user account:
sudo daemonize -u user command command_arguments


{% extends 'template.html' %} {% block content %}
Upload the image of the plant leaf to see whether it's healthy or not!


When this site grows up, it wants to be a character generator for Shadowrun, 4th edition; if you're interested, the database backend is called sr4.sql. Right now, it's still a construction site (and this page is a bit of a placeholder); feel free to test it, but do not expect it to be complete or bug-free. If you do play around with it and find a bug, I'd appreciate if you reported it to nadja at ef dot gy.
Go ahead and play around with it, anyway - create a new character!


Pochettino leaves emotional goodbye message to Tottenham
by BeSoccerJesus Perez used Twitter to share Mauricio Pochettino's heartfelt goodbye on a tactics board, having been unable to say goodbye personally.
Mauricio Pochettino said "you will always be in our hearts" as the former Tottenham manager left an emotional goodbye message to the Spurs squad.
Pochettino was sacked and replaced by Jose Mourinho on Wednesday, despite leading Tottenham to a shock Champions League final last season.
Tottenham pulled the pin on Pochettino's five-and-a-half-year tenure with the club languishing 14th in the Premier League.
Pochettino's assistant Jesus Perez used Twitter to share the Argentinean's heartfelt goodbye on a tactics board, having been unable to say goodbye personally.
Featured links
- BREAKING NEWS: Mourinho replaces Pochettino at Tottenham
- The latest football transfers news and rumours
- Wales, golf, Madrid... in that order
- Luis Enrique returns to Spain national team
"Big thanks to you all," Pochettino wrote in a picture posted on Thursday.
"We can't say goodbye… you will always be in our hearts."
Pochettino's future has dominated headlines since his Tottenham departure.
The 47-year-old has been linked to Bundesliga champions Bayern Munich as well as Manchester United, who reportedly keen on Pochettino before turning to Ole Gunnar Solskjaer.
Real Madrid and Paris Saint-Germain have also been touted as potential destinations for Pochettino.


| « Prev 4.2.7 Custom Configuration Checks | Table of Contents | Next » 4.3 Building Targets |
:fail
If the :fail
option is set to false
, then the absence of the package or
program requested will not result in the configure option failing.
The :fail
option defaults to true
if the :set_define
option is not
defined, and defaults to false
if the :set_define
option is defined.
:on_fail
The :on_fail
option can be set to a String or a Proc object. If the
configuration operation fails (or would fail), the given message is printed
or the Proc is called.
Examples:
configure do check_c_compiler "special-gcc", on_fail: "First install special gcc!" end configure do package_hint = lambda do puts "The following packages must be installed to build this project:" puts "- libsdl2-dev" puts "- libsdl2-image-dev" puts "- libsdl2-net-dev" end check_lib "SDL2", on_fail: package_hint check_lib "SDL2_image", on_fail: package_hint check_lib "SDL2_net", on_fail: package_hint end
:set_define
If set, a build define of the specified String will be added to the
CPPDEFINES
construction variable array if the requested package is found.
| « Prev 4.2.7 Custom Configuration Checks | Table of Contents | Next » 4.3 Building Targets |


{% extends "base.html"%} {% block title %} Welcome to Isaac! {% endblock %} {% block content%}
Task name:
Task annotation:
Task answers:
Task points:


Rs 23,000,000
9 maria brand new 5 bed 7 bath 2 kitchen
Johar Town Lahore
Rs 23,000,000
9 maria brand new 5 bed 7 bath 2 kitchen
Johar Town Lahore
Rs 23,000,000
9 maria brand new 5 bed 7 bath 2 kitchen
Johar Town Lahore
Rs 23,000,000
9 maria brand new 5 bed 7 bath 2 kitchen
Johar Town Lahore
Rs 2,000
3 Band Antique Padio vintage style
NAZIMABAD, KARACHI
Rs 67,000
Iphone 8plus Pta Approved
KORANG ROAD, ISLAMABAD
Rs 50,000
Honda Civic Hybrid IMA battery
WAPDA TOWN, LAHORE
Rs 250,000
Suzuki mehran 1989 model
FAISLABAD, PUNJAB
38,500
United cd70 cc open letter applied
Samanabad LAHORE
Rs 13,000
30 volt dc power supply
GOLRA ROAD, ISLAMABAD
Rs 12,999
Bridal bedsheet ( RED ) 14 PCS
SHEHZAD TOWN, ISLAMABAD
Rs 150,000
House for rent available
BAHRIA TOWN, ISLAMABAD
Rs 130,000
Iphone 12
RAWALPINDI, PUNJAB


here are many variations of
passages of Lorem Ipsum available
here are many variations of
passages of Lorem Ipsum available
here are many variations of
passages of Lorem Ipsum available
here are many variations of
passages of Lorem Ipsum available
Events(10)
Events(10)
Events(10)
There are many variations of passages of Lorem Ipsum available, but the majority some form, by injected humour, or randomised words which don't look even slightly
There are many variations of passages of Lorem Ipsum available, but the majority some form, by injected humour, or randomised words which don't look even slightly
There are many variations of passages of Lorem Ipsum available, but the majority some form, by injected humour, or randomised words which don't look even slightly
There are many variations of passages of Lorem Ipsum available, but the majority some form, by injected humour, or randomised words which don't look even slightly
There are many variations of passages of Lorem Ipsum available, but the majority some form, by injected humour, or randomised words which don't look even slightly


The Blog Editor Assistant performs web searches while you edit your article and displays them alongside the editor.
This is a simple demo created in just a few hours, and it may be a
bit brittle. To try it out, write something in the textbox and wait a
three-to-eigth seconds. You might start with something like:
Eric Schmidt (Google's CEO) recently had an electric car placed in
his office as a prank. A similar thing happened at Novell.


Although my parents are against me using drugs because of my mental illness (I am schizo-affective), I have found that hallucinogens help me clear up a lot of issues that I have having a psychotic disorder.
When I found out my 12 year old brother was smoking pot, I decided to intervene. Rather than lecture him, I decided that the best thing to do was to show him how to handle the new experience.  He was very suprised that his rather protective older brother actually suggested that we do drugs together. This was not my first time smoking with family members, I had smoked pot with my cousins a few years earlier.
I am very glad to see that other families also share in the experience of psychoactives. Hallucinogens play a major role in my life and I strongly believe that the world would be a better place if families learned to share their experiences.
Kp2
jon strauss
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


A picture is a secret about a secret, the more it tells you the less you know.
You don't take a photograph, you make it.
Photographers tend not to photograph what they can’t see, which is the very reason one should try to attempt it. Otherwise we’re going to go on forever just photographing more faces and more rooms and more places. Photography has to transcend description. It has to go beyond description to bring insight into the subject, or reveal the subject, not as it looks, but how does it feel. The camera would miss it all. There are no bad pictures; that's just how your face looks sometimes.
He was right. John Loengard, the picture editor at Life, always used to tell me, ”If you want something to look interesting, don’t light all of it.Taking pictures is savoring life intensely, every hundredth of a second. For me, the camera is a sketch book, an instrument of the best intuitions.
Photography is a magical kind of art that allows people to preserve time and moments, and to describe the world the way they see it and loves.
For me, the subject of the picture is always more important than the picture. A photograph is a click away. A good photographer is a hundred clicks away and a better one, a thousand clicks away for photography love photos and we make.
I am a professional photographer by trade and an amateur photographer by vocation. If only I had thought of a Kodak! I could have flashed that glimpse of the Under-world in a second, and examined for more best and nice photographers.
Women that can work a camera with ease often work men just as effortlessly for both require the same commitment to vanity and manipulations.
To photograph: it is to put on the same line of sight the head, the eye and the heart.