155714Skris/*
255714Skris * The Initial Developer of the Original Code is International
355714Skris * Business Machines Corporation. Portions created by IBM
455714Skris * Corporation are Copyright (C) 2005 International Business
555714Skris * Machines Corporation. All Rights Reserved.
655714Skris *
755714Skris * This program is free software; you can redistribute it and/or modify
855714Skris * it under the terms of the Common Public License as published by
955714Skris * IBM Corporation; either version 1 of the License, or (at your option)
1055714Skris * any later version.
1155714Skris *
1255714Skris * This program is distributed in the hope that it will be useful,
1355714Skris * but WITHOUT ANY WARRANTY; without even the implied warranty of
1455714Skris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1555714Skris * Common Public License for more details.
1655714Skris *
1755714Skris * You should have received a copy of the Common Public License
1855714Skris * along with this program; if not, a copy can be viewed at
1955714Skris * http://www.opensource.org/licenses/cpl1.0.php.
2055714Skris */
2155714Skris
2255714Skris#include "tpm_tspi.h"
2355714Skris#include "tpm_utils.h"
2455714Skris
2555714Skris/*
2655714Skris * Affect: Change the TPM state regarding if take_ownership can be performed.
2755714Skris * Default: Set state to ownable
2855714Skris * Requires: Physical presence
2955714Skris */
3055714Skris
3155714Skris//Controlled by option inputs
3255714Skrisstatic TSS_BOOL bValue = TRUE;
3355714Skrisstatic BOOL bCheck = FALSE;
3455714Skrisstatic BOOL changeRequested = FALSE;
3555714Skrisstatic BOOL isWellKnown = FALSE;
3655714SkrisTSS_HCONTEXT hContext = 0;
3755714Skris
3855714Skrisstatic int parse(const int aOpt, const char *aArg)
3955714Skris{
4055714Skris
4155714Skris	switch (aOpt) {
4255714Skris	case 's':
4355714Skris		logDebug(_("Changing mode to check status.\n"));
4455714Skris		bCheck = TRUE;
4555714Skris		break;
4655714Skris	case 'p':
4755714Skris		logDebug(_("Changing to prevent ownership mode\n"));
4855714Skris		bValue = FALSE;
4955714Skris		changeRequested = TRUE;
5055714Skris		break;
5155714Skris	case 'a':
5255714Skris		logDebug(_("Changing to allow ownership mode\n"));
5355714Skris		bValue = TRUE;
5455714Skris		changeRequested = TRUE;
5555714Skris		break;
5655714Skris	case 'z':
5755714Skris		logDebug(_("Using TSS_WELL_KNOWN_SECRET to authorize the TPM command\n"));
5889840Skris		isWellKnown = TRUE;
5989840Skris		break;
6089840Skris	default:
6189840Skris		return -1;
6289840Skris	}
6389840Skris	return 0;
6489840Skris}
6589840Skris
6689840Skrisstatic void help(const char *aCmd)
6789840Skris{
6889840Skris
6989840Skris	logCmdHelp(aCmd);
7089840Skris	logUnicodeCmdOption();
7189840Skris	logCmdOption("-s, --status", _("Display current status"));
7289840Skris	logCmdOption("-a, --allow", _("Allow TPM takeownership command"));
7389840Skris	logCmdOption("-p, --prevent", _("Prevent TPM takeownership command"));
7489840Skris	logCmdOption("-z, --well-known",
7589840Skris		     _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the TPM secret authorization data"));
7689840Skris}
7789840Skris
7889840Skrisint main(int argc, char **argv)
7989840Skris{
8089840Skris
8189840Skris	char *szTpmPasswd = NULL;
8289840Skris	int pswd_len;
8389840Skris	TSS_HPOLICY hTpmPolicy;
8489840Skris	TSS_HTPM hTpm;
8589840Skris	int iRc = -1;
8689840Skris	struct option opts[] = { {"allow", no_argument, NULL, 'a'},
8789840Skris	{"prevent", no_argument, NULL, 'p'},
8889840Skris	{"status", no_argument, NULL, 's'},
8989840Skris	{"well-known", no_argument, NULL, 'z'},
9089840Skris	};
9189840Skris	BYTE well_known[] = TSS_WELL_KNOWN_SECRET;
9289840Skris
9389840Skris        initIntlSys();
9489840Skris
9589840Skris	if (genericOptHandler
9689840Skris	    (argc, argv, "apsz", opts, sizeof(opts) / sizeof(struct option),
9789840Skris	     parse, help) != 0)
9889840Skris		goto out;
9989840Skris
10089840Skris	if (contextCreate(&hContext) != TSS_SUCCESS)
10189840Skris		goto out;
10289840Skris
10389840Skris	if (contextConnect(hContext) != TSS_SUCCESS)
10489840Skris		goto out_close;
10589840Skris
10689840Skris	if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS)
10789840Skris		goto out_close;
10889840Skris
10989840Skris	if (bCheck || !changeRequested) {
11089840Skris		if (isWellKnown) {
11155714Skris			szTpmPasswd = (char *)well_known;
11255714Skris			pswd_len = sizeof(well_known);
113110007Smarkm		} else {
11455714Skris			// Prompt for owner password
11555714Skris			szTpmPasswd = GETPASSWD(_("Enter owner password: "), &pswd_len, FALSE);
11655714Skris			if (!szTpmPasswd) {
11755714Skris				logMsg(_("Failed to get password\n"));
11855714Skris				goto out_close;
11955714Skris			}
12055714Skris		}
12155714Skris		if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS)
12255714Skris			goto out_close;
123110007Smarkm
12455714Skris		if (policySetSecret
12555714Skris		    (hTpmPolicy, pswd_len,
12655949Skris		     (BYTE *)szTpmPasswd) != TSS_SUCCESS)
12755714Skris			goto out_close;
12855714Skris		if (tpmGetStatus
12955714Skris		    (hTpm, TSS_TPMSTATUS_SETOWNERINSTALL,
13055714Skris		     &bValue) != TSS_SUCCESS)
13155714Skris			goto out_close;
13255714Skris
13355714Skris		logMsg(_("Ownable status: %s\n"), logBool(mapTssBool(bValue)));
13455714Skris		goto out_success;
13555714Skris	}
13655714Skris
13755714Skris	if (tpmSetStatus(hTpm, TSS_TPMSTATUS_SETOWNERINSTALL, bValue) !=
13855714Skris	    TSS_SUCCESS)
13955714Skris		goto out_close;
14055714Skris
14155714Skris      out_success:
142110007Smarkm	iRc = 0;
143110007Smarkm	logSuccess(argv[0]);
144110007Smarkm
145110007Smarkm      out_close:
146110007Smarkm	contextClose(hContext);
147110007Smarkm
148110007Smarkm      out:
149110007Smarkm	if (szTpmPasswd && !isWellKnown)
150110007Smarkm		shredPasswd(szTpmPasswd);
151110007Smarkm	return iRc;
152110007Smarkm}
153110007Smarkm