Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/util/princflags.py
34878 views
1
import re
2
3
# Module for translating KDB principal flags between string and
4
# integer forms.
5
#
6
# When run as a standalone script, print out C tables to insert into
7
# lib/kadm5/str_conv.c.
8
9
# KDB principal flag definitions copied from kdb.h
10
11
KRB5_KDB_DISALLOW_POSTDATED = 0x00000001
12
KRB5_KDB_DISALLOW_FORWARDABLE = 0x00000002
13
KRB5_KDB_DISALLOW_TGT_BASED = 0x00000004
14
KRB5_KDB_DISALLOW_RENEWABLE = 0x00000008
15
KRB5_KDB_DISALLOW_PROXIABLE = 0x00000010
16
KRB5_KDB_DISALLOW_DUP_SKEY = 0x00000020
17
KRB5_KDB_DISALLOW_ALL_TIX = 0x00000040
18
KRB5_KDB_REQUIRES_PRE_AUTH = 0x00000080
19
KRB5_KDB_REQUIRES_HW_AUTH = 0x00000100
20
KRB5_KDB_REQUIRES_PWCHANGE = 0x00000200
21
KRB5_KDB_DISALLOW_SVR = 0x00001000
22
KRB5_KDB_PWCHANGE_SERVICE = 0x00002000
23
KRB5_KDB_SUPPORT_DESMD5 = 0x00004000
24
KRB5_KDB_NEW_PRINC = 0x00008000
25
KRB5_KDB_OK_AS_DELEGATE = 0x00100000
26
KRB5_KDB_OK_TO_AUTH_AS_DELEGATE = 0x00200000
27
KRB5_KDB_NO_AUTH_DATA_REQUIRED = 0x00400000
28
KRB5_KDB_LOCKDOWN_KEYS = 0x00800000
29
30
# Input tables -- list of tuples of the form (name, flag, invert)
31
32
# Input forms from kadmin.c
33
_kadmin_pflags = [
34
("allow_postdated", KRB5_KDB_DISALLOW_POSTDATED, True),
35
("allow_forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),
36
("allow_tgs_req", KRB5_KDB_DISALLOW_TGT_BASED, True),
37
("allow_renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),
38
("allow_proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),
39
("allow_dup_skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),
40
("allow_tix", KRB5_KDB_DISALLOW_ALL_TIX, True),
41
("requires_preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),
42
("requires_hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),
43
("needchange", KRB5_KDB_REQUIRES_PWCHANGE, False),
44
("allow_svr", KRB5_KDB_DISALLOW_SVR, True),
45
("password_changing_service", KRB5_KDB_PWCHANGE_SERVICE, False),
46
("support_desmd5", KRB5_KDB_SUPPORT_DESMD5, False),
47
("ok_as_delegate", KRB5_KDB_OK_AS_DELEGATE, False),
48
("ok_to_auth_as_delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),
49
("no_auth_data_required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),
50
("lockdown_keys", KRB5_KDB_LOCKDOWN_KEYS, False),
51
]
52
53
# Input forms from lib/kadm5/str_conv.c
54
_strconv_pflags = [
55
("postdateable", KRB5_KDB_DISALLOW_POSTDATED, True),
56
("forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),
57
("tgt-based", KRB5_KDB_DISALLOW_TGT_BASED, True),
58
("renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),
59
("proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),
60
("dup-skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),
61
("allow-tickets", KRB5_KDB_DISALLOW_ALL_TIX, True),
62
("preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),
63
("hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),
64
("ok-as-delegate", KRB5_KDB_OK_AS_DELEGATE, False),
65
("pwchange", KRB5_KDB_REQUIRES_PWCHANGE, False),
66
("service", KRB5_KDB_DISALLOW_SVR, True),
67
("pwservice", KRB5_KDB_PWCHANGE_SERVICE, False),
68
("md5", KRB5_KDB_SUPPORT_DESMD5, False),
69
("ok-to-auth-as-delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),
70
("no-auth-data-required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),
71
("lockdown-keys", KRB5_KDB_LOCKDOWN_KEYS, False),
72
]
73
74
# kdb.h symbol prefix
75
_prefix = 'KRB5_KDB_'
76
_prefixlen = len(_prefix)
77
78
# Names of flags, as printed by kadmin (derived from kdb.h symbols).
79
# To be filled in by _setup_tables().
80
_flagnames = {}
81
82
# Translation table to map hyphens to underscores
83
_squash = str.maketrans('-', '_')
84
85
# Combined input-to-flag lookup table, to be filled in by
86
# _setup_tables()
87
pflags = {}
88
89
# Tables of ftuples, to be filled in by _setup_tables()
90
kadmin_ftuples = []
91
strconv_ftuples = []
92
sym_ftuples = []
93
all_ftuples = []
94
95
# Inverted table to look up ftuples by flag value, to be filled in by
96
# _setup_tables()
97
kadmin_itable = {}
98
strconv_itable = {}
99
sym_itable = {}
100
101
102
# Bundle some methods that are useful for writing tests.
103
class Ftuple(object):
104
def __init__(self, name, flag, invert):
105
self.name = name
106
self.flag = flag
107
self.invert = invert
108
109
def __repr__(self):
110
return "Ftuple" + str((self.name, self.flag, self.invert))
111
112
def flagname(self):
113
return _flagnames[self.flag]
114
115
def setspec(self):
116
return ('-' if self.invert else '+') + self.name
117
118
def clearspec(self):
119
return ('+' if self.invert else '-') + self.name
120
121
def spec(self, doset):
122
return self.setspec() if doset else self.clearspec()
123
124
125
def _setup_tables():
126
# Filter globals for 'KRB5_KDB_' prefix to create lookup tables.
127
# Make the reasonable assumption that the Python runtime doesn't
128
# define any names with that prefix by default.
129
global _flagnames
130
for k, v in globals().items():
131
if k.startswith(_prefix):
132
_flagnames[v] = k[_prefixlen:]
133
134
# Construct an input table based on kdb.h constant names by
135
# truncating the "KRB5_KDB_" prefix and downcasing.
136
sym_pflags = []
137
for v, k in sorted(_flagnames.items()):
138
sym_pflags.append((k.lower(), v, False))
139
140
global kadmin_ftuples, strconv_ftuples, sym_ftuples, all_ftuples
141
for x in _kadmin_pflags:
142
kadmin_ftuples.append(Ftuple(*x))
143
for x in _strconv_pflags:
144
strconv_ftuples.append(Ftuple(*x))
145
for x in sym_pflags:
146
sym_ftuples.append(Ftuple(*x))
147
all_ftuples = kadmin_ftuples + strconv_ftuples + sym_ftuples
148
149
# Populate combined input-to-flag lookup table. This will
150
# eliminate some duplicates.
151
global pflags
152
for x in all_ftuples:
153
name = x.name.translate(_squash)
154
pflags[name] = x
155
156
global kadmin_itable, strconv_itable, sym_itable
157
for x in kadmin_ftuples:
158
kadmin_itable[x.flag] = x
159
for x in strconv_ftuples:
160
strconv_itable[x.flag] = x
161
for x in sym_ftuples:
162
sym_itable[x.flag] = x
163
164
165
# Convert the bit number of a flag to a string. Remove the
166
# 'KRB5_KDB_' prefix. Give an 8-digit hexadecimal number if the flag
167
# is unknown.
168
def flagnum2str(n):
169
s = _flagnames.get(1 << n)
170
if s is None:
171
return "0x%08x" % ((1 << n) & 0xffffffff)
172
return s
173
174
175
# Return a list of flag names from a flag word.
176
def flags2namelist(flags):
177
a = []
178
for n in range(32):
179
if flags & (1 << n):
180
a.append(flagnum2str(n))
181
return a
182
183
184
# Given a single specifier in the form {+|-}flagname, return a tuple
185
# of the form (flagstoset, flagstoclear).
186
def flagspec2mask(s):
187
req_neg = False
188
if s[0] == '-':
189
req_neg = True
190
s = s[1:]
191
elif s[0] == '+':
192
s = s[1:]
193
194
s = s.lower().translate(_squash)
195
x = pflags.get(s)
196
if x is not None:
197
flag, invert = x.flag, x.invert
198
else:
199
# Maybe it's a hex number.
200
if not s.startswith('0x'):
201
raise ValueError
202
flag, invert = int(s, 16), False
203
204
if req_neg:
205
invert = not invert
206
return (0, ~flag) if invert else (flag, ~0)
207
208
209
# Given a string containing a space/comma separated list of specifiers
210
# of the form {+|-}flagname, return a tuple of the form (flagstoset,
211
# flagstoclear). This shares the same limitation as
212
# kadm5int_acl_parse_restrictions() of losing the distinction between
213
# orderings when the same flag bit appears in both the positive and
214
# the negative sense.
215
def speclist2mask(s):
216
toset, toclear = (0, ~0)
217
for x in re.split('[\t, ]+', s):
218
fset, fclear = flagspec2mask(x)
219
toset |= fset
220
toclear &= fclear
221
222
return toset, toclear
223
224
225
# Print C table of input flag specifiers for lib/kadm5/str_conv.c.
226
def _print_ftbl():
227
print('static const struct flag_table_row ftbl[] = {')
228
a = sorted(pflags.items(), key=lambda k, v: (v.flag, -v.invert, k))
229
for k, v in a:
230
s1 = ' {"%s",' % k
231
s2 = '%-31s KRB5_KDB_%s,' % (s1, v.flagname())
232
print('%-63s %d},' % (s2, 1 if v.invert else 0))
233
234
print('};')
235
print('#define NFTBL (sizeof(ftbl) / sizeof(ftbl[0]))')
236
237
238
# Print C table of output flag names for lib/kadm5/str_conv.c.
239
def _print_outflags():
240
print('static const char *outflags[] = {')
241
for i in range(32):
242
flag = 1 << i
243
if flag > max(_flagnames.keys()):
244
break
245
try:
246
s = ' "%s",' % _flagnames[flag]
247
except KeyError:
248
s = ' NULL,'
249
print('%-32s/* 0x%08x */' % (s, flag))
250
251
print('};')
252
print('#define NOUTFLAGS (sizeof(outflags) / sizeof(outflags[0]))')
253
254
255
# Print out C tables to insert into lib/kadm5/str_conv.c.
256
def _main():
257
_print_ftbl()
258
print
259
_print_outflags()
260
261
262
_setup_tables()
263
264
265
if __name__ == '__main__':
266
_main()
267
268