Path: blob/main/crypto/krb5/src/util/princflags.py
34878 views
import re12# Module for translating KDB principal flags between string and3# integer forms.4#5# When run as a standalone script, print out C tables to insert into6# lib/kadm5/str_conv.c.78# KDB principal flag definitions copied from kdb.h910KRB5_KDB_DISALLOW_POSTDATED = 0x0000000111KRB5_KDB_DISALLOW_FORWARDABLE = 0x0000000212KRB5_KDB_DISALLOW_TGT_BASED = 0x0000000413KRB5_KDB_DISALLOW_RENEWABLE = 0x0000000814KRB5_KDB_DISALLOW_PROXIABLE = 0x0000001015KRB5_KDB_DISALLOW_DUP_SKEY = 0x0000002016KRB5_KDB_DISALLOW_ALL_TIX = 0x0000004017KRB5_KDB_REQUIRES_PRE_AUTH = 0x0000008018KRB5_KDB_REQUIRES_HW_AUTH = 0x0000010019KRB5_KDB_REQUIRES_PWCHANGE = 0x0000020020KRB5_KDB_DISALLOW_SVR = 0x0000100021KRB5_KDB_PWCHANGE_SERVICE = 0x0000200022KRB5_KDB_SUPPORT_DESMD5 = 0x0000400023KRB5_KDB_NEW_PRINC = 0x0000800024KRB5_KDB_OK_AS_DELEGATE = 0x0010000025KRB5_KDB_OK_TO_AUTH_AS_DELEGATE = 0x0020000026KRB5_KDB_NO_AUTH_DATA_REQUIRED = 0x0040000027KRB5_KDB_LOCKDOWN_KEYS = 0x008000002829# Input tables -- list of tuples of the form (name, flag, invert)3031# Input forms from kadmin.c32_kadmin_pflags = [33("allow_postdated", KRB5_KDB_DISALLOW_POSTDATED, True),34("allow_forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),35("allow_tgs_req", KRB5_KDB_DISALLOW_TGT_BASED, True),36("allow_renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),37("allow_proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),38("allow_dup_skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),39("allow_tix", KRB5_KDB_DISALLOW_ALL_TIX, True),40("requires_preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),41("requires_hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),42("needchange", KRB5_KDB_REQUIRES_PWCHANGE, False),43("allow_svr", KRB5_KDB_DISALLOW_SVR, True),44("password_changing_service", KRB5_KDB_PWCHANGE_SERVICE, False),45("support_desmd5", KRB5_KDB_SUPPORT_DESMD5, False),46("ok_as_delegate", KRB5_KDB_OK_AS_DELEGATE, False),47("ok_to_auth_as_delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),48("no_auth_data_required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),49("lockdown_keys", KRB5_KDB_LOCKDOWN_KEYS, False),50]5152# Input forms from lib/kadm5/str_conv.c53_strconv_pflags = [54("postdateable", KRB5_KDB_DISALLOW_POSTDATED, True),55("forwardable", KRB5_KDB_DISALLOW_FORWARDABLE, True),56("tgt-based", KRB5_KDB_DISALLOW_TGT_BASED, True),57("renewable", KRB5_KDB_DISALLOW_RENEWABLE, True),58("proxiable", KRB5_KDB_DISALLOW_PROXIABLE, True),59("dup-skey", KRB5_KDB_DISALLOW_DUP_SKEY, True),60("allow-tickets", KRB5_KDB_DISALLOW_ALL_TIX, True),61("preauth", KRB5_KDB_REQUIRES_PRE_AUTH, False),62("hwauth", KRB5_KDB_REQUIRES_HW_AUTH, False),63("ok-as-delegate", KRB5_KDB_OK_AS_DELEGATE, False),64("pwchange", KRB5_KDB_REQUIRES_PWCHANGE, False),65("service", KRB5_KDB_DISALLOW_SVR, True),66("pwservice", KRB5_KDB_PWCHANGE_SERVICE, False),67("md5", KRB5_KDB_SUPPORT_DESMD5, False),68("ok-to-auth-as-delegate", KRB5_KDB_OK_TO_AUTH_AS_DELEGATE, False),69("no-auth-data-required", KRB5_KDB_NO_AUTH_DATA_REQUIRED, False),70("lockdown-keys", KRB5_KDB_LOCKDOWN_KEYS, False),71]7273# kdb.h symbol prefix74_prefix = 'KRB5_KDB_'75_prefixlen = len(_prefix)7677# Names of flags, as printed by kadmin (derived from kdb.h symbols).78# To be filled in by _setup_tables().79_flagnames = {}8081# Translation table to map hyphens to underscores82_squash = str.maketrans('-', '_')8384# Combined input-to-flag lookup table, to be filled in by85# _setup_tables()86pflags = {}8788# Tables of ftuples, to be filled in by _setup_tables()89kadmin_ftuples = []90strconv_ftuples = []91sym_ftuples = []92all_ftuples = []9394# Inverted table to look up ftuples by flag value, to be filled in by95# _setup_tables()96kadmin_itable = {}97strconv_itable = {}98sym_itable = {}99100101# Bundle some methods that are useful for writing tests.102class Ftuple(object):103def __init__(self, name, flag, invert):104self.name = name105self.flag = flag106self.invert = invert107108def __repr__(self):109return "Ftuple" + str((self.name, self.flag, self.invert))110111def flagname(self):112return _flagnames[self.flag]113114def setspec(self):115return ('-' if self.invert else '+') + self.name116117def clearspec(self):118return ('+' if self.invert else '-') + self.name119120def spec(self, doset):121return self.setspec() if doset else self.clearspec()122123124def _setup_tables():125# Filter globals for 'KRB5_KDB_' prefix to create lookup tables.126# Make the reasonable assumption that the Python runtime doesn't127# define any names with that prefix by default.128global _flagnames129for k, v in globals().items():130if k.startswith(_prefix):131_flagnames[v] = k[_prefixlen:]132133# Construct an input table based on kdb.h constant names by134# truncating the "KRB5_KDB_" prefix and downcasing.135sym_pflags = []136for v, k in sorted(_flagnames.items()):137sym_pflags.append((k.lower(), v, False))138139global kadmin_ftuples, strconv_ftuples, sym_ftuples, all_ftuples140for x in _kadmin_pflags:141kadmin_ftuples.append(Ftuple(*x))142for x in _strconv_pflags:143strconv_ftuples.append(Ftuple(*x))144for x in sym_pflags:145sym_ftuples.append(Ftuple(*x))146all_ftuples = kadmin_ftuples + strconv_ftuples + sym_ftuples147148# Populate combined input-to-flag lookup table. This will149# eliminate some duplicates.150global pflags151for x in all_ftuples:152name = x.name.translate(_squash)153pflags[name] = x154155global kadmin_itable, strconv_itable, sym_itable156for x in kadmin_ftuples:157kadmin_itable[x.flag] = x158for x in strconv_ftuples:159strconv_itable[x.flag] = x160for x in sym_ftuples:161sym_itable[x.flag] = x162163164# Convert the bit number of a flag to a string. Remove the165# 'KRB5_KDB_' prefix. Give an 8-digit hexadecimal number if the flag166# is unknown.167def flagnum2str(n):168s = _flagnames.get(1 << n)169if s is None:170return "0x%08x" % ((1 << n) & 0xffffffff)171return s172173174# Return a list of flag names from a flag word.175def flags2namelist(flags):176a = []177for n in range(32):178if flags & (1 << n):179a.append(flagnum2str(n))180return a181182183# Given a single specifier in the form {+|-}flagname, return a tuple184# of the form (flagstoset, flagstoclear).185def flagspec2mask(s):186req_neg = False187if s[0] == '-':188req_neg = True189s = s[1:]190elif s[0] == '+':191s = s[1:]192193s = s.lower().translate(_squash)194x = pflags.get(s)195if x is not None:196flag, invert = x.flag, x.invert197else:198# Maybe it's a hex number.199if not s.startswith('0x'):200raise ValueError201flag, invert = int(s, 16), False202203if req_neg:204invert = not invert205return (0, ~flag) if invert else (flag, ~0)206207208# Given a string containing a space/comma separated list of specifiers209# of the form {+|-}flagname, return a tuple of the form (flagstoset,210# flagstoclear). This shares the same limitation as211# kadm5int_acl_parse_restrictions() of losing the distinction between212# orderings when the same flag bit appears in both the positive and213# the negative sense.214def speclist2mask(s):215toset, toclear = (0, ~0)216for x in re.split('[\t, ]+', s):217fset, fclear = flagspec2mask(x)218toset |= fset219toclear &= fclear220221return toset, toclear222223224# Print C table of input flag specifiers for lib/kadm5/str_conv.c.225def _print_ftbl():226print('static const struct flag_table_row ftbl[] = {')227a = sorted(pflags.items(), key=lambda k, v: (v.flag, -v.invert, k))228for k, v in a:229s1 = ' {"%s",' % k230s2 = '%-31s KRB5_KDB_%s,' % (s1, v.flagname())231print('%-63s %d},' % (s2, 1 if v.invert else 0))232233print('};')234print('#define NFTBL (sizeof(ftbl) / sizeof(ftbl[0]))')235236237# Print C table of output flag names for lib/kadm5/str_conv.c.238def _print_outflags():239print('static const char *outflags[] = {')240for i in range(32):241flag = 1 << i242if flag > max(_flagnames.keys()):243break244try:245s = ' "%s",' % _flagnames[flag]246except KeyError:247s = ' NULL,'248print('%-32s/* 0x%08x */' % (s, flag))249250print('};')251print('#define NOUTFLAGS (sizeof(outflags) / sizeof(outflags[0]))')252253254# Print out C tables to insert into lib/kadm5/str_conv.c.255def _main():256_print_ftbl()257258_print_outflags()259260261_setup_tables()262263264if __name__ == '__main__':265_main()266267268