1#!/usr/bin/ruby 2 3# Copyright (c) 2012 Apple Inc. All Rights Reserved. 4 5# IMPORTANT NOTE: This file is licensed only for use on Apple-branded 6# computers and is subject to the terms and conditions of the Apple Software 7# License Agreement accompanying the package this file is a part of. 8# You may not port this file to another platform without Apple's written consent. 9 10# This is a wrapper script for httpd, intended to gather minimal usage data on 11# the Apache web server. This script logs usage data locally, but that data is only 12# sent to Apple if the "send usage data" option is turned on. 13 14begin 15 LastUseFile = "/var/db/.httpd-wrapper" 16 TooSoonInSeconds = 3600.0 # Throttle 17 if !FileTest.exists?(LastUseFile) || Time.now - File.new(LastUseFile).atime > TooSoonInSeconds 18 require 'fileutils' 19 FileUtils.touch(LastUseFile) 20 $SERVER_LIBRARY_PATH = '/Library/Server' 21 $SERVER_WEB_CONFIG_DIR = "#{$SERVER_LIBRARY_PATH}/Web/Config/apache2/" 22 ServerDefaultWebConfigPath = "#{$SERVER_WEB_CONFIG_DIR}httpd_server_app.conf" 23 ServerDefaultWebVHostConfigPath = "#{$SERVER_WEB_CONFIG_DIR}sites/0000_any_80_.conf" 24 ServerDefaultWebSecureVHostConfigPath = "#{$SERVER_WEB_CONFIG_DIR}sites/0000_any_443_.conf" 25 DesktopDefaultWebConfigPath = '/etc/apache2/httpd.conf' 26 ServerAppPath = '/Applications/Server.app/Contents/MacOS/Server' 27 ServerWordPressPath = "#{$SERVER_LIBRARY_PATH}/Web/Data/Sites/Default/wordpress" 28 DesktopWordPressPath = '/Library/WebServer/Documents/wordpress' 29 ThinPath = '/usr/bin/thin' 30 MySQLPath = '/usr/local/mysql' 31 MampPath = '/Applications/MAMP' 32 XCodePath = '/Applications/Xcode.app' 33 activeConfigFile = DesktopDefaultWebConfigPath 34 config_dict = { 35 'active' => 0, 36 'valid_syntax' => 0, 37 'invalid_syntax' => 0, 38 'invalid_usage' => 0, 39 'failed_open' => 0, 40 'unexpected_response' => 0, 41 'zero_exit_status' => 0, 42 'nonzero_exit_status' => 0, 43 'has_php_enabled' => 0, 44 'has_perl_enabled' => 0, 45 'has_ssl_enabled' => 0, 46 'has_third_party_web_sw' => 0, 47 'has_xcode' => 0 48 } 49 settings = { 50 'apache_launch' => 1, 51 'desktop_config' => config_dict.clone, 52 'server_config' => config_dict.clone, 53 'unknown_config' => config_dict.clone, 54 'has_server_app_installed' => 0, 55 'uses_pristine_desktop_config_file' => 0, 56 'uses_pristine_server_main_config_file' => 0, 57 'uses_pristine_server_vhost_config_file' => 0, 58 'has_server_webservice_enabled' => 0, 59 'has_wiki_enabled' => 0, 60 'has_wsgi_enabled' => 0, 61 'has_devicemanagement_enabled' => 0, 62 'has_calendarserver_enabled' => 0, 63 'has_webdavsharing_enabled' => 0, 64 'has_custom_sites' => 0, 65 'has_many_custom_sites' => 0 66 } 67 for i in 0..ARGV.count - 2 68 if ARGV[i] == "-f" 69 activeConfigFile = ARGV[i + 1] 70 elsif ARGV[i] == "-D" && ARGV[i + 1] == "WEBSERVICE_ON" 71 settings['has_server_webservice_enabled'] = 1 72 end 73 end 74 sum = `/usr/bin/cksum #{activeConfigFile} 2>&1`.chomp.split(/\s+/)[0] 75 if activeConfigFile == ServerDefaultWebConfigPath 76 config = 'server_config' 77 if ['2471706962'].include?(sum) 78 settings['uses_pristine_server_main_config_file'] = 1 79 end 80 elsif activeConfigFile == DesktopDefaultWebConfigPath 81 config = 'desktop_config' 82 if ['3298336432'].include?(sum) 83 settings['uses_pristine_desktop_config_file'] = 1 84 end 85 else 86 config = 'unknown_config' 87 end 88 settings[config]['active'] = 1 89 open(activeConfigFile) do |file| 90 file.each_line do |line| 91 if line.match(/^\s*LoadModule\s+php5_module/) 92 settings[config]['has_php_enabled'] = 1 93 elsif line.match(/^\s*LoadModule\s+perl_module/) 94 settings[config]['has_perl_enabled'] = 1 95 elsif config == 'server_config' && line.match(/^\s*Include\s+\/private\/etc\/apache2\/extra\/httpd-ssl.conf/) 96 settings[config]['has_ssl_enabled'] = 1 97 elsif config == 'unknown_config' && line.match(/^\s*SSLEngine\s+On/) 98 settings[config]['has_ssl_enabled'] = 1 99 end 100 end 101 end 102 if config == 'server_config' 103 sum = `/usr/bin/cksum #{ServerDefaultWebVHostConfigPath} 2>&1`.chomp.split(/\s+/)[0] 104 if ['872795171', '1914927767'].include?(sum) 105 settings['uses_pristine_server_vhost_config_file'] = 1 106 else 107 open(ServerDefaultWebVHostConfigPath) do |file| 108 file.each_line do |line| 109 if line.match(/^\s*Include\s+.*httpd_wsgi.conf/) 110 settings['has_wsgi_enabled'] = 1 111 elsif line.match(/^\s*Include\s+.*httpd_corecollaboration_required.conf/) 112 settings['has_wiki_enabled'] = 1 113 elsif line.match(/^\s*Include\s+.*httpd_devicemanagement.conf/) 114 settings['has_devicemanagement_enabled'] = 1 115 elsif line.match(/^\s*Include\s+.*httpd_calendarserver.conf/) 116 settings['has_calendarserver_enabled'] = 1 117 elsif line.match(/^\s*Include\s+.*httpd_webdavsharing.conf/) 118 settings['has_webdavsharing_enabled'] = 1 119 end 120 end 121 end 122 end 123 open(ServerDefaultWebSecureVHostConfigPath) do |file| 124 file.each_line do |line| 125 if line.match(/^\s*Include\s+.*httpd_wsgi.conf/) 126 settings['has_wsgi_enabled'] = 1 127 elsif line.match(/^\s*Include\s+.*httpd_corecollaboration_required.conf/) 128 settings['has_wiki_enabled'] = 1 129 elsif line.match(/^\s*Include\s+.*httpd_devicemanagement.conf/) 130 settings['has_devicemanagement_enabled'] = 1 131 elsif line.match(/^\s*Include\s+.*httpd_calendarserver.conf/) 132 settings['has_calendarserver_enabled'] = 1 133 elsif line.match(/^\s*Include\s+.*httpd_webdavsharing.conf/) 134 settings['has_webdavsharing_enabled'] = 1 135 end 136 end 137 end 138 siteCount = Dir.glob("#{$SERVER_WEB_CONFIG_DIR}sites/*.conf").count 139 settings['has_custom_sites'] = 1 if siteCount > 3 140 settings['has_many_custom_sites'] = 1 if siteCount > 12 141 end 142 msg = `/usr/sbin/httpd #{ARGV.join(' ')} -t 2>&1` 143 if msg =~ /^Syntax OK/ 144 settings[config]['valid_syntax'] = 1 145 elsif msg =~ /^Syntax error/ 146 settings[config]['invalid_syntax'] = 1 147 elsif msg =~ /^Usage:/ 148 settings[config]['invalid_usage'] = 1 149 elsif msg =~ /Could not open configuration/ 150 settings[config]['failed_open'] = 1 151 else 152 settings[config]['unexpected_response'] = 1 153 end 154 settings[config]['zero_exit_status'] = $?.exitstatus == 0 ? 1 : 0 155 settings[config]['nonzero_exit_status'] = $?.exitstatus == 0 ? 0 : 1 156 settings['has_server_app_installed'] = FileTest.exists?(ServerAppPath) ? 1 : 0 157 settings[config]['has_third_party_web_sw'] = (FileTest.exists?(ServerWordPressPath) || FileTest.exists?(DesktopWordPressPath) \ 158 || FileTest.exists?(MySQLPath) \ 159 || FileTest.exists?(MampPath) \ 160 || FileTest.exists?(ThinPath)) ? 1 : 0 161 settings[config]['has_xcode'] = FileTest.exists?(XCodePath) ? 1 : 0 162 163 `syslog -s -l Notice -k com.apple.message.domain com.apple.server.apache.detailed.launch.stats \ 164 com.apple.message.apache_launch #{settings['apache_launch']} \ 165 \ 166 com.apple.message.uses_server_config #{settings['server_config']['active']} \ 167 com.apple.message.server_config_has_valid_syntax #{settings['server_config']['valid_syntax']} \ 168 com.apple.message.server_config_has_invalid_syntax #{settings['server_config']['invalid_syntax']} \ 169 com.apple.message.server_config_has_invalid_usage #{settings['server_config']['invalid_usage']} \ 170 com.apple.message.server_config_has_failed_open #{settings['server_config']['failed_open']} \ 171 com.apple.message.server_config_has_unexpected_response #{settings['server_config']['unexpected_response']} \ 172 com.apple.message.server_config_has_zero_exit_status #{settings['server_config']['zero_exit_status']} \ 173 com.apple.message.server_config_has_nonzero_exit_status #{settings['server_config']['nonzero_exit_status']} \ 174 \ 175 com.apple.message.uses_desktop_config #{settings['desktop_config']['active']} \ 176 com.apple.message.desktop_config_has_valid_syntax #{settings['desktop_config']['valid_syntax']} \ 177 com.apple.message.desktop_config_has_invalid_syntax #{settings['desktop_config']['invalid_syntax']} \ 178 com.apple.message.desktop_config_has_invalid_usage #{settings['desktop_config']['invalid_usage']} \ 179 com.apple.message.desktop_config_has_failed_open #{settings['desktop_config']['failed_open']} \ 180 com.apple.message.desktop_config_has_unexpected_response #{settings['desktop_config']['unexpected_response']} \ 181 com.apple.message.desktop_config_has_zero_exit_status #{settings['desktop_config']['zero_exit_status']} \ 182 com.apple.message.desktop_config_has_nonzero_exit_status #{settings['desktop_config']['nonzero_exit_status']} \ 183 \ 184 com.apple.message.uses_unknown_config #{settings['unknown_config']['active']} \ 185 com.apple.message.unknown_config_has_valid_syntax #{settings['unknown_config']['valid_syntax']} \ 186 com.apple.message.unknown_config_has_invalid_syntax #{settings['unknown_config']['invalid_syntax']} \ 187 \ 188 com.apple.message.uses_pristine_desktop_config_file #{settings['uses_pristine_desktop_config_file']} \ 189 com.apple.message.uses_pristine_server_main_config_file #{settings['uses_pristine_server_main_config_file']} \ 190 com.apple.message.uses_pristine_server_vhost_config_file #{settings['uses_pristine_server_vhost_config_file']} \ 191 com.apple.message.has_server_app_installed #{settings['has_server_app_installed']} \ 192 com.apple.message.desktop_config_with_php_enabled #{settings['desktop_config']['has_php_enabled']} \ 193 com.apple.message.server_config_with_php_enabled #{settings['server_config']['has_php_enabled']} \ 194 com.apple.message.desktop_config_with_perl_enabled #{settings['desktop_config']['has_perl_enabled']} \ 195 com.apple.message.server_config_with_perl_enabled #{settings['server_config']['has_perl_enabled']} \ 196 com.apple.message.server_third_party_web_sw_installed #{settings['server_config']['has_third_party_web_sw']} \ 197 com.apple.message.desktop_third_party_web_sw_installed #{settings['desktop_config']['has_third_party_web_sw']} \ 198 com.apple.message.unknown_third_party_web_sw_installed #{settings['unknown_config']['has_third_party_web_sw']} \ 199 com.apple.message.server_xcode_installed #{settings['server_config']['has_xcode']} \ 200 com.apple.message.desktop_xcode_installed #{settings['desktop_config']['has_xcode']} \ 201 com.apple.message.unknown_xcode_installed #{settings['unknown_config']['has_xcode']} \ 202 com.apple.message.has_wiki_enabled #{settings['has_wiki_enabled']} \ 203 com.apple.message.has_custom_sites #{settings['has_custom_sites']} \ 204 com.apple.message.has_many_custom_sites #{settings['has_many_custom_sites']} \ 205 com.apple.message.has_wsgi_enabled #{settings['has_wsgi_enabled']} \ 206 com.apple.message.has_devicemanagement_enabled #{settings['has_devicemanagement_enabled']} \ 207 com.apple.message.has_calendarserver_enabled #{settings['has_calendarserver_enabled']} \ 208 com.apple.message.has_webdavsharing_enabled #{settings['has_webdavsharing_enabled']} \ 209 com.apple.message.has_ssl_enabled_for_desktop #{settings['desktop_config']['has_ssl_enabled']} \ 210 com.apple.message.has_ssl_enabled_for_unknown #{settings['unknown_config']['has_ssl_enabled']} \ 211 com.apple.message.has_server_webservice_enabled #{settings['has_server_webservice_enabled']} \ 212 \ 213 com.apple.message.websites_only #{(settings['has_server_webservice_enabled'] == 1 \ 214 && settings['has_wiki_enabled'] == 0 \ 215 && settings['has_devicemanagement_enabled'] == 0 \ 216 && settings['has_calendarserver_enabled'] == 0 \ 217 && settings['has_webdavsharing_enabled'] == 0) ? 1 : 0} \ 218 com.apple.message.websites_or_a_service #{(settings['has_server_webservice_enabled'] == 1 \ 219 || settings['has_wiki_enabled'] == 1 \ 220 || settings['has_devicemanagement_enabled'] == 1 \ 221 || settings['has_calendarserver_enabled'] == 1 \ 222 || settings['has_webdavsharing_enabled'] == 1) ? 1 : 0} \ 223 com.apple.message.service_only #{(settings['has_server_webservice_enabled'] == 0 \ 224 && settings['has_wiki_enabled'] == 1 \ 225 && settings['has_devicemanagement_enabled'] == 1 \ 226 && settings['has_calendarserver_enabled'] == 1 \ 227 && settings['has_webdavsharing_enabled'] == 1) ? 1 : 0} \ 228 com.apple.message.no_websites_nor_service #{(settings['has_server_webservice_enabled'] == 0 \ 229 && settings['has_wiki_enabled'] == 0 \ 230 && settings['has_devicemanagement_enabled'] == 0 \ 231 && settings['has_calendarserver_enabled'] == 0 \ 232 && settings['has_webdavsharing_enabled'] == 0) ? 1 : 0}` 233 end 234 exec("/usr/sbin/httpd #{ARGV.join(' ')}") 235rescue => e 236 require 'logger' 237 $logger = Logger.new('/var/log/apache2/httpd-wrapper.log') 238 $logger.level = Logger::ERROR 239 $logger.error("Exception raised running httpd-wrapper: #{e.message}") 240 $logger.error("Proceeding with exec of httpd") 241 exec("/usr/sbin/httpd #{ARGV.join(' ')}") 242end 243