File: Security.st

package info (click to toggle)
gnu-smalltalk 3.2.4-2.1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 32,688 kB
  • ctags: 14,104
  • sloc: ansic: 87,424; sh: 22,729; asm: 8,465; perl: 4,513; cpp: 3,548; xml: 1,669; awk: 1,581; yacc: 1,357; makefile: 1,237; lisp: 855; lex: 843; sed: 258; objc: 124
file content (270 lines) | stat: -rw-r--r-- 7,292 bytes parent folder | download | duplicates (6)
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
"======================================================================
|
|   Security-related Class Definitions
|
|
 ======================================================================"

"======================================================================
|
| Copyright 2003
| Free Software Foundation, Inc.
| Written by Paolo Bonzini.
|
| This file is part of the GNU Smalltalk class library.
|
| The GNU Smalltalk class library is free software; you can redistribute it
| and/or modify it under the terms of the GNU Lesser General Public License
| as published by the Free Software Foundation; either version 2.1, or (at
| your option) any later version.
| 
| The GNU Smalltalk class library is distributed in the hope that it will be
| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
| General Public License for more details.
| 
| You should have received a copy of the GNU Lesser General Public License
| along with the GNU Smalltalk class library; see the file COPYING.LIB.
| If not, write to the Free Software Foundation, 59 Temple Place - Suite
| 330, Boston, MA 02110-1301, USA.  
|
 ======================================================================"



Object subclass: Permission [
    | name actions target positive |
    
    <category: 'Language-Security'>
    <comment: 'I am the basic class that represents whether operations that could harm
the system''s security are allowed or denied.'>

    Permission class >> name: aSymbol target: aTarget actions: actionsArray [
	<category: 'testing'>
	^(self new)
	    name: aSymbol;
	    target: aTarget;
	    actions: actionsArray;
	    yourself
    ]

    Permission class >> name: aSymbol target: aTarget action: action [
	<category: 'testing'>
	^self 
	    name: aSymbol
	    target: aTarget
	    actions: {action}
    ]

    Permission class >> allowing: aSymbol target: aTarget actions: actionsArray [
	<category: 'testing'>
	^(self 
	    name: aSymbol
	    target: aTarget
	    actions: actionsArray) allow
    ]

    Permission class >> allowing: aSymbol target: aTarget action: action [
	<category: 'testing'>
	^(self 
	    name: aSymbol
	    target: aTarget
	    actions: {action}) allow
    ]

    Permission class >> denying: aSymbol target: aTarget actions: actionsArray [
	<category: 'testing'>
	^(self 
	    name: aSymbol
	    target: aTarget
	    actions: actionsArray) deny
    ]

    Permission class >> denying: aSymbol target: aTarget action: action [
	<category: 'testing'>
	^(self 
	    name: aSymbol
	    target: aTarget
	    actions: {action}) deny
    ]

    Permission class >> granting: aSymbol target: aTarget actions: actionsArray [
	<category: 'testing'>
	^(self 
	    name: aSymbol
	    target: aTarget
	    actions: actionsArray) allow
    ]

    Permission class >> granting: aSymbol target: aTarget action: action [
	<category: 'testing'>
	^(self 
	    name: aSymbol
	    target: aTarget
	    actions: {action}) allow
    ]

    check: aPermission for: anObject [
	<category: 'testing'>
	^(self implies: aPermission) 
	    ifTrue: [self isAllowing]
	    ifFalse: [anObject isUntrusted not]
    ]

    implies: aPermission [
	<category: 'testing'>
	aPermission name = name ifFalse: [^false].
	(self target notNil and: [aPermission target notNil]) 
	    ifTrue: 
		[(self target isString and: [aPermission target isString]) 
		    ifTrue: [(self target match: aPermission target) ifFalse: [^false]]
		    ifFalse: [self target == aPermission target ifFalse: [^false]]].
	(self actions notNil and: [aPermission actions notNil]) 
	    ifTrue: 
		[aPermission actions size = 1 
		    ifTrue: [^self actions includes: (aPermission at: 1)].
		^aPermission actions allSatisfy: [:each | self actions includes: each]].
	^true
    ]

    action: anObject [
	<category: 'accessing'>
	self actions: {anObject}
    ]

    actions [
	<category: 'accessing'>
	^actions
    ]

    actions: anObject [
	<category: 'accessing'>
	actions isNil 
	    ifFalse: [self error: 'can set permission actions only once'].
	(actions allSatisfy: [:each | each isSymbol]) 
	    ifFalse: [self error: 'actions must be symbols'].
	actions := anObject copy asArray
    ]

    allow [
	<category: 'accessing'>
	positive isNil ifFalse: [self error: 'can set allow/deny only once'].
	positive := true
    ]

    allowing [
	<category: 'accessing'>
	| savePositive result |
	savePositive := positive.
	positive := true.
	result := self copy.
	positive := savePositive.
	^result
    ]

    deny [
	<category: 'accessing'>
	positive isNil ifFalse: [self error: 'can set allow/deny only once'].
	positive := false
    ]

    denying [
	<category: 'accessing'>
	| savePositive result |
	savePositive := positive.
	positive := false.
	result := self copy.
	positive := savePositive.
	^result
    ]

    isAllowing [
	<category: 'accessing'>
	^positive
    ]

    name [
	<category: 'accessing'>
	^name
    ]

    name: anObject [
	<category: 'accessing'>
	name isNil ifFalse: [self error: 'can set permission name only once'].
	anObject isSymbol 
	    ifFalse: [self error: 'permission name must be a symbol'].
	name := anObject copy
    ]

    target [
	<category: 'accessing'>
	^target
    ]

    target: anObject [
	<category: 'accessing'>
	target isNil ifFalse: [self error: 'can set permission target only once'].
	(target allSatisfy: [:each | each isSymbol]) 
	    ifFalse: [self error: 'target must be symbols'].
	target := anObject copy
    ]
]



Object subclass: SecurityPolicy [
    | dictionary owner |
    
    <category: 'Language-Security'>
    <comment: 'I am the class that represents which operations that could harm
the system''s security are allowed or denied to a particular class.  If
a class does not have a policy, it is allowed everything if it is trusted,
and denied everything if it is untrusted'>

    addPermission: aPermission [
	<category: 'modifying'>
	owner isNil 
	    ifFalse: [thisContext securityCheckFor: #securityManagement target: owner].
	dictionary isNil ifTrue: [dictionary := IdentityDictionary new].
	(dictionary at: aPermission name ifAbsentPut: [OrderedCollection new]) 
	    add: aPermission allowing
    ]

    removePermission: aPermission [
	<category: 'modifying'>
	owner isNil 
	    ifFalse: [thisContext securityCheckFor: #securityManagement target: owner].
	dictionary isNil ifTrue: [dictionary := IdentityDictionary new].
	(dictionary at: aPermission name ifAbsentPut: [OrderedCollection new]) 
	    add: aPermission denying
    ]

    withOwner: aClass [
	<category: 'modifying'>
	^(self copy)
	    owner: aClass;
	    yourself
    ]

    owner: aClass [
	<category: 'modifying'>
	thisContext securityCheckFor: #securityManagement target: aClass.
	dictionary := dictionary deepCopy.
	owner := aClass.
	^self
    ]

    check: aPermission [
	<category: 'querying'>
	^(dictionary at: aPermission name ifAbsent: [#()]) 
	    inject: owner isUntrusted not
	    into: [:old :perm | (perm implies: aPermission) ifTrue: [perm isAllowing] ifFalse: [old]]
    ]

    implies: aPermission [
	<category: 'querying'>
	^(dictionary at: aPermission name ifAbsent: [#()]) inject: false
	    into: [:old :perm | (perm implies: aPermission) ifTrue: [perm isAllowing] ifFalse: [old]]
    ]
]