#!/usr/bin/python
#
# Copyright 2015 Tim Sutton
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""See docstring for AdobeFlashDownloadDecoder class"""

import os
import subprocess

from autopkglib import Processor, ProcessorError


__all__ = ["AdobeFlashDownloadDecoder"]

#pylint: disable=missing-docstring
#pylint: disable=e1101

class AdobeFlashDownloadDecoder(Processor):
    '''Decodes an Adobe Flash Download using `security cms`. Thanks to Per
    Olofsson for documenting the use of the `security` command to decode the
    ASN-1 data from Adobe's Flash Player download.'''
    description = __doc__
    input_variables = {
        "encoded_path": {
            "required": True,
            "description": ("Path to a downloaded, encoded DMG from Adobe's "
                            "auto-update url."),
        },
    }
    output_variables = {
        "pathname": {
            "description": ("Path to the decoded DMG file. Note that this is "
                            "the same variable name as output by "
                            "URLDownloader, since we have no other use in "
                            "child recipes or processors for the original "
                            "encoded file."),
        },
    }

    def main(self):
        '''Decode the file specified at encoded_path to a new file stored
        in the pathname variable.'''
        inpath = self.env["encoded_path"]
        outname = self.env.get("NAME", "AdobeFlashPlayer") + ".dmg"
        outpath = os.path.join(self.env["RECIPE_CACHE_DIR"], outname)

        sec_cmd = ["/usr/bin/security", "cms", "-D",
                   "-i", inpath,
                   "-o", outpath]
        # wrap our call around a general exception in case of unexpected
        # issues calling `security`
        try:
            proc = subprocess.Popen(sec_cmd,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            _, err = proc.communicate()
            # we expect no output on success, so raise an error in case
            # of any non-zero return code or stderr output
            if proc.returncode or err:
                raise ProcessorError("`security` error: %s, return code: %s"
                                     % (err, proc.returncode))
        except Exception as exp:
            raise ProcessorError("Unexpected exception in running `security` "
                                 "command: %s" % exp)
        self.env["pathname"] = outpath


if __name__ == '__main__':
    PROCESSOR = AdobeFlashDownloadDecoder()
    PROCESSOR.execute_shell()

@@ -673,16 +673,46 @@
 rocess%0A%0A
+from tempfile import mkstemp%0A%0A
 from aut
@@ -1890,24 +1890,62 @@
 ariable.'''%0A
+        sec_bin = %22/usr/bin/security%22%0A
         inpa
@@ -2125,246 +2125,606 @@
     
-sec_cmd = %5B%22/usr/bin/security%22, %22cms%22, %22-D%22,%0A                   %22-i%22, inpath,%0A                   %22-o%22, outpath%5D%0A        # wrap our call around a general exception in case of unexpected%0A        # issues calling %60security%60%0A        try:%0A    
+# set up a temporary keychain path%0A        keychain_file = mkstemp(prefix=%22autopkg-fp-keychain-%22)%5B1%5D%0A        os.remove(keychain_file)%0A%0A        try:%0A            subprocess.check_call(%5Bsec_bin, %22create-keychain%22,%0A                                   %22-p%22, %22%22, keychain_file%5D)%0A        except Exception as exp:%0A            raise ProcessorError(%22Error creating temporary keychain at path %22%0A                                 %22%25s: %25s%22 %25 (keychain_file, exp))%0A%0A        sec_cmd = %5Bsec_bin, %22cms%22, %22-D%22,%0A                   %22-k%22, keychain_file,%0A                   %22-i%22, inpath,%0A                   %22-o%22, outpath%5D%0A
     
@@ -2792,20 +2792,16 @@
         
-    
 stdout=s
@@ -2816,20 +2816,16 @@
 s.PIPE,%0A
-    
         
@@ -2880,20 +2880,16 @@
         
-    
 _, err =
@@ -2916,20 +2916,16 @@
         
-   
- 
 # we exp
@@ -2984,20 +2984,16 @@
         
-    
 # of any
@@ -3039,20 +3039,16 @@
         
- 
-   
 if proc.
@@ -3070,36 +3070,32 @@
 rr:%0A            
-    
 raise ProcessorE
@@ -3100,16 +3100,27 @@
 rError(%22
+Unexpected 
 %60securit
@@ -3131,29 +3131,18 @@
 rror
-: %25s, return code
+ (%25s)
 : %25s
+ 
 %22%0A  
@@ -3176,202 +3176,179 @@
     
-    %25 (err, proc.returncode))%0A        except Exception as exp:%0A            raise ProcessorError(%22Unexpected exception in running %60security%60 %22%0A                                 %22command: %25s%22 %25 exp
+%22keychain path: %25s%22 %25 (%0A                                     proc.returncode, err, keychain_file))%0A%0A        # remove our temporary keychain%0A        os.remove(keychain_file
 )%0A  

use a temporary keychain with `security`