// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/installer/gcapi_mac/gcapi.h"

#import <Cocoa/Cocoa.h>
#include <grp.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>

namespace {

// The "~~" prefixes are replaced with the home directory of the
// console owner (i.e. not the home directory of the euid).
NSString* const kChromeInstallPath = @"/Applications/Google Chrome.app";

NSString* const kBrandKey = @"KSBrandID";
NSString* const kUserBrandPath = @"~~/Library/Google/Google Chrome Brand.plist";

NSString* const kSystemKsadminPath =
    @"/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
     "Contents/MacOS/ksadmin";

NSString* const kUserKsadminPath =
    @"~~/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
     "Contents/MacOS/ksadmin";

NSString* const kSystemMasterPrefsPath =
    @"/Library/Google/Google Chrome Master Preferences";
NSString* const kUserMasterPrefsPath =
    @"~~/Library/Application Support/Google/Chrome/"
     "Google Chrome Master Preferences";

// Condensed from chromium's base/mac/mac_util.mm.
bool IsOSXVersionSupported() {
  // On 10.6, Gestalt() was observed to be able to spawn threads (see
  // http://crbug.com/53200). Don't call Gestalt().
  struct utsname uname_info;
  if (uname(&uname_info) != 0)
    return false;
  if (strcmp(uname_info.sysname, "Darwin") != 0)
    return false;

  char* dot = strchr(uname_info.release, '.');
  if (!dot)
    return false;

  int darwin_major_version = atoi(uname_info.release);
  if (darwin_major_version < 6)
    return false;

  // The Darwin major version is always 4 greater than the Mac OS X minor
  // version for Darwin versions beginning with 6, corresponding to Mac OS X
  // 10.2.
  int mac_os_x_minor_version = darwin_major_version - 4;

  // Chrome is known to work on 10.6 - 10.9.
  return mac_os_x_minor_version >= 6 && mac_os_x_minor_version <= 9;
}

// Returns the pid/gid of the logged-in user, even if getuid() claims that the
// current user is root.
// Returns NULL on error.
passwd* GetRealUserId() {
  CFDictionaryRef session_info_dict = CGSessionCopyCurrentDictionary();
  [NSMakeCollectable(session_info_dict) autorelease];
  if (!session_info_dict)
    return NULL;  // Possibly no screen plugged in.

  CFNumberRef ns_uid = (CFNumberRef)CFDictionaryGetValue(session_info_dict,
                                                         kCGSessionUserIDKey);
  if (CFGetTypeID(ns_uid) != CFNumberGetTypeID())
    return NULL;

  uid_t uid;
  BOOL success = CFNumberGetValue(ns_uid, kCFNumberSInt32Type, &uid);
  if (!success)
    return NULL;

  return getpwuid(uid);
}

enum TicketKind {
  kSystemTicket, kUserTicket
};

// Replaces "~~" with |home_dir|.
NSString* AdjustHomedir(NSString* s, const char* home_dir) {
  if (![s hasPrefix:@"~~"])
    return s;
  NSString* ns_home_dir = [NSString stringWithUTF8String:home_dir];
  return [ns_home_dir stringByAppendingString:[s substringFromIndex:2]];
}

// If |chrome_path| is not 0, |*chrome_path| is set to the path where chrome
// is according to keystone. It's only set if that path exists on disk.
BOOL FindChromeTicket(TicketKind kind, const passwd* user,
                      NSString** chrome_path) {
  if (chrome_path)
    *chrome_path = nil;

  // Don't use Objective-C 2 loop syntax, in case an installer runs on 10.4.
  NSMutableArray* keystone_paths =
      [NSMutableArray arrayWithObject:kSystemKsadminPath];
  if (kind == kUserTicket) {
    [keystone_paths insertObject:AdjustHomedir(kUserKsadminPath, user->pw_dir)
                        atIndex:0];
  }
  NSEnumerator* e = [keystone_paths objectEnumerator];
  id ks_path;
  while ((ks_path = [e nextObject])) {
    if (![[NSFileManager defaultManager] fileExistsAtPath:ks_path])
      continue;

    NSTask* task = nil;
    NSString* string = nil;
    bool ksadmin_ran_successfully = false;

    @try {
      task = [[NSTask alloc] init];
      [task setLaunchPath:ks_path];

      NSArray* arguments = @[
          kind == kUserTicket ? @"--user-store" : @"--system-store",
          @"--print-tickets",
          @"--productid",
          @"com.google.Chrome",
      ];
      if (geteuid() == 0 && kind == kUserTicket) {
        NSString* run_as = [NSString stringWithUTF8String:user->pw_name];
        [task setLaunchPath:@"/usr/bin/sudo"];
        arguments = [@[@"-u", run_as, ks_path]
            arrayByAddingObjectsFromArray:arguments];
      }
      [task setArguments:arguments];

      NSPipe* pipe = [NSPipe pipe];
      [task setStandardOutput:pipe];

      NSFileHandle* file = [pipe fileHandleForReading];

      [task launch];

      NSData* data = [file readDataToEndOfFile];
      [task waitUntilExit];

      ksadmin_ran_successfully = [task terminationStatus] == 0;
      string = [[[NSString alloc] initWithData:data
                                    encoding:NSUTF8StringEncoding] autorelease];
    }
    @catch (id exception) {
      // Most likely, ks_path didn't exist.
    }
    [task release];

    if (ksadmin_ran_successfully && [string length] > 0) {
      // If the user deleted chrome, it doesn't get unregistered in keystone.
      // Check if the path keystone thinks chrome is at still exists, and if not
      // treat this as "chrome isn't installed". Sniff for
      //   xc=<KSPathExistenceChecker:1234 path=/Applications/Google Chrome.app>
      // in the output. But don't mess with system tickets, since reinstalling
      // a user chrome on top of a system ticket produces a non-autoupdating
      // chrome.
      NSRange start = [string rangeOfString:@"\n\txc=<KSPathExistenceChecker:"];
      if (start.location == NSNotFound && start.length == 0)
        return YES;  // Err on the cautious side.
      string = [string substringFromIndex:start.location];

      start = [string rangeOfString:@"path="];
      if (start.location == NSNotFound && start.length == 0)
        return YES;  // Err on the cautious side.
      string = [string substringFromIndex:start.location];

      NSRange end = [string rangeOfString:@".app>\n\t"];
      if (end.location == NSNotFound && end.length == 0)
        return YES;

      string = [string substringToIndex:NSMaxRange(end) - [@">\n\t" length]];
      string = [string substringFromIndex:start.length];

      BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:string];
      if (exists && chrome_path)
        *chrome_path = string;
      // Don't allow reinstallation over a system ticket, even if chrome doesn't
      // exist on disk.
      if (kind == kSystemTicket)
        return YES;
      return exists;
    }
  }

  return NO;
}

// File permission mask for files created by gcapi.
const mode_t kUserPermissions = 0755;
const mode_t kAdminPermissions = 0775;

BOOL CreatePathToFile(NSString* path, const passwd* user) {
  path = [path stringByDeletingLastPathComponent];

  // Default owner, group, permissions:
  // * Permissions are set according to the umask of the current process. For
  //   more information, see umask.
  // * The owner ID is set to the effective user ID of the process.
  // * The group ID is set to that of the parent directory.
  // The default group ID is fine. Owner ID is fine if creating a system path,
  // but when creating a user path explicitly set the owner in case euid is 0.
  // Do set permissions explicitly; for admin paths all admins can write, for
  // user paths just the owner may.
  NSMutableDictionary* attributes = [NSMutableDictionary dictionary];
  if (user) {
    [attributes setObject:[NSNumber numberWithShort:kUserPermissions]
                   forKey:NSFilePosixPermissions];
    [attributes setObject:[NSNumber numberWithInt:user->pw_uid]
                   forKey:NSFileOwnerAccountID];
  } else {
    [attributes setObject:[NSNumber numberWithShort:kAdminPermissions]
                   forKey:NSFilePosixPermissions];
    [attributes setObject:@"admin" forKey:NSFileGroupOwnerAccountName];
  }

  NSFileManager* manager = [NSFileManager defaultManager];
  return [manager createDirectoryAtPath:path
            withIntermediateDirectories:YES
                             attributes:attributes
                                  error:nil];
}

// Tries to write |data| at |user_path|.
// Returns the path where it wrote, or nil on failure.
NSString* WriteUserData(NSData* data,
                        NSString* user_path,
                        const passwd* user) {
  user_path = AdjustHomedir(user_path, user->pw_dir);
  if (CreatePathToFile(user_path, user) &&
      [data writeToFile:user_path atomically:YES]) {
    chmod([user_path fileSystemRepresentation], kUserPermissions & ~0111);
    chown([user_path fileSystemRepresentation], user->pw_uid, user->pw_gid);
    return user_path;
  }
  return nil;
}

// Tries to write |data| at |system_path| or if that fails at |user_path|.
// Returns the path where it wrote, or nil on failure.
NSString* WriteData(NSData* data,
                    NSString* system_path,
                    NSString* user_path,
                    const passwd* user) {
  // Try system first.
  if (CreatePathToFile(system_path, NULL) &&
      [data writeToFile:system_path atomically:YES]) {
    chmod([system_path fileSystemRepresentation], kAdminPermissions & ~0111);
    // Make sure the file is owned by group admin.
    if (group* group = getgrnam("admin"))
      chown([system_path fileSystemRepresentation], 0, group->gr_gid);
    return system_path;
  }

  // Failed, try user.
  return WriteUserData(data, user_path, user);
}

NSString* WriteBrandCode(const char* brand_code, const passwd* user) {
  NSDictionary* brand_dict = @{
      kBrandKey: [NSString stringWithUTF8String:brand_code],
  };
  NSData* contents = [NSPropertyListSerialization
      dataFromPropertyList:brand_dict
                    format:NSPropertyListBinaryFormat_v1_0
          errorDescription:nil];

  return WriteUserData(contents, kUserBrandPath, user);
}

BOOL WriteMasterPrefs(const char* master_prefs_contents,
                      size_t master_prefs_contents_size,
                      const passwd* user) {
  NSData* contents = [NSData dataWithBytes:master_prefs_contents
                                    length:master_prefs_contents_size];
  return WriteData(
      contents, kSystemMasterPrefsPath, kUserMasterPrefsPath, user) != nil;
}

NSString* PathToFramework(NSString* app_path, NSDictionary* info_plist) {
  NSString* version = [info_plist objectForKey:@"CFBundleShortVersionString"];
  if (!version)
    return nil;
  return [[[app_path
      stringByAppendingPathComponent:@"Contents/Versions"]
      stringByAppendingPathComponent:version]
      stringByAppendingPathComponent:@"Google Chrome Framework.framework"];
}

NSString* PathToInstallScript(NSString* app_path, NSDictionary* info_plist) {
  return [PathToFramework(app_path, info_plist) stringByAppendingPathComponent:
      @"Resources/install.sh"];
}

bool isbrandchar(int c) {
  // Always four upper-case alpha chars.
  return c >= 'A' && c <= 'Z';
}

}  // namespace

int GoogleChromeCompatibilityCheck(unsigned* reasons) {
  unsigned local_reasons = 0;
  @autoreleasepool {
    passwd* user = GetRealUserId();
    if (!user)
      return GCCC_ERROR_ACCESSDENIED;

    if (!IsOSXVersionSupported())
      local_reasons |= GCCC_ERROR_OSNOTSUPPORTED;

    NSString* path;
    if (FindChromeTicket(kSystemTicket, NULL, &path)) {
      local_reasons |= GCCC_ERROR_ALREADYPRESENT;
      if (!path)  // Ticket points to nothingness.
        local_reasons |= GCCC_ERROR_ACCESSDENIED;
    }

    if (FindChromeTicket(kUserTicket, user, NULL))
      local_reasons |= GCCC_ERROR_ALREADYPRESENT;

    if ([[NSFileManager defaultManager] fileExistsAtPath:kChromeInstallPath])
      local_reasons |= GCCC_ERROR_ALREADYPRESENT;

    if ((local_reasons & GCCC_ERROR_ALREADYPRESENT) == 0) {
      if (![[NSFileManager defaultManager]
              isWritableFileAtPath:@"/Applications"])
      local_reasons |= GCCC_ERROR_ACCESSDENIED;
    }

  }
  if (reasons != NULL)
    *reasons = local_reasons;
  return local_reasons == 0;
}

int InstallGoogleChrome(const char* source_path,
                        const char* brand_code,
                        const char* master_prefs_contents,
                        unsigned master_prefs_contents_size) {
  if (!GoogleChromeCompatibilityCheck(NULL))
    return 0;

  @autoreleasepool {
    passwd* user = GetRealUserId();
    if (!user)
      return 0;

    NSString* app_path = [NSString stringWithUTF8String:source_path];
    NSString* info_plist_path =
        [app_path stringByAppendingPathComponent:@"Contents/Info.plist"];
    NSDictionary* info_plist =
        [NSDictionary dictionaryWithContentsOfFile:info_plist_path];

    // Use install.sh from the Chrome app bundle to copy Chrome to its
    // destination.
    NSString* install_script = PathToInstallScript(app_path, info_plist);
    if (!install_script) {
      return 0;
    }

    @try {
      NSTask* task = [[[NSTask alloc] init] autorelease];

      // install.sh tries to make the installed app admin-writable, but
      // only when it's not run as root.
      if (geteuid() == 0) {
        // Use |su $(whoami)| instead of sudo -u. If the current user is in more
        // than 16 groups, |sudo -u $(whoami)| will drop all but the first 16
        // groups, which can lead to problems (e.g. if "admin" is one of the
        // dropped groups).
        // Since geteuid() is 0, su won't prompt for a password.
        NSString* run_as = [NSString stringWithUTF8String:user->pw_name];
        [task setLaunchPath:@"/usr/bin/su"];

        NSString* single_quote_escape = @"'\"'\"'";
        NSString* install_script_quoted = [install_script
            stringByReplacingOccurrencesOfString:@"'"
                                      withString:single_quote_escape];
        NSString* app_path_quoted =
            [app_path stringByReplacingOccurrencesOfString:@"'"
                                                withString:single_quote_escape];
        NSString* install_path_quoted = [kChromeInstallPath
            stringByReplacingOccurrencesOfString:@"'"
                                      withString:single_quote_escape];

        NSString* install_script_execution =
            [NSString stringWithFormat:@"exec '%@' '%@' '%@'",
                                       install_script_quoted,
                                       app_path_quoted,
                                       install_path_quoted];
        [task setArguments:
            @[run_as, @"-c", install_script_execution]];
      } else {
        [task setLaunchPath:install_script];
        [task setArguments:@[app_path, kChromeInstallPath]];
      }

      [task launch];
      [task waitUntilExit];
      if ([task terminationStatus] != 0) {
        return 0;
      }
    }
    @catch (id exception) {
      return 0;
    }

    // Set brand code. If Chrome's Info.plist contains a brand code, use that.
    NSString* info_plist_brand = [info_plist objectForKey:kBrandKey];
    if (info_plist_brand &&
        [info_plist_brand respondsToSelector:@selector(UTF8String)])
      brand_code = [info_plist_brand UTF8String];

    BOOL valid_brand_code = brand_code && strlen(brand_code) == 4 &&
        isbrandchar(brand_code[0]) && isbrandchar(brand_code[1]) &&
        isbrandchar(brand_code[2]) && isbrandchar(brand_code[3]);

    NSString* brand_path = nil;
    if (valid_brand_code)
      brand_path = WriteBrandCode(brand_code, user);

    // Write master prefs.
    if (master_prefs_contents)
      WriteMasterPrefs(master_prefs_contents, master_prefs_contents_size, user);

    // TODO Set default browser if requested.
  }
  return 1;
}

int LaunchGoogleChrome() {
  @autoreleasepool {
    passwd* user = GetRealUserId();
    if (!user)
      return 0;

    NSString* app_path;

    NSString* path;
    if (FindChromeTicket(kUserTicket, user, &path) && path)
      app_path = path;
    else if (FindChromeTicket(kSystemTicket, NULL, &path) && path)
      app_path = path;
    else
      app_path = kChromeInstallPath;

    // NSWorkspace launches processes as the current console owner,
    // even when running with euid of 0.
    return [[NSWorkspace sharedWorkspace] launchApplication:app_path];
  }
}
