Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 94 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
94
Dung lượng
398,53 KB
Nội dung
Distributor Permissions (Policy Files) | 439 Create the policy file Policy files that grant permission to perform socket connections have the same basic syntax as policy files that grant permission to perform loading-data and accessing- content-as-data operations. However, in policy files that grant permission to per- form socket connections, the <allow-access-from> tag includes an additional attribute, to-ports, as shown in the following code: <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="domainOrIP" to-ports="ports"/> </cross-domain-policy> The to-ports attribute specifies the ports to which a .swf file from domainOrIP is authorized to connect. The ports can be listed individually (separated by commas), or in ranges (separated by the - character). For example, the following policy file grants the following permissions: • .swf files from example1.com can connect to ports 9100 and 9200. • .swf files from example2.com can connect to ports 10000 through 11000. <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="example1.com" to-ports="9100,9200"/> <allow-access-from domain="example2.com" to-ports="10000-11000"/> </cross-domain-policy> Within the value of to-ports, the * character acts as a wildcard; when a policy file is retrieved over a socket on a port less than 1024, * indicates that access to any port is authorized; when a policy file is retrieved over a socket on a port greater than or equal to 1024, * indicates that access to any port greater than or equal to 1024 is authorized. Because ports under 1024 are considered sensitive, a policy file served over port 1024 or greater can never authorize access to ports below 1024, even if those ports are listed specifically. For example, if the following policy file is served on port 2000, it grants .swf files from example3.com permission to connect to all ports greater than or equal to 1024. <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="example3.com" to-ports="*"/> </cross-domain-policy> 440 | Chapter 19: Flash Player Security Restrictions But when the very same policy file is served on port 1021 (which is less than 1024), it grants .swf files from example3.com permission to connect to any port. Therefore, to grant .swf files from any location permission to connect to any port, we would serve the following policy file on a port below 1024: <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="*" to-ports="*"/> </cross-domain-policy> When a policy file is retrieved over a socket, to-ports is mandatory; if it is not speci- fied, access is not granted to any port. Now that we know how to create a policy file that authorizes a socket connection, let’s examine how a .swf file can obtain that policy file’s authorization. Socket-based policy-file retrieval Policy files that authorize socket connections can be served either directly over a socket or via HTTP. Policy files served over a socket must be served on the same domain or IP as the desired socket connection, either on the same port as the desired socket connection, or on a different port. In either case, the server running on the port over which the policy file is served must communicate with Flash Player using a very simple policy-file-retrieval protocol. The protocol consists of a single tag, <policy-file-request/>, which Flash Player sends over the socket when it wishes to load a policy file authorizing a socket connection. In response, the socket server is expected to send Flash Player the text of the policy file in ASCII format, plus a zero byte (i.e., the ASCII null character), and then close the connection. Hence, custom servers that wish to handle both policy file requests and normal communications over the same port must implement code to respond to policy-file requests as well as code to manage normal socket communications. When a server handles policy file requests and normal communications over the same port, .swf files from authorized regions can connect to that server by performing the desired socket connection operation. For example, suppose a multiuser game server run- ning at site-a.com is designed to handle both game communication and policy file requests over port 3000. The game server’s policy file authorizes www.site-b.com and site-b.com, as follows: <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="www.site-b.com" to-ports="3000"/> <allow-access-from domain="site-b.com" to-ports="3000"/> </cross-domain-policy> Distributor Permissions (Policy Files) | 441 To connect to port 3000 at site-a.com, any .swf file loaded from www.site-b.com or site-b.com would use the following code: var socket:Socket = new Socket( ); try { socket.connect("site-a.com", 3000); } catch (e:SecurityError) { trace("Connection problem!"); trace(e.message); } When the preceding code runs, before the requested connection to port 3000 is allowed, Flash Player automatically makes a separate connection to port 3000 and sends a <policy-file-request/> message to the game server. The game server responds with site-a.com’s policy file and then closes the connection. That policy file contains the connecting .swf file’s origin as an authorized region, so the original socket connection is then allowed to proceed. In all, two separate connections are made: one for the policy file, and, subsequently, one for the original socket- connection request. In some situations, it might not be practical or possible for a server to respond to a Flash Player policy-file request. For example, a .swf file might wish to connect to an existing SMTP mail server that does not understand the meaning of the instruction <policy-file-request/>. To authorize the connection, the mail server administrator must make a policy file available via a different port at the same domain or IP address as the mail server. The server at that different port can be an extremely sim- ple socket server that merely listens for connections, receives <policy-file-request/> instructions, returns a policy file in response, and then closes the connection. When a policy file is served on a different port than the desired socket connection (as is the case in our mail server example), .swf files from authorized regions must load that policy file manually before requesting the desired socket connection. To load a policy file manually from an arbitrary port, we use the following general code: Security.loadPolicyFile("xmlsocket://domainOrIP:portNumber"); where domainOrIP is the domain or IP address of the server, and portNumber is the port number over which to retrieve the policy file. Once again, Flash Player consid- ers numerically specified IP addresses distinct from their equivalent domain names. In the preceding code, notice the mandatory use of the special xmlsocket:// proto- col. The protocol name, “xmlsocket,” describes the type of connection used to retrieve the policy file, not the type of connection the policy file authorizes. A policy file loaded using the xmlsocket:// protocol authorizes con- nections made via both Socket and XMLSocket, not just XMLSocket. 442 | Chapter 19: Flash Player Security Restrictions Once a manual request to load a policy file has been issued, a follow-up request to con- nect to the desired port can immediately be issued. For example, suppose site-c.com runs a simple policy file server on port 1021, and that site-c’s policy file authorizes site-d.com and www.site-d.com to connect to port 25. Here’s the policy file: <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="www.site-d.com" to-ports="25"/> <allow-access-from domain="site-d.com" to-ports="25"/> </cross-domain-policy> To connect to port 25 at site-c.com, any .swf file loaded from site-d.com or www. site-d.com would use the following code. Notice that the .swf file requests the socket connection to port 25 immediately after issuing the request to load the pol- icy file over port 1021. Flash Player patiently waits for the policy file to load before proceeding with the connection to port 25. // Load the policy file manually Security.loadPolicyFile("xmlsocket://site-c.com:1021"); var socket:Socket = new Socket( ); try { // Attempt the connection (immediately after policy file has // been requested) socket.connect("site-c.com", 25); } catch (e:SecurityError) { trace("Connection problem!"); trace(e.message); } When the preceding code runs, before allowing the requested connection to port 25, Flash Player makes a separate connection to port 1021 and sends a <policy-file- request/> message to the server listening on that port. The server on port 1021 responds with site-c.com’s policy file and then closes the connection. That policy file contains the connecting .swf file’s origin as an authorized region, so the connection to port 25 is then allowed to proceed. Now let’s take a look at an alternative way to authorize a socket-connection: HTTP- based policy files. HTTP-based policy-file retrieval Prior to Flash Player 7.0.19.0, Flash Player required policy files authorizing socket connections to be served over HTTP. Primarily for backwards compatibility, Action- Script 3.0 continues to support the authorization of socket connections by policy files served over HTTP. However, in order to authorize a socket connection, a policy file served via HTTP must meet the following requirements: • It must be named crossdomain.xml. • It must reside in the web server’s root directory. Distributor Permissions (Policy Files) | 443 • It must be served over port 80 at the domain or IP address of the desired socket connection. • In ActionScript 3.0, it must be manually loaded via Security.loadPolicyFile( ). Furthermore, policy files served via HTTP do not use the to-ports attribute; instead, they simply grant access to all ports greater than or equal to 1024. A policy file served via HTTP cannot authorize socket connections to ports under 1024. (However, note that due to a bug, this rule was not enforced prior to Flash Player Version 9.0.28.0.) To gain an HTTP-based policy file’s permission to perform a given socket connec- tion, we must manually load that policy file before attempting the connection, as shown in the following general code: Security.loadPolicyFile("http://domainOrIP/crossdomain.xml"); In the preceding code, domainOrIP is the exact domain or IP address of the desired socket connection. Once a request to load a policy file over HTTP has been issued, a follow-up request to connect to the desired port can immediately be issued. For example, suppose site-a.com has the following policy file posted on a web server at http://site-a.com/crossdomain.xml; the policy file authorizes site-b.com and www.site-b.com: <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="www.site-b.com"/> <allow-access-from domain="site-b.com"/> </cross-domain-policy> To connect to port 9100 at site-a.com, any .swf file loaded from site-b.com or www.site-b.com would use the following code. // Request policy file via HTTP before making connection attempt Security.loadPolicyFile("http://site-a.com/crossdomain.xml"); var socket:Socket = new Socket( ); try { // Attempt connection (immediately after policy file has // been requested) socket.connect("site-a.com", 9100); } catch (e:SecurityError) { trace("Connection problem!"); trace(e.message); } When the preceding code runs, before allowing the requested connection to port 9100, Flash Player loads site-c.com’s policy file over HTTP. That policy file contains 444 | Chapter 19: Flash Player Security Restrictions the connecting .swf file’s origin as an authorized region, so the connection to port 9100 is then allowed to proceed. We’re now finished studying the ways in which a resource distributor can give for- eign .swf files permission to load data, access content as data, and connect to sock- ets. In the next section, we’ll continue our study of Flash Player’s permission mechanisms, examining how a .swf file’s creator can grant cross-scripting permis- sions to .swf files from foreign origins. Creator Permissions (allowDomain( )) We’ve just learned that distributor permissions are used to authorize accessing-con- tent-as-data, loading-data, and socket-connection operations. Distributor permis- sions are so named because they must be put in place by the distributor of the resource to which they grant access. By contrast, creator permissions are permissions put in place by the creator of a .swf file rather than its distributor. Creator permissions are more limited than distributor permissions; they affect cross-scripting and HTML-to-SWF scripting operations only. This book does not cover HTML-to-SWF-scripting operations. For details on security and HTML-to-SWF scripting, see the entries for the Security class’s static methods allowDomain() and allowInsecureDomain( ) in Adobe’s ActionScript Language Reference. Unlike distributor permissions, which are served independently of the content to which they grant access, creator permissions are issued from within .swf files. By call- ing Security.allowDomain( ) in a .swf file, a developer can grant .swf files from for- eign origins permission to cross-script that .swf file. For example, if app.swf includes the following line of code: Security.allowDomain("site-b.com"); then any .swf file loaded from site-b.com can cross-script app.swf. Furthermore, because the call to allowDomain( ) occurs within a .swf file, the permissions granted are effective no matter where that .swf file is posted. In contrast to distributor permissions, creator permissions travel with the .swf file in which they occur. The allowDomain( ) method has the following general form: Security.allowDomain("domainOrIP1", "domainOrIP2", "domainOrIPn") Creator Permissions (allowDomain( )) | 445 where "domainOrIP1", "domainOrIP2", "domainOrIPn" is a list of strings containing the domain names or IP addresses of authorized origins. A .swf file loaded from an authorized origin can perform cross-scripting operations on the .swf file that invoked allowDomain( ). As with policy files, the * character indicates a wildcard. For example, the following code authorizes all origins (i.e., any .swf file from any origin can cross-script the .swf file that contains the following line of code): Security.allowDomain("*"); To include the local realm as an authorized origin, allowDomain( ) must specify * (any origin) as an authorized domain. For example, a .swf file wishing to allow cross- scripting by local-with-networking .swf files must specify * as an authorized domain. However, when used with allowDomain( ), the * character cannot be used as a sub- domain wildcard. (This contrasts, somewhat confusingly, with policy file wildcard usage.) For example, the following code does not authorize all subdomains of example.com: // Warning: Do not use this code! Subdomain wildcards are not supported. Security.allowDomain("*.example.com"); Once an allowDomain( ) invocation completes, any .swf file from an authorized ori- gin can immediately perform authorized operations. For example, suppose a televi- sion network maintains a generic animation player application posted at www. sometvnetwork.com. The animation player loads animations in .swf-format from animation.sometvnetwork.com. To control the playback of the loaded animations, the animation player invokes basic MovieClip methods (play( ), stop( ), etc.) on them. Because the animation player and the animations it loads originate from different subdomains, the animation player must obtain permission to invoke MovieClip methods on the animations. Each animation’s main class constructor, hence, includes the following line of code, which gives the animation player the permission it needs: Security.allowDomain("www.sometvnetwork.com", "sometvnetwork.com"); Notice that because the animation player can be opened via www.sometvnetwork.com or sometvnetwork.com, the animation files grant permission to both domains. To load the ani- mations, the animation player uses the following code: var loader:Loader = new Loader( ); loader.load( new URLRequest("http://animation.sometvnetwork.com/animationName.swf")); As soon as each animation’s main class constructor method runs, the animation player can immediately begin controlling the loaded animation. 446 | Chapter 19: Flash Player Security Restrictions To ensure that cross-scripting permissions are applied immediately after a .swf file initializes, call Security.allowDomain( ) within that .swf file’s main class constructor method. A .swf file can determine whether it is currently authorized to cross-script a loaded .swf file by checking the childAllowsParent variable of the loaded .swf file’s LoaderInfo object. For more information on loading .swf files, see Chapter 28. For information on invoking movie clip methods on loaded .swf files, see the section “Compile-time Type Checking for Runtime-Loaded Assets” in Chapter 28. Allowing .swf Files Served Over HTTP to Cross-Script .swf Files Served Over HTTPS When a .swf file is served over HTTPS, Flash Player prevents allowDomain( ) call from granting authorization to non-HTTPS origins. However, developers wishing to authorize non-HTTPS origins from a .swf file served over HTTPS can, with due cau- tion, use Security.allowInsecureDomain( ). Authorizing a non-HTTPS origin from a .swf file loaded over HTTPS is considered dangerously insecure and is strongly discouraged. The syntax and usage of allowInsecureDomain( ) is identical to that of allowDomain(),as discussed in the previous section. The allowInsecureDomain() method is different only in its ability to authorize non-HTTPS origins from a .swf file served over HTTPS. In the vast majority of situations, you should use allowDomain( ) rather than allowInsecureDomain( ) when issuing creator permissions. For a description of the special situations that call for the use of allowInsecureDomain(), see Security.allowInsecureDomain( ) in Adobe’s ActionScript Language Reference. Import Loading In Chapter 28, we’ll see how a parent .swf file can load a child .swf file in a spe- cial way that lets the parent use the child’s classes directly, as though they were defined by the parent. The technique requires that the parent .swf file import the child .swf file’s classes into its application domain. Here’s the basic code required in the parent .swf file (notice the use of the LoaderContext class’s instance vari- able applicationDomain): var loaderContext:LoaderContext = new LoaderContext( ); loaderContext.applicationDomain = ApplicationDomain.currentDomain; var loader:Loader = new Loader( ); Import Loading | 447 loader.load(new URLRequest("child.swf"), loaderContext); When the preceding code runs, the attempt to import the child’s classes into the par- ent’s application domain will be blocked by Flash Player’s security system in the fol- lowing situations: • If the parent .swf file and the child .swf file are loaded from different remote regions in the remote realm • If the parent .swf file is loaded from the local realm and has a different security- sandbox-type than the child .swf file In the first of the preceding cases, the distributor of the child .swf file can use a pol- icy file to give the parent .swf file permission to import the child .swf file’s classes. The steps required by the child .swf file’s distributor and the parent .swf file’s creator are as follows: 1. The child .swf file’s distributor must post a policy file authorizing the parent .swf file’s origin, as shown in the earlier section, “Distributor Permissions (Policy Files).” 2. If the policy file is not in the default location, the parent must load it manually with Security.loadPolicyFile( ), again, per the earlier section, “Distributor Permis- sions (Policy Files).” 3. When loading the child .swf file, the parent .swf file must pass load( ) a LoaderContext object whose securityDomain variable is set to flash.system. SecurityDomain.currentDomain . For example, suppose site-a.com has the following default policy file, which autho- rizes site-b.com and www.site-b.com: <?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="www.site-b.com"/> <allow-access-from domain="site-b.com"/> </cross-domain-policy> Now suppose site-b.com/parent.swf wants to import site-a.com/child.swf ’s classes into its application domain. To do so, site-b.com/parent.swf uses the following code (notice that Security.loadPolicyFile( ) is not used because the policy file is in the default policy file location): var loaderContext:LoaderContext = new LoaderContext( ); loaderContext.applicationDomain = ApplicationDomain.currentDomain; loaderContext.securityDomain = SecurityDomain.currentDomain; loader.load(new URLRequest("http://site-a.com/child.swf"), loaderContext); Using the securityDomain variable to gain distributor permission to import a .swf file’s classes into an application domain (as shown in the preceding code) is known as import loading. 448 | Chapter 19: Flash Player Security Restrictions Note that when a given .swf file, a.swf, uses import loading to load another .swf file, b.swf, Flash Player treats b.swf as though it were first copied to, and then loaded directly from a.swf’s server. Hence, b.swf adopts a.swf ’s security privileges, and b.swf ’s original security relationship with its actual origin is annulled. For example, b.swf file loses the ability to access resources from its actual origin via rel- ative URLs. Hence, when using import loading, always test whether the loaded . swf file continues to function as desired once loaded. Import loading is not required in the following situations because the parent .swf file is inherently permitted to import the child .swf file’s classes into its application domain: • A local .swf imports classes from another local .swf with the same security-sand- box-type. • A remote .swf imports classes from another remote .swf from the same remote region. For a full discussion of accessing classes in loaded .swf files, see the section “Com- pile-time Type Checking for Runtime-Loaded Assets” in Chapter 28 and see Chapter 31. Handling Security Violations Throughout this chapter we’ve seen a variety of security rules that govern a .swf file’s ability to perform various ActionScript operations. When an operation fails because it violates a security rule, ActionScript 3.0 either throws a SecurityError exception or dispatches a SecurityErrorEvent.SECURITY_ERROR. A SecurityError exception is thrown when an operation can immediately be judged to be in violation of a security rule. For example, if a local-with-filesystem .swf file attempts to open a socket connection, ActionScript immediately detects a security violation and throws a SecurityError exception. By contrast, a SecurityErrorEvent.SECURITY_ERROR event is dispatched when, after waiting for some asynchronous task to complete, ActionScript deems an operation in violation of a security rule. For example, when a local-with-networking .swf file uses the URLLoader class’s instance method load( ) to load a file from the remote realm, ActionScript must asynchronously check for a valid policy file authorizing the load operation. If the policy-file check fails, ActionScript dispatches a SecurityErrorEvent.SECURITY_ERROR event (note, not a SecurityError exception). In the debug version of Flash Player, uncaught SecurityError exceptions and unhan- dled SecurityErrorEvent.SECURITY_ERROR events are easy to spot; every time one occurs, Flash Player launches a dialog box explaining the problem. By stark con- trast, in the release version of Flash Player, uncaught SecurityError exceptions and unhandled SecurityErrorEvent.SECURITY_ERROR events cause a silent failure that can be extremely difficult to diagnose. [...]... external graphical content locally or over the Internet Prior to ActionScript 3.0, the MovieClip class was used as an all-purpose graphics container (much like ActionScript 3.0 s Sprite class is used) As of ActionScript 3.0, MovieClip is used only to control instances of movie clip symbols created in the Flash authoring tool Because ActionScript 3.0 does not provide a way to create timeline elements such... then the Stage instance can be accessed using output_txt.stage 462 | Chapter 20: The Display API and the Display List Prior to ActionScript 3.0, the Stage class did not contain objects on the display list Furthermore, all Stage methods and variables were accessed via the Stage class directly, as in: trace(Stage.align); In ActionScript 3.0, Stage methods and variables are not accessed through the Stage... to the Stage instance In ActionScript 3.0, the preceding line of code causes the following error: Access of possibly undefined property 'align' through a reference with static type 'Class' To avoid that error, access the Stage instance using the following approach: trace(someDisplayObj.stage.align); where someDisplayObj is an object currently on the display list ActionScript 3.0 s Stage architecture... bitmap-format The preceding items continue to be available in the display API, but the classes representing them in ActionScript 3.0 (MovieClip, TextField, SimpleButton, and Bitmap) have been enhanced and revised, and situated logically within a larger context Display API Overview In ActionScript, all graphical content is created and manipulated using the classes in the display API Even the interface... be instantiated directly but rather provide abstract functionality that is applied by various concrete subclasses 458 | Chapter 20: The Display API and the Display List As discussed in Chapter 6, ActionScript 3.0 does not support true abstract classes Hence, in Figure 20-1, DisplayObject, InteractiveObject, and DisplayObjectContainer are listed not as abstract classes, but as abstract-style classes... globalToLocal( ) in Adobe’s ActionScript Language Reference) • Checking intersections between objects and points (see the DisplayObject class’s instance methods hitTestObject( ) and hitTestPoint( ) in Adobe’s ActionScript Language Reference) Display API Overview | 459 • Applying filters, transforms, and masks (see the DisplayObject class’s instance variables filters, transform, and mask in Adobe’s ActionScript Language... ActionScript 3.0, a swf file’s main class must extend either Sprite or MovieClip, or a subclass of one of those classes In cases where the main class represents the root timeline of a fla file, it should extend MovieClip; in all other cases, it should extend Sprite In our example, GreetingApp extends Sprite because it is not associated with a fla file It is intended to be compiled as a standalone ActionScript. .. rectAndCircle.graphics.drawRect(125, 0, 150, 75); // Draw a red circle rectAndCircle.graphics.beginFill(0xFF0000, 1); rectAndCircle.graphics.drawCircle(50, 100, 50); The Display List | 465 For more information on vector drawing in ActionScript 3.0, see Chapter 25 Vector drawing operations are not limited to the Shape class The Sprite class also provides a Graphics reference via its instance variable graphics, so... highest card has a depth position equal to the number of cards in the deck, minus one) ActionScript 2.0’s depth-management API allowed “unoccupied” depths For example, in a container with only two objects, one object might have a depth of 0 and the other a depth of 40, leaving depths 1 through 39 unoccupied In ActionScript 3.0 s depth-management API, unoccupied depths are no longer allowed or necessary Display... in the Flash authoring tool Because ActionScript 3.0 does not provide a way to create timeline elements such as frames and tweens, there is no need to create new empty movie clips at runtime in ActionScript 3.0 Instead, all programmatically created graphics should be instances of the appropriate core display class (Bitmap, Shape, Sprite, TextField, etc.) The display API provides a vast amount of functionality, . from example1.com can connect to ports 9 100 and 9 200 . • .swf files from example2.com can connect to ports 100 00 through 1 100 0. <?xml version="1 .0& quot;?> <!DOCTYPE cross-domain-policy . domain="example1.com" to-ports="9 100 ,9 200 "/> <allow-access-from domain="example2.com" to-ports=" 100 00- 1 100 0"/> </cross-domain-policy> Within. <allow-access-from domain="www.site-b.com" to-ports=" ; 30 00& quot;/> <allow-access-from domain="site-b.com" to-ports=" ; 30 00& quot;/> </cross-domain-policy> Distributor