Advertisement
iPwnOSX

ipaDistrubution.php

Jul 4th, 2018
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.57 KB | None | 0 0
  1. <?
  2. /**
  3. * Creates an Manifest from any IPA iPhone application file for iOS Wireless App Distribution.
  4. * and searches for the right provision profile in the same folder
  5. *
  6. * Script needs GD Library (for resizing the images) and CFPropertyList class (http://code.google.com/p/cfpropertylist/)
  7.  
  8. * @author Wouter van den Broek <wvb@webstate.nl>
  9. */
  10.  
  11. class ipaDistrubution {
  12.  
  13. /**
  14. * The base url of the script.
  15. */
  16. protected $baseurl;
  17. /**
  18. * The base folder of the script.
  19. */
  20. protected $basedir;
  21. /**
  22. * The folder of the app where the manifest will be written.
  23. */
  24. protected $folder;
  25. /**
  26. * iTunesArtwork name which is an standard from Apple (http://developer.apple.com/iphone/library/qa/qa2010/qa1686.html).
  27. */
  28. protected $itunesartwork = "iTunesArtwork";
  29. /**
  30. * App name which can be used for the HTML page.
  31. */
  32. public $appname;
  33. /**
  34. * App ccon which can be used for the HTML page.
  35. */
  36. public $appicon;
  37. /**
  38. * The link to the manifest for the iPhone .
  39. */
  40. public $applink = "itms-services://?action=download-manifest&url=";
  41. /**
  42. * Bundle identifier which is used to find the proper provision profile.
  43. */
  44. protected $identiefier;
  45. /**
  46. * Bundle icon name for extracting icon file
  47. */
  48. protected $icon;
  49. /**
  50. * The name of the provision profile for the IPA iPhone application .
  51. */
  52. public $provisionprofile;
  53.  
  54.  
  55. /**
  56. * Initialize the IPA and create the Manifest.
  57. *
  58. * @param String $ipa the IPA file for which an Manifest must be made
  59. */
  60. public function __construct($ipa){
  61. $this->baseurl = "http".((!empty($_SERVER['HTTPS'])) ? "s" : "")."://".$_SERVER['SERVER_NAME'];
  62. $this->basedir = (strpos($_SERVER['REQUEST_URI'],".php")===false?$_SERVER['REQUEST_URI']:dirname($_SERVER['REQUEST_URI'])."/");
  63.  
  64. $this->makeDir(basename($ipa, ".ipa"));
  65.  
  66. $this->getPlist($ipa);
  67.  
  68. $this->createManifest($ipa);
  69.  
  70. $this->seekMobileProvision($this->identiefier);
  71.  
  72. $this->getIcon($ipa);
  73.  
  74. if (file_exists($this->itunesartwork)) {
  75. $this->makeImages();
  76. }
  77.  
  78. $this->cleanUp();
  79. }
  80.  
  81. /**
  82. * Make a folder where the Manifest and icon files are held.
  83. *
  84. * @param String $dirname name of the folder
  85. */
  86. function makeDir ($dirname) {
  87. $this->folder = $dirname;
  88. if (!is_dir($dirname)) {
  89. if (!mkdir($dirname)) die('Failed to create folder '.$dirname.'... Is the current folder writeable?');
  90. }
  91. }
  92.  
  93. /**
  94. * Get de Plist and iTunesArtwork from the IPA file
  95. *
  96. * @param String $ipa the location of the IPA file
  97. */
  98. function getPlist ($ipa) {
  99. if (is_dir($this->folder)) {
  100. $zip = zip_open($ipa);
  101. if ($zip) {
  102. while ($zip_entry = zip_read($zip)) {
  103. $fileinfo = pathinfo(zip_entry_name($zip_entry));
  104. if ($fileinfo['basename']=="Info.plist"||$fileinfo['basename']==$this->itunesartwork) {
  105. $fp = fopen($fileinfo['basename'], "w");
  106. if (zip_entry_open($zip, $zip_entry, "r")) {
  107. $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
  108. fwrite($fp,"$buf");
  109. zip_entry_close($zip_entry);
  110. fclose($fp);
  111. }
  112. }
  113. }
  114. zip_close($zip);
  115. }
  116. }
  117. }
  118.  
  119. /**
  120. * Create the icon (if not in IPA) and itunes artwork from the original iTunesArtwork
  121. */
  122. function makeImages () {
  123. if (function_exists("ImageCreateFromJPEG")) {
  124. $im = @ImageCreateFromJPEG ($this->itunesartwork);
  125. $x = @getimagesize($this->itunesartwork);
  126. $iTunesfile = @ImageCreateTrueColor (512, 512);
  127. @ImageCopyResampled ($iTunesfile, $im, 0, 0, 0, 0, 512, 512, $x[0], $x[1]);
  128. @ImagePNG($iTunesfile,$this->folder."/itunes.png",0);
  129. @ImageDestroy($iTunesfile);
  130. if ($this->icon==null) {
  131. $iconfile = @ImageCreateTrueColor (57, 57);
  132. @ImageCopyResampled ($iconfile, $im, 0, 0, 0, 0, 57, 57, $x[0], $x[1]);
  133. @ImagePNG($iconfile,$this->folder."/icon.png",0);
  134. @ImageDestroy($iconfile);
  135. $this->appicon = $this->folder."/icon.png";
  136. }
  137. }
  138. }
  139.  
  140.  
  141. /**
  142. * Get the icon file out of the IPA and place it in the right folder
  143. */
  144. function getIcon ($ipa) {
  145. if (is_dir($this->folder)) {
  146. $zip = zip_open($ipa);
  147. if ($zip) {
  148. while ($zip_entry = zip_read($zip)) {
  149. $fileinfo = pathinfo(zip_entry_name($zip_entry));
  150. if ($fileinfo['basename']==$this->icon) {
  151. $fp = fopen($this->folder.'/'.$fileinfo['basename'], "w");
  152. if (zip_entry_open($zip, $zip_entry, "r")) {
  153. $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
  154. fwrite($fp,"$buf");
  155. zip_entry_close($zip_entry);
  156. fclose($fp);
  157. }
  158. $this->appicon = $this->folder."/".$this->icon;
  159. }
  160. }
  161. zip_close($zip);
  162. }
  163. }
  164. }
  165.  
  166. /**
  167. * Parse the Plist and get the values for the creating an Manifest and write the Manifest
  168. *
  169. * @param String $ipa the location of the IPA file
  170. */
  171. function createManifest ($ipa) {
  172. if (file_exists(dirname(__FILE__).'/cfpropertylist/CFPropertyList.php')) {
  173. require_once(dirname(__FILE__).'/cfpropertylist/CFPropertyList.php');
  174.  
  175. $plist = new CFPropertyList('Info.plist');
  176. $plistArray = $plist->toArray();
  177. //var_dump($plistArray);
  178. $this->identiefier = $plistArray['CFBundleIdentifier'];
  179. $this->appname = $plistArray['CFBundleDisplayName'];
  180. $this->icon = ($plistArray['CFBundleIconFile']!=""?$plistArray['CFBundleIconFile']:(count($plistArray['CFBundleIconFile'])>0?$plistArray['CFBundleIconFile'][0]:null));
  181.  
  182.  
  183. $manifest = '<?xml version="1.0" encoding="UTF-8"?>
  184. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  185. <plist version="1.0">
  186. <dict>
  187. <key>items</key>
  188. <array>
  189. <dict>
  190. <key>assets</key>
  191. <array>
  192. <dict>
  193. <key>kind</key>
  194. <string>software-package</string>
  195. <key>url</key>
  196. <string>'.$this->baseurl.$this->basedir.$ipa.'</string>
  197. </dict>
  198. '.(file_exists($this->folder.'/itunes.png')?'<dict>
  199. <key>kind</key>
  200. <string>full-size-image</string>
  201. <key>needs-shine</key>
  202. <false/>
  203. <key>url</key>
  204. <string>'.$this->baseurl.$this->basedir.$this->folder.'/itunes.png</string>
  205. </dict>':'').'
  206. '.(file_exists($this->folder.'/icon.png')?'<dict>
  207. <key>kind</key>
  208. <string>display-image</string>
  209. <key>needs-shine</key>
  210. <false/>
  211. <key>url</key>
  212. <string>'.$this->baseurl.$this->basedir.$this->folder.'/'.($this->icon==null?'icon.png':$this->icon).'</string>
  213. </dict>':'').'
  214. </array>
  215. <key>metadata</key>
  216. <dict>
  217. <key>bundle-identifier</key>
  218. <string>'.$plistArray['CFBundleIdentifier'].'</string>
  219. <key>bundle-version</key>
  220. <string>'.$plistArray['CFBundleVersion'].'</string>
  221. <key>kind</key>
  222. <string>software</string>
  223. <key>title</key>
  224. <string>'.$plistArray['CFBundleDisplayName'].'</string>
  225. </dict>
  226. </dict>
  227. </array>
  228. </dict>
  229. </plist>';
  230.  
  231. if (file_put_contents($this->folder."/".basename($ipa, ".ipa").".plist",$manifest)) $this->applink = $this->applink.$this->baseurl.$this->basedir.$this->folder."/".basename($ipa, ".ipa").".plist";
  232. else die("Wireless manifest file could not be created !?! Is the folder ".$this->folder." writable?");
  233.  
  234.  
  235. } else die("CFPropertyList class was not found! You need it to create the wireless manifest. Put it in de folder cfpropertylist!");
  236. }
  237.  
  238. /**
  239. * Removes temporary files
  240. */
  241. function cleanUp () {
  242. if (file_exists($this->itunesartwork)) @unlink($this->itunesartwork);
  243. if (file_exists("Info.plist")) @unlink("Info.plist");
  244. }
  245.  
  246. /**
  247. * Search for the right provision profile in de current folder
  248. *
  249. * @param String $identiefier the bundle identifier for the app
  250. */
  251. function seekMobileProvision ($identiefier) {
  252. $wildcard = pathinfo($identiefier);
  253.  
  254. $bundels = array();
  255. foreach (glob("*.mobileprovision") as $filename) {
  256. $profile = file_get_contents($filename);
  257. $seek = strpos(strstr($profile, $wildcard['filename']),"</string>");
  258. if ($seek!== false) $bundels[substr(strstr($profile, $wildcard['filename']),0,$seek)] = $filename;
  259. }
  260.  
  261. if (array_key_exists($this->identiefier,$bundels)) $this->provisionprofile = $bundels[$this->identiefier];
  262. else if (array_key_exists($wildcard['filename'].".*",$bundels)) $this->provisionprofile = $bundels[$wildcard['filename'].".*"];
  263. else $this->provisionprofile = null;
  264. }
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement