File: task.yaml

package info (click to toggle)
snapd 2.72-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 80,412 kB
  • sloc: sh: 16,506; ansic: 16,211; python: 11,213; makefile: 1,919; exp: 190; awk: 58; xml: 22
file content (175 lines) | stat: -rw-r--r-- 9,308 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
summary: Verify that snap-interfaces-requests-control grants read-access to relevant endpoints
details: |
    The snap-interfaces-requests-control interface grants access to prompting clients
    (e.g. prompting-client) to a subset of snapd's API endpoints needed
    to view and manage request prompts and request rules.

    Specifically:
      - /v2/notices: to read interfaces-requests-prompt and interfaces-requests-rule-update notices
      - /v2/interfaces/requests/prompts: to receive and reply to request prompts
      - /v2/interfaces/requests/rules: to view and manage request rules
      - /v2/system-info: to check whether prompting is supported/enabled
      - /v2/snaps/{name}: to get details about installed snaps

systems: [ubuntu-2*]

environment:
    # not all terminals support UTF-8, but Python tries to be smart and attempts
    # to guess the encoding as if the output would go to the terminal, but in
    # fact all the test does is pipe the output to (go)jq
    PYTHONIOENCODING: utf-8

prepare: |
    if os.query is-ubuntu 20.04; then
        tests.exec skip-test "Ubuntu 20.04 kernel doesn't support prompting" && exit 0
    fi
    if os.query is-ubuntu 22.04 && ! [[ "$SPREAD_BACKEND" =~ google ]]; then
        tests.exec skip-test "Ubuntu 22.04 kernel doesn't support prompting (except on google)" && exit 0
    fi
    if os.query is-ubuntu 22.04 && not tests.info is-reexec-in-use; then
        tests.exec skip-test "Ubuntu 22.04 AppArmor parser doesn't support prompting" && exit 0
    fi

    snap remove --purge api-client || true
    # prerequisite for having a prompts handler service
    snap set system experimental.user-daemons=true

debug: |
    tests.exec is-skipped && exit 0

    echo "Check kernel version"
    uname -a
    echo "Check kernel notification socket presence"
    if ls /sys/kernel/security/apparmor/.notify ; then
        echo "kernel notification socket exists"
    else
        echo "kernel notification socket does not exist"
    fi
    echo "Check system info"
    snap debug api /v2/system-info

execute: |
    tests.exec is-skipped && exit 0

    "$TESTSTOOLS"/snaps-state install-local api-client
    echo "The snap-interfaces-requests-control plug on the api-client snap is initially disconnected"
    snap connections api-client | MATCH "snap-interfaces-requests-control +api-client:snap-interfaces-requests-control +- +-"
    echo "Connect the snap-interfaces-requests-control plug"
    snap connect api-client:snap-interfaces-requests-control

    echo "Check snap can access interfaces-requests-prompt and interfaces-requests-rule-update notices under /v2/notices"
    api-client --socket /run/snapd-snap.socket "/v2/notices?types=interfaces-requests-prompt" | \
        gojq '."status-code"' | MATCH '^200$'
    api-client --socket /run/snapd-snap.socket "/v2/notices?types=interfaces-requests-rule-update" | \
        gojq '."status-code"' | MATCH '^200$'
    api-client --socket /run/snapd-snap.socket "/v2/notices" | gojq '."status-code"' | MATCH '^200$'
    echo "But not other notice types"
    api-client --socket /run/snapd-snap.socket "/v2/notices?types=change-update,warning" | \
        gojq '."status-code"' | MATCH '^403$'

    echo "Check snap can access system info via /v2/system-info"
    api-client --socket /run/snapd-snap.socket "/v2/system-info" | gojq '."status-code"' | MATCH '^200$'

    SNAP_NAME="snapd"
    if os.query is-core16; then
        SNAP_NAME="core"
    fi

    echo "Check snap can access snap info via /v2/snaps/{name}"
    api-client --socket /run/snapd-snap.socket "/v2/snaps/$SNAP_NAME" | gojq '."status-code"' | MATCH '^200$'

    echo "Enable AppArmor prompting experimental feature"
    snap set system experimental.apparmor-prompting=true

    echo 'Check "apparmor-prompting" is shown as enabled in /v2/system-info'
    api-client --socket /run/snapd-snap.socket "/v2/system-info" | \
        gojq '."result"."features"."apparmor-prompting"."enabled"' | MATCH '^true$'

    echo "Check snap can access prompts via /v2/interfaces/requests/prompts"
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/prompts" | \
        gojq '."status-code"' | MATCH '^200$'
    echo "Check snap can access a single prompt via /v2/interfaces/requests/prompts/<ID>"
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/prompts/1234123412341234" | \
        gojq '."status-code"' | MATCH '^404$' # nonexistent prompt ID
    # TODO: include the "home" interface and create a request prompt by attempting to list contents of $HOME
    # PROMPT_ID=FIXME
    # api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/prompts/$PROMPT_ID" | \
    #     gojq '."status-code"' | MATCH '^200$'
    # echo "Check snap can reply to a prompt via /v2/interfaces/requests/prompts/<ID>
    # TODO: split this line more
    # api-client --socket /run/snapd-snap.socket --method=POST '{"action":"allow","lifespan":"forever","constraints":{"path-pattern":"/**","permissions":["read"]}}' "/v2/interfaces/requests/prompts/$PROMPT_ID" | \
    #     gojq '."status-code"' | MATCH '^200$'
    # TODO: check that thread which triggered request completed successfully

    echo "Check snap can access rules via /v2/interfaces/requests/rules"
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/rules" | \
        gojq '."status-code"' | MATCH '^200$'

    # XXX: creating rules requires polkit authentication, so for now, use snap debug api instead of api-client
    # echo "Check snap can create rule via /v2/interfaces/requests/rules"
    # api-client --socket /run/snapd-snap.socket --method=POST '{"action":"add","rule":{"snap":"api-client","interface":"home","constraints":{"path-pattern":"/path/to/file","permissions":{"read":{"outcome":"allow","lifespan":"forever"},"write":{"outcome":"deny","lifespan":"forever"},"execute":{"outcome":"allow","lifespan":"timespan","duration":"1h"}}}}}' "/v2/interfaces/requests/rules" > result.json
    echo '{
      "action": "add",
      "rule": {
        "snap": "api-client",
        "interface": "home",
        "constraints": {
          "path-pattern": "/path/to/file",
          "permissions": {
            "read": {
              "outcome": "allow",
              "lifespan": "forever"
            },
            "write": {
              "outcome": "deny",
              "lifespan": "forever"
            },
            "execute": {
              "outcome": "allow",
              "lifespan": "timespan",
              "duration": "1h"
            }
          }
        }
      }
    }' | \
        snap debug api -X POST -H 'Content-Type: application/json' "/v2/interfaces/requests/rules" | \
        tee result.json
    gojq '."status-code"' < result.json | MATCH '^200$'
    RULE_ID=$(gojq '."result"."id"' < result.json | tr -d '"')
    echo "Check snap can view a single rule via /v2/interfaces/requests/rules/<ID>"
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/rules/$RULE_ID" | \
        gojq '."status-code"' | MATCH '^200$'
    # XXX: modifying rules requires polkit authentication
    # echo "Check snap can modify a single rule via /v2/interfaces/requests/rules/<ID>"
    # api-client --socket /run/snapd-snap.socket --method=POST '{"action":"remove"}' "/v2/interfaces/requests/rules/$RULE_ID" | gojq '."status-code"' | MATCH '^200$'

    echo "Check that snap can access icons info via /v2/icons and gets 404 if icon is not found"
    api-client --socket /run/snapd-snap.socket "/v2/icons/api-client/icon" | gojq '."status-code"' | MATCH '^404$'

    echo "Without snap-interfaces-requests-control the snap cannot access those API endpoints"
    snap disconnect api-client:snap-interfaces-requests-control

    # XXX: this relies on the fact that prompting remains enabled, even though
    # the prerequisite of there being a snap with snap-interfaces-requests-control
    # connected and a handler service running is no longer true. Otherwise, the error
    # code would be 500 instead of 403.
    api-client --socket /run/snapd-snap.socket "/v2/notices?types=interfaces-requests-prompt" | \
        gojq '."status-code"' | MATCH '^403$'
    api-client --socket /run/snapd-snap.socket "/v2/notices?types=interfaces-requests-rule-update" | \
        gojq '."status-code"' | MATCH '^403$'
    api-client --socket /run/snapd-snap.socket "/v2/system-info" | \
        gojq '."status-code"' | MATCH '^403$'
    api-client --socket /run/snapd-snap.socket "/v2/snaps/$SNAP_NAME" | \
        gojq '."status-code"' | MATCH '^403$'
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/prompts" | \
        gojq '."status-code"' | MATCH '^403$'
    # Try to access an arbitrary prompt ID, should fail with 403 rather than 404
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/prompts/1234123412341234" | \
        gojq '."status-code"' | MATCH '^403$'
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/rules" | \
        gojq '."status-code"' | MATCH '^403$'
    api-client --socket /run/snapd-snap.socket "/v2/interfaces/requests/rules/$RULE_ID" | \
        gojq '."status-code"' | MATCH '^403$'
    api-client --socket /run/snapd-snap.socket "/v2/icons/api-client/icon" | \
        gojq '."status-code"' | MATCH '^403$'