This file is indexed.

/usr/sbin/smbios-token-ctl is in smbios-utils 2.2.28-2.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
#! /usr/bin/python
# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:tw=0

  #############################################################################
  #
  # Copyright (c) 2005 Dell Computer Corporation
  # Dual Licenced under GNU GPL and OSL
  #
  #############################################################################
"""smbios-token-ctl"""

from __future__ import generators

# import arranged alphabetically
import csv
import gettext
import locale
import fnmatch
from optparse import OptionParser
import os
import StringIO
import string
import sys
import traceback

# the following vars are all substituted on install
# this bin isnt byte-compiled, so this is ok
__VERSION__="2.2.28"
pythondir="/usr/lib/python2.7/dist-packages"
clidir="/usr/share/smbios-utils"
# end vars

# import all local modules after this.
sys.path.insert(0,pythondir)
sys.path.insert(0,clidir)

import cli
from libsmbios_c import token, localedir, GETTEXT_PACKAGE, pkgdatadir
from libsmbios_c.trace_decorator import decorate, traceLog, getLog

locale.setlocale(locale.LC_ALL, '')
gettext.install(GETTEXT_PACKAGE, localedir, unicode=1)

moduleLog = getLog()
verboseLog = getLog(prefix="verbose.")

TOKENLIST_CSV=os.path.join(pkgdatadir, "token_list.csv")
TOKENBLACKLIST_CSV=os.path.join(pkgdatadir, "token_blacklist.csv")

class CmdlineError(Exception): pass
class BlacklistedToken(Exception): pass

def command_parse():
    parser = cli.OptionParser(usage=__doc__, version=__VERSION__)

    parser.add_option("-d", '--dump-tokens', action="store_const", dest="action",
                      help= _("Action: dump token table"), const="dump-tokens", default="dump-tokens")
    parser.add_option('--dump-tokens-csv', action="store_const", dest="action",
                      help= _("Action: dump token table in CSV format"), const="dump-tokens-csv")

    parser.add_option('--import-token-settings-csv', action="store_const", dest="action",
                      help= _("Action: Restore token settings from CSV table dump"), const="import-tokens-csv")

    parser.add_option('--is-string', action="store_const", dest="action",
                      help=_("Action: return true if specified token is a string."),
                      const="is-string")

    parser.add_option('--is-bool', action="store_const", dest="action",
                      help=_("Action: return true if specified token is a bool."),
                      const="is-bool")

    parser.add_option('--is-active', action="store_const", dest="action",
                      help=_("Action: return true if specified bool token is active."),
                      const="is-active")

    parser.add_option('--get-string', action="store_const", dest="action",
                      help=_("Action: get string token value."),
                      const="get-string")

    parser.add_option('--activate', action="store_const", dest="action",
                      help=_("Action: activate specified bool token."),
                      const="activate")

    parser.add_option('--set-string', action="store_const", dest="action",
                      help=_("Action: set string token value."),
                      const="set-string")

    parser.add_option("-i", '--token-id', "--token", action="store", dest="token_id",
                      help=_("Filter only token with ID."), default=None)
    parser.add_option("-n", '--token-name', action="store", dest="token_name",
                      help=_("Filter only token with name."), default=None)
    parser.add_option("-s", '--token-setting', action="store", dest="token_setting",
                      help=_("Filter only token with setting."), default=None)

    parser.add_option('--token-csv', action="append", type="string", dest="token_csv",
                      help=_("path to the token.csv file."), default=[TOKENLIST_CSV,])
    parser.add_option('--token-blacklist-csv', action="append", dest="token_blacklist_csv",
                      help=_("Path to token blacklist file."), default=[TOKENBLACKLIST_CSV])

    cli.addStdOptions(parser)
    return parser.parse_args()

class CommentedFile:
    def __init__(self, f, commentstring="#"):
        self.f = f
        self.commentstring = commentstring

    def next(self):
        line = self.f.next()
        while line[0] in self.commentstring:
            line = self.f.next()
        return line

    def __iter__(self):
        return self

class translatedToken(object):
    id = ""
    name = _("unknown")
    setting = _("unknown")
    description = _("unknown")
    spec = _("unknown")
    def __init__(self, tokenObj):
        self.id = tokenObj.getId()

class TokenTranslator(object):
    def __init__(self, *args, **kargs):
        self.tokens={}
        self.blacklist_tokens={}
        self.honorBlacklist=kargs.get('honorBlacklist',1)
        #print "add internal blacklist"
        self.addToList(csv.DictReader(CommentedFile(StringIO.StringIO(INTERNAL_BLACKLIST))), self.blacklist_tokens)

        #print "add file blacklist"
        for csvfile in kargs.get('csvblacklist',[]):
            try:
                csvdict = csv.DictReader(CommentedFile(open(csvfile, "rb")))
                self.addToList(csvdict, self.blacklist_tokens)
            except IOError, e:
                pass

    def __call__(self, tokenObj):
        retval = translatedToken(tokenObj)
        if self.tokens.get(retval.id) is not None:
            retval.name = self.tokens[retval.id]["Attribute Name"]
            retval.setting = self.tokens[retval.id]["Attribute Setting"]
            retval.description = self.tokens[retval.id]["Description"]
            retval.spec = self.tokens[retval.id]["Spec"]
        if self.blacklist_tokens.get(retval.id) and self.honorBlacklist:
            raise BlacklistedToken, self.blacklist_tokens[retval.id]['Reason']
        return retval

    def addToList(self, csvdict, whichlist):
        for line in csvdict:
            try:
                val = int(line["Token Value"],16)
                line["Token Value"] = "0x%04x" % val
                whichlist[val] = line
#                if whichlist == self.blacklist_tokens:
#                    print "add blacklist: (%s) = %s" % (val, line)
            except Exception, e:
                sys.stderr.write("="*79 + "\n")
                sys.stderr.write(_("Ignoring parsing error in CSV file:") )
                traceback.print_exc()
                sys.stderr.write("="*79 + "\n")

class TokenTranslatorCsv(TokenTranslator):
    def __init__(self, *args, **kargs):
        super(TokenTranslatorCsv,self).__init__(self, *args, **kargs)
        for csvfile in kargs.get('csvlist', []):
            try:
                csvdict = csv.DictReader(CommentedFile(open(csvfile, "rb")))
                self.addToList(csvdict, self.tokens)
            except IOError, e:
                sys.stderr.write(_("Skipping '%s' due to IOError.\n") % cvsfile)
                sys.stderr.write(_("The error message was: %s") % e)
                continue


def tokenInfo(tokenObj, action):
    exit_code=1

    type = _("<weird unknown type>")
    value = _("<unknown value>")
    if tokenObj.isBool():
        if action == "is-bool": exit_code = 0
        type="bool"
        value="false"
        if tokenObj.isActive():
            if action == "is-active": exit_code = 0
            value="true"

    elif tokenObj.isString():
        if action == "is-string": exit_code = 0
        type = "string"
        value = tokenObj.getString()

    return (exit_code, type, value)

def shouldSkipToken(token, options):
    skip = 0

    if options.token_id is not None:
        skip = 1
        if token.id == options.token_id:
            skip=0

    if options.token_name is not None:
        skip = 1
        if fnmatch.fnmatch(token.name.lower(), options.token_name.lower()):
            skip=0

    if options.token_setting is not None:
        skip = 1
        if token.setting == options.token_setting:
            skip=0

    return skip

def dumpTokens(tokenTable, tokenXlator, options):
     for token in tokenTable:
        try:
            translatedToken = tokenXlator(token)
        except BlacklistedToken, e:
            #sys.stdout.write( "="*80 + "\n" )
            #print "Not dumping blacklisted token 0x%04x. Reason: %s" % (token.getId(), str(e))
            continue

        if shouldSkipToken(translatedToken, options):
            continue

        sys.stdout.write( "="*80 + "\n" )
        print _("  Token: 0x%04x - %s (%s)") % (translatedToken.id, translatedToken.name, translatedToken.setting)

        try:
            (e, type, value) = tokenInfo(token, "dump-tokens")
            print _("  value: %s = %s") % (type, cli.makePrintable(value))
        except RuntimeError, e:
            pass

        desc = _("   Desc: ")
        sys.stdout.write(desc)
        cli.wrap(translatedToken.description, indent=len(desc), first_line_start=len(desc))
        print


def dumpTokensCsv(tokenTable, tokenXlator, options):
    # make sure not to localize the string below:
    sys.stdout.write("ID,Type,Value,Name,Setting\n")
    w = csv.writer( sys.stdout )
    for token in tokenTable:
        try:
            translatedToken = tokenXlator(token)
        except BlacklistedToken, e:
            #sys.stdout.write( "="*80 + "\n" )
            #print "Not dumping blacklisted token 0x%04x. Reason: %s" % (token.getId(), str(e))
            continue

        if shouldSkipToken(translatedToken, options):
            continue

        (e, type, value) = tokenInfo(token, "dump-tokens")
        w.writerow(("0x%04x" % translatedToken.id,type,cli.makePrintable(value),translatedToken.name, translatedToken.setting))
    sys.stdout.flush()

def importTokensCsv(tokenTable, tokenXlator, options, args):
    retval=True
    print _("Importing token values from '%s'") % args[0]
    csvdict = csv.DictReader(CommentedFile(open(args[0], "rb")))
    for line in csvdict:
        try:
            id = int(line["ID"], 0)
            type=line["Type"]
            value=line["Value"]
        except KeyError, e:
            print _("File format error. The first line should list the column names. Could not find the %s column") % str(e)
            print _("Cannot continue, exiting.")
            retval=False
            break

        try:
            token = tokenTable[id]
            translatedToken = tokenXlator(token)
            if shouldSkipToken(translatedToken, options):
                continue

            if translatedToken.name == _("unknown") or translatedToken.setting == _("unknown"):
                print _("Not importing token that is unknown: 0x%04x") % id
                retval=False
                continue

            if translatedToken.name != line["Name"]:
                print _("INFO: token 0x%04x settings file name does not match my DB. Applying setting anyways.") % id
                print _("\tsettings file: %s") % line["Name"]
                print _("\tDB name      : %s") % translatedToken.name

            if translatedToken.setting != line["Setting"]:
                print _("INFO: token 0x%04x settings file setting-name does not match my DB. Applying setting anyways.") % id
                print _("\tsettings file: %s") % line["Setting"]
                print _("\tDB name      : %s") % translatedToken.setting

            if type == "bool":
                if not token.isBool():
                    print _("SKIPPING: TYPE MISMATCH. Settings file says token 0x%04x should be bool, but it doesnt pass bool check.") % (id)
                    retval=False
                    continue
                elif value == "true":
                    if not token.isActive():
                        print _("Importing setting for token (active): 0x%04x") % id
                        token.activate()
                    else:
                        print _("Token already correct (bool, active): 0x%04x") % id
                elif value == "false":
                    if token.isActive():
                        print _("Info: Cannot de-activate tokens, can only activate the contrapositive. (0x%04x == false)") % id
                    else:
                        print _("Token already correct (bool, inactive): 0x%04x") % id
                else:
                    print _("UNEXPECTED VALUE: Bool token should only ever have values of 'true' or 'false', but token 0x%04x tries to set value '%s'") % (id, value)
                    continue

            elif type == "string":
                if not token.isString():
                    print _("SKIPPING: TYPE MISMATCH. Settings file says token 0x%04x should be string, but it doesnt pass string check.") % (id)
                    retval=False
                    continue
                if token.getString() != value:
                    print _("Importing setting for token (string): 0x%04x") % id
                    token.setString(value)
                else:
                    print _("Token already correct (string=='%s'): 0x%04x") % (value, id)

        except IndexError, e:
            print _("Not importing token which is inapplicable to this system: 0x%04x") % (id)
            retval=False
            continue

        except BlacklistedToken, e:
            print _("Not importing blacklisted token 0x%04x. Reason: %s") % (token.getId(), str(e))
            retval=False
            continue

        except Exception, e:
            sys.stderr.write("="*79 + "\n")
            sys.stderr.write(_("Ignoring parsing error in CSV file:") )
            traceback.print_exc()
            sys.stderr.write("="*79 + "\n")
            retval=False
            continue
    return retval

def getTokenObj(tokenTable, tokenXlator, options):
    # optimization
    if options.token_id:
        return tokenTable[options.token_id]

    if options.token_name is None or options.token_setting is None:
        raise CmdlineError, _("require token-id or token name/setting pair.")

    for token in tokenTable:
        try:
            translatedToken = tokenXlator(token)
            if shouldSkipToken(translatedToken, options):
                continue
            return token
        except BlacklistedToken, e:
            pass

    raise CmdlineError, _("token not found. Name(%s) Setting(%s).") % (
            options.token_name, options.token_setting)

def main():
    exit_code = 0
    (options, args) = command_parse()
    cli.setup_std_options(options)
    if options.token_id:
        options.token_id = int(options.token_id, 0)

    try:
        tokenXlator = TokenTranslatorCsv(csvlist=options.token_csv, csvblacklist=options.token_blacklist_csv)

        tokenTable = token.TokenTable()

        if options.action == "dump-tokens":
            dumpTokens(tokenTable, tokenXlator, options)
            return exit_code

        if options.action == "dump-tokens-csv":
            dumpTokensCsv(tokenTable, tokenXlator, options)
            return exit_code

        if options.action == "import-tokens-csv":
            exit_code = not importTokensCsv(tokenTable, tokenXlator, options, args)
            return exit_code

        tokenObj = getTokenObj(tokenTable, tokenXlator, options)
        tokenObj.tryPassword(options.password_ascii, options.password_scancode)

        if options.action in ("set-string", "activate"):
            (exit_code, type, value) = tokenInfo(tokenObj, options.action)
            print _("Original Value")
            print _("       token: 0x%04x") % tokenObj.getId()
            print _("        type: %s") % type
            print _("       value: %s") % cli.makePrintable(value)

        if options.action == "set-string":
            (exit_code, type, value) = tokenInfo(tokenObj, "dump-tokens")
            print _("Setting string value ...")
            tokenObj.setString(args[0])
            print _("New value")

        if options.action == "activate":
            (exit_code, type, value) = tokenInfo(tokenObj, "dump-tokens")
            print _("Activating token...")
            tokenObj.activate()
            print _("New value")

        if options.action in ("set-string", "activate", "is-bool", "is-string", "is-active", "get-string"):
            (exit_code, type, value) = tokenInfo(tokenObj, options.action)
            print _("        type: %s") % type
            print _("       value: %s") % cli.makePrintable(value)

    except (token.TokenTableParseError, ), e:
        exit_code=3
        moduleLog.info( _("ERROR: Could not parse system SMBIOS table.") )
        verboseLog.info( _("The smbios library returned this error:") )
        verboseLog.info( str(e) )
        moduleLog.info( cli.standardFailMessage )
    except (token.TokenManipulationFailure,), e:
        exit_code=4
        moduleLog.info( _("ERROR: Could not manipulate system token.") )
        verboseLog.info( _("The token library returned this error:") )
        verboseLog.info( str(e) )
        moduleLog.info( cli.standardFailMessage )

    return exit_code

INTERNAL_BLACKLIST = \
"""\
"Token Value","Reason"
# blacklist:
#   - raid shadow copy (0x00CD, 0x00CE, 0x00CF, 0x00D0)
0x00CD,"Manufacturing use."
0x00CE,"Manufacturing use."
0x00CF,"Manufacturing use."
0x00D0,"Manufacturing use."

#   - sata controller shadow copy ( 0x013a 0x013b 0x013c 0x013d 0x01FF)
0x013A,"Manufacturing use."
0x013B,"Manufacturing use."
0x013C,"Manufacturing use."
0x013D,"Manufacturing use."
0x01FF,"Manufacturing use."

#   - management driver  (0x0058, 0x0059)
0x0058,"Management driver use."
0x0059,"Management driver use."
0x8004,"dangerous - hard system power down."

#   - absolute security rom (0x0175, 0x0176)
0x0175,"dangerous - permanent write once"
0x0176,"dangerous - permanent write once"

#   - manufacturing mode (0x4026, 0x4027)
0x4026,"Manufacturing mode."
0x4027,"Manufacturing mode."

#   - cmos location for post (0x9000, 0x9001)
0x9000,"Manufacturing use."
0x9001,"Manufacturing use."

#   - TPM os enable/disable (0xa0002, 0xa003)
0xa002,"Manufacturing use."
0xa003,"Manufacturing use."
"""

if __name__ == "__main__":
    sys.exit( main() )