Skip to content
This repository has been archived by the owner on Feb 20, 2020. It is now read-only.

Bug 1560388 - don't update macOS autologin settings within 10 seconds of user login #208

Merged
merged 1 commit into from
Jun 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .taskcluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ tasks:
- set CGO_ENABLED=1
- set GORACE=history_size=7
- C:\generic-worker\generic-worker-test-creds.cmd
- copy "%TASK_USER_CREDENTIALS%" "%CD%\next-task-user.json"
- 'go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=%revision%" -v -race ./...'
- set GW_TESTS_RUN_AS_TASK_USER=true
- 'go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=%revision%" -v -race'
Expand Down Expand Up @@ -146,6 +147,7 @@ tasks:
- go install -tags multiuser -v -ldflags "-X main.revision=%revision%" ./...
- set GORACE=history_size=7
- C:\generic-worker\generic-worker-test-creds.cmd
- copy "%TASK_USER_CREDENTIALS%" "%CD%\next-task-user.json"
- 'go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=%revision%" -v ./...'
- set GW_TESTS_RUN_AS_TASK_USER=true
- 'go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=%revision%" -v'
Expand Down Expand Up @@ -229,6 +231,7 @@ tasks:
- set CGO_ENABLED=1
- set GORACE=history_size=7
- C:\generic-worker\generic-worker-test-creds.cmd
- copy "%TASK_USER_CREDENTIALS%" "%CD%\next-task-user.json"
- 'go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=%revision%" -v -race ./...'
- set GW_TESTS_RUN_AS_TASK_USER=true
- 'go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=%revision%" -v -race'
Expand Down Expand Up @@ -374,6 +377,7 @@ tasks:
go install -tags multiuser -v -ldflags "-X main.revision=$(git rev-parse HEAD)" ./...
# output of wc command can contain spaces on darwin, so no quotes around expression
test $(git status --porcelain | wc -l) == 0
cp "${TASK_USER_CREDENTIALS}" next-task-user.json
GORACE=history_size=7 CGO_ENABLED=1 go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=$(git rev-parse HEAD)" -race -v ./...
GW_TESTS_RUN_AS_TASK_USER=true GORACE=history_size=7 CGO_ENABLED=1 go test -tags multiuser -timeout 45m -ldflags "-X github.com/taskcluster/generic-worker.revision=$(git rev-parse HEAD)" -race -v
ineffassign .
Expand Down
42 changes: 28 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,31 +139,45 @@ with automatic quarantining of workers, waiting for custom events, etc).

## macOS - multiuser/simple build

__These instructions require macOS Mojave version 10.14.x__

1. Log into target user account:

__Simple build__: Create user account `genericworker` to run the worker
under, and log in as `genericworker` in a shell.

__Multiuser build__: Log in as root (`sudo su -`) in a shell.
__Multiuser build__: Log in as _root_ (`sudo su -`) in a shell.

2. __Multiuser build only__

Disable wizards/warning pop ups on first-login to user accounts:

* `git clone git@github.com:rtrouton/profiles.git`
* `git -C profiles checkout f23bc6146ca570108dbaa9e3cb8da954ce325002` (just because this is the version I tested, later versions may also be fine)
* `profiles install -path=profiles/SkipSiriSetup/SkipSiriSetup.mobileconfig`
* `profiles install -path=profiles/SkipDarkorLightAppearance/SkipDarkorLightAppearance.mobileconfig`
* `profiles install -path=profiles/Disable32BitApplicationWarning/10.14/Disable32BitApplicationWarning.mobileconfig`
* `profiles install -path=profiles/SkipDataAndPrivacy/SkipDataAndPrivacy.mobileconfig`
* `profiles install -path=profiles/SkipiCloudSetup/SkipiCloudSetup.mobileconfig`

2. Download `generic-worker` from
3. Download `generic-worker` from
https://github.com/taskcluster/generic-worker/releases and place it in
`/usr/local/bin/generic-worker`.

3. Download livelog from https://github.com/taskcluster/livelog/releases and
4. Download livelog from https://github.com/taskcluster/livelog/releases and
place it in `/usr/local/bin/livelog`.

4. Download taskcluster proxy from
5. Download taskcluster proxy from
https://github.com/taskcluster/taskcluster-proxy/releases and place it in
`/usr/local/bin/taskcluster-proxy`.

5. Make `generic-worker`, `taskcluster-proxy`, `livelog` binaries executable:
6. Make `generic-worker`, `taskcluster-proxy`, `livelog` binaries executable:

* `chmod a+x /usr/local/bin/{generic-worker,taskcluster-proxy,livelog}`

6. Generate a key for signing artifacts:
7. Generate a key for signing artifacts:

* `mkdir /etc/generic-worker`
* `sudo mkdir /etc/generic-worker`

* __Simple build only__: `sudo chown genericworker:staff /etc/generic-worker`

Expand All @@ -174,7 +188,7 @@ with automatic quarantining of workers, waiting for custom events, etc).
standard out. Keep a copy of the public key if you wish to validate artifact
signatures.

6. Create the file `/usr/local/bin/run-generic-worker.sh` with the following content:
8. Create the file `/usr/local/bin/run-generic-worker.sh` with the following content:

```
#!/bin/bash
Expand All @@ -193,11 +207,11 @@ with automatic quarantining of workers, waiting for custom events, etc).
/usr/local/bin/generic-worker run --config /etc/generic-worker/config
```

7. Run the following to make the `run-generic-worker.sh` script executable:
9. Run the following to make the `run-generic-worker.sh` script executable:

* `chmod a+x /usr/local/bin/run-generic-worker.sh`

8. Create `/etc/generic-worker/config` with appropriate configuration settings
10. Create `/etc/generic-worker/config` with appropriate configuration settings
(see `generic-worker --help` for details). Something like this:

```
Expand Down Expand Up @@ -227,7 +241,7 @@ with automatic quarantining of workers, waiting for custom events, etc).
}
```

9. Create launch daemon:
11. Create launch daemon:

Create the file `/Library/LaunchDaemons/com.mozilla.genericworker.plist`
with the following content:
Expand All @@ -254,11 +268,11 @@ with automatic quarantining of workers, waiting for custom events, etc).
</plist>
```

10. Install launch daemon:
12. Install launch daemon:

* `sudo launchctl load -w /Library/LaunchDaemons/com.mozilla.genericworker.plist`

11. Watch for logs in `/var/log/generic-worker/`.
13. Watch for logs in `/var/log/generic-worker/`.


## Linux simple/docker build
Expand Down Expand Up @@ -753,7 +767,7 @@ allowed in the generic-worker config file:
openpgpSigningKeyLocation
```

**Please note, you need to remove this config property from your config file, if it exists, in order to
**Please note, you need to remove this config property from your config file, if it exists, in order to
work with generic-worker 14 onwards.**

* [Bug 1436195 - Deploy websocktunnel on generic-worker](https://bugzil.la/1436195)
Expand Down
33 changes: 33 additions & 0 deletions fileutil/fileutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
Expand Down Expand Up @@ -39,3 +40,35 @@ func CalculateSHA256(file string) (hash string, err error) {
hash = hex.EncodeToString(hasher.Sum(nil))
return
}

func Copy(dst, src string) (nBytes int64, err error) {
var sourceFileStat os.FileInfo
sourceFileStat, err = os.Stat(src)
if err != nil {
return
}
if !sourceFileStat.Mode().IsRegular() {
err = fmt.Errorf("Cannot copy %s to %s: %s is not a regular file", src, dst, src)
return
}
var source *os.File
source, err = os.Open(src)
if err != nil {
return
}
closeFile := func(file *os.File) {
err2 := file.Close()
if err == nil {
err = err2
}
}
defer closeFile(source)
var destination *os.File
destination, err = os.Create(dst)
if err != nil {
return
}
defer closeFile(destination)
nBytes, err = io.Copy(destination, source)
return
}
37 changes: 12 additions & 25 deletions kc/kc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
package kc

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os/exec"
Expand All @@ -17,10 +15,10 @@ var (
)

func Encode(password []byte) []byte {
overflow := len(password) % len(MagicKey)
paddingLength := 0
overflow := (len(password) + 1) % (len(MagicKey) + 1)
paddingLength := 1
if overflow > 0 {
paddingLength = len(MagicKey) - overflow
paddingLength += len(MagicKey) + 1 - overflow
}
data := append(password, make([]byte, paddingLength, paddingLength)...)
for j := 0; j < len(data); j++ {
Expand All @@ -41,22 +39,13 @@ func Decode(encoded []byte) []byte {
}

func SetAutoLogin(user string, password []byte) (err error) {
pList, err := loginWindowPList()
output, err := exec.Command("defaults", "write", "/Library/Preferences/com.apple.loginwindow", "autoLoginUser", "-string", user).CombinedOutput()
if err != nil {
return
return fmt.Errorf("Error setting autoLoginUser: %v, Output: %v", err, string(output))
}
pList["autoLoginUser"] = user
var data []byte
data, err = json.Marshal(&pList)
output, err = exec.Command("defaults", "write", "/Library/Preferences/com.apple.loginwindow", "autoLoginUserScreenLocked", "-bool", "false").CombinedOutput()
if err != nil {
return
}
buf := bytes.NewBuffer(data)
cmd := exec.Command("/usr/bin/sudo", "/usr/bin/plutil", "-convert", "binary1", "-", "-o", "/Library/Preferences/com.apple.loginwindow.plist")
cmd.Stdin = buf
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("Error: %v, Output: %v", err, string(output))
return fmt.Errorf("Error setting autoLoginUserScreenLocked: %v, Output: %v", err, string(output))
}
encodedPassword := Encode(password)
return ioutil.WriteFile("/etc/kcpassword", encodedPassword, 0600)
Expand All @@ -72,14 +61,12 @@ func AutoLoginUser() (user string, password []byte, err error) {
}

func AutoLoginUsername() (user string, err error) {
pList, err := loginWindowPList()
output, err := exec.Command("defaults", "read", "/Library/Preferences/com.apple.loginwindow", "autoLoginUser").CombinedOutput()
if err != nil {
return "", err
}
if user, ok := pList["autoLoginUser"].(string); ok {
return user, nil
return "", fmt.Errorf("Error reading autoLoginUser: %v, Output: %v", err, string(output))
}
return "", errors.New("No auto login user")
// remove last char (\n) from string
return string(output[:len(output)-1]), nil
}

func AutoLoginPassword() (password []byte, err error) {
Expand All @@ -91,7 +78,7 @@ func AutoLoginPassword() (password []byte, err error) {
return
}

func loginWindowPList() (data map[string]interface{}, err error) {
func LoginWindowPList() (data map[string]interface{}, err error) {
var loginWindowPListBytes []byte
loginWindowPListBytes, err = exec.Command("/usr/bin/sudo", "/usr/bin/plutil", "-convert", "json", "/Library/Preferences/com.apple.loginwindow.plist", "-o", "-").CombinedOutput()
if err != nil {
Expand Down
22 changes: 13 additions & 9 deletions kc/kc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,27 @@ import (

func ExampleEncode() {
fmt.Printf("%x\n", kc.Encode([]byte(`mysecretpassword`)))
// 11 byte password should be 11 bytes when encoded
// 11 byte password should be 12 bytes when encoded
fmt.Printf("%x\n", kc.Encode([]byte(`fredmary123`)))
// 12 byte password should be 22 bytes when encoded (since encoded
// passwords should always be a multiple of 11 bytes)
// 12 byte password should be 24 bytes when encoded (since encoded
// passwords should always be a multiple of 12 bytes, but trailing
// 0 byte is included in encoding, so 12 byte password is stored
// as 13 bytes, meaning 24 bytes are needed not 12).
fmt.Printf("%x\n", kc.Encode([]byte(`fredmary1234`)))
fmt.Printf("%x\n", kc.Encode([]byte(`12345!@#$%{}PO"we[]{*&$!#+^ffdSWrhd4b#`)))
// Output:
// 10f02146b1ceb89ed3d86c0efe3d51b6bcddeaa3b91f
// 1bfb3747bfddaf93928b2c
// 1bfb3747bfddaf93928b2c49895223d2bcddeaa3b91f
// 4cbb6117e79d9dc9879c6400d91d01a5d986b7d8933959a871088cdabb8ef0ee6d15ed6641f1bcddeaa3b91f
// 10f02146b1ceb89ed3d86c0efe3d51b6bcddeaa3b91f7d89
// 1bfb3747bfddaf93928b2c7d
// 1bfb3747bfddaf93928b2c49895223d2bcddeaa3b91f7d89
// 4cbb6117e79d9dc9879c6400d91d01a5d986b7d8933959a871088cdabb8ef0ee6d15ed6641f1bcddeaa3b91f7d895223
}

func ExampleDecode() {
// Check case of no null byte terminator (password multiple of 11 bytes)
// Check case of no bytes after 0 byte terminator (password (12*n-1) bytes
// for integer n, n > 0)
fmt.Println(string(kc.Decode(kc.Encode([]byte("fredmary123")))))
// Check case of null byte terminator (password not multiple of 11 bytes)
// Check case of trailing bytes after 0 byte terminator (password not
// (12*n-1) bytes for integer n, n > 0)
fmt.Println(string(kc.Decode(kc.Encode([]byte("fredmary1234")))))
// Output:
// fredmary123
Expand Down
Loading