Home | History | Annotate | Line # | Download | only in lib
      1      1.1  christos /*
      2      1.1  christos  * The Initial Developer of the Original Code is International
      3      1.1  christos  * Business Machines Corporation. Portions created by IBM
      4      1.1  christos  * Corporation are Copyright (C) 2005 International Business
      5      1.1  christos  * Machines Corporation. All Rights Reserved.
      6      1.1  christos  *
      7      1.1  christos  * This program is free software; you can redistribute it and/or modify
      8      1.1  christos  * it under the terms of the Common Public License as published by
      9      1.1  christos  * IBM Corporation; either version 1 of the License, or (at your option)
     10      1.1  christos  * any later version.
     11      1.1  christos  *
     12      1.1  christos  * This program is distributed in the hope that it will be useful,
     13      1.1  christos  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos  * Common Public License for more details.
     16      1.1  christos  *
     17      1.1  christos  * You should have received a copy of the Common Public License
     18      1.1  christos  * along with this program; if not, a copy can be viewed at
     19      1.1  christos  * http://www.opensource.org/licenses/cpl1.0.php.
     20      1.1  christos  */
     21      1.1  christos 
     22      1.1  christos #include "config.h"
     23      1.1  christos #include <unistd.h>
     24      1.1  christos #include <stdlib.h>
     25      1.1  christos #include <trousers/tss.h>
     26      1.1  christos #include <trousers/trousers.h>
     27      1.1  christos 
     28      1.1  christos #include "tpm_tspi.h"
     29      1.1  christos #include "tpm_utils.h"
     30      1.1  christos 
     31      1.1  christos BOOL useUnicode = FALSE;
     32      1.1  christos 
     33      1.1  christos static const struct option sGenLongOpts[] = {
     34      1.1  christos 	{ "help", no_argument, NULL, 'h' },
     35      1.1  christos 	{ "version", no_argument, NULL, 'v' },
     36      1.1  christos 	{ "log", required_argument, NULL, 'l' },
     37      1.1  christos 	{ "unicode", no_argument, NULL, 'u' },
     38      1.1  christos };
     39      1.1  christos 
     40      1.1  christos static const char *pszGenShortOpts = "hvl:u";
     41      1.1  christos 
     42      1.1  christos void initIntlSys( ) {
     43      1.1  christos 
     44      1.1  christos 	setlocale( LC_ALL, "" );
     45      1.1  christos 	bindtextdomain( PACKAGE, LOCALEDIR );
     46      1.1  christos 	textdomain( PACKAGE );
     47      1.1  christos }
     48      1.1  christos 
     49      1.1  christos int
     50      1.1  christos genericOptHandler( int a_iNumArgs, char **a_pszArgs,
     51      1.1  christos 		   const char *a_pszShortOpts,
     52      1.1  christos 		   struct option *a_sLongOpts, int a_iNumOpts,
     53      1.1  christos 		   CmdOptParser a_tCmdOptParser, CmdHelpFunction a_tCmdHelpFunction ) {
     54      1.1  christos 
     55      1.1  christos 	CmdHelpFunction  tCmdHelp = ( a_tCmdHelpFunction ) ? a_tCmdHelpFunction
     56      1.1  christos 							   : logCmdHelp;
     57      1.1  christos 
     58      1.1  christos 	char  szShortOpts[strlen( pszGenShortOpts )
     59      1.1  christos 			  + ( ( a_pszShortOpts == NULL ) ? 0 : strlen( a_pszShortOpts ) )
     60      1.1  christos 			  + 1];
     61      1.1  christos 
     62      1.1  christos 	int            iNumGenLongOpts = sizeof( sGenLongOpts ) / sizeof( struct option );
     63      1.1  christos 	struct option  sLongOpts[iNumGenLongOpts + a_iNumOpts + 1];
     64      1.1  christos 
     65      1.1  christos 	int  iOpt;
     66      1.1  christos 	int  rc;
     67      1.1  christos 
     68      1.1  christos 	strcpy( szShortOpts, pszGenShortOpts);
     69      1.1  christos 	if ( a_pszShortOpts )
     70      1.1  christos 		strcat( szShortOpts, a_pszShortOpts );
     71      1.1  christos 
     72  1.1.1.2  christos 	__memset( sLongOpts, 0, sizeof( sLongOpts ) );
     73      1.1  christos 	memcpy( sLongOpts, sGenLongOpts, sizeof( sGenLongOpts ) );
     74      1.1  christos 	if ( a_sLongOpts ) {
     75      1.1  christos 		memcpy( sLongOpts + iNumGenLongOpts,
     76      1.1  christos 			a_sLongOpts,
     77      1.1  christos 			a_iNumOpts * sizeof( struct option ) );
     78      1.1  christos 	}
     79      1.1  christos 
     80      1.1  christos 	while ( ( iOpt = getopt_long( a_iNumArgs, a_pszArgs,
     81      1.1  christos 					szShortOpts, sLongOpts, NULL ) ) != -1 ) {
     82      1.1  christos 
     83      1.1  christos 		switch ( iOpt ) {
     84      1.1  christos 			case 'h':
     85      1.1  christos 				tCmdHelp( a_pszArgs[0] );
     86      1.1  christos 				return -1;
     87      1.1  christos 
     88      1.1  christos 			case 'v':
     89      1.1  christos 				logMsg( _("%s version: %s\n"), a_pszArgs[0], CMD_VERSION );
     90      1.1  christos 				return -1;
     91      1.1  christos 
     92      1.1  christos 			case 'l':
     93      1.1  christos 				if ( !optarg ) {
     94      1.1  christos 					tCmdHelp( a_pszArgs[0] );
     95      1.1  christos 					return -1;
     96      1.1  christos 				}
     97      1.1  christos 
     98      1.1  christos 				if ( strcmp( optarg, LOG_NONE ) == 0 )
     99      1.1  christos 					iLogLevel = LOG_LEVEL_NONE;
    100      1.1  christos 				else if ( strcmp( optarg, LOG_ERROR ) == 0 )
    101      1.1  christos 					iLogLevel = LOG_LEVEL_ERROR;
    102      1.1  christos 				else if ( strcmp( optarg, LOG_INFO ) == 0 )
    103      1.1  christos 					iLogLevel = LOG_LEVEL_INFO;
    104      1.1  christos 				else if ( strcmp( optarg, LOG_DEBUG ) == 0 )
    105      1.1  christos 					iLogLevel = LOG_LEVEL_DEBUG;
    106      1.1  christos 				else {
    107      1.1  christos 					logMsg( _("Valid log levels are: %s, %s, %s, %s\n"),
    108      1.1  christos 						LOG_NONE,
    109      1.1  christos 						LOG_ERROR,
    110      1.1  christos 						LOG_INFO,
    111      1.1  christos 						LOG_DEBUG );
    112      1.1  christos 					tCmdHelp( a_pszArgs[0] );
    113      1.1  christos 					return -1;
    114      1.1  christos 				}
    115      1.1  christos 				break;
    116      1.1  christos 			case 'u':
    117      1.1  christos 				useUnicode = TRUE;
    118      1.1  christos 				break;
    119      1.1  christos 			case '?':
    120      1.1  christos 				tCmdHelp( a_pszArgs[0] );
    121      1.1  christos 				return -1;
    122      1.1  christos 
    123      1.1  christos 			default:
    124      1.1  christos 				if ( !a_tCmdOptParser )
    125      1.1  christos 					return -1;
    126      1.1  christos 
    127      1.1  christos 				rc = a_tCmdOptParser( iOpt, optarg );
    128      1.1  christos 				if ( rc != 0 )
    129      1.1  christos 					return rc;
    130      1.1  christos 				break;
    131      1.1  christos 		}
    132      1.1  christos 	}
    133      1.1  christos 
    134      1.1  christos 	return 0;
    135      1.1  christos }
    136      1.1  christos 
    137  1.1.1.2  christos void * __no_optimize
    138  1.1.1.2  christos __memset(void *s, int c, size_t n)
    139  1.1.1.2  christos {
    140  1.1.1.2  christos 	return memset(s, c, n);
    141  1.1.1.2  christos }
    142  1.1.1.2  christos 
    143      1.1  christos /*
    144      1.1  christos  * This function should be called when you are done with a password
    145      1.1  christos  * the above getPasswd function to properly clean up.
    146      1.1  christos  */
    147      1.1  christos void shredPasswd( char *a_pszPasswd ) {
    148      1.1  christos 
    149      1.1  christos 	if ( a_pszPasswd ) {
    150  1.1.1.2  christos 		__memset( a_pszPasswd, 0, strlen( a_pszPasswd ) );
    151      1.1  christos 		free( a_pszPasswd );
    152      1.1  christos 	}
    153      1.1  christos }
    154      1.1  christos 
    155      1.1  christos /*
    156      1.1  christos  * You must free the memory passed back to you when you are finished.
    157      1.1  christos  * Loop will always terminate by the second pass.
    158      1.1  christos  * Safest use of getpass is to zero the memory as soon as possible.
    159      1.1  christos  */
    160      1.1  christos char *getPlainPasswd(const char *a_pszPrompt, BOOL a_bConfirm) {
    161      1.1  christos 	int len;
    162      1.1  christos 	return _getPasswd(a_pszPrompt, &len, a_bConfirm, FALSE);
    163      1.1  christos }
    164      1.1  christos 
    165      1.1  christos #ifndef TSS_LIB_IS_12
    166      1.1  christos char *getPasswd(const char *a_pszPrompt, int* a_iLen,
    167      1.1  christos 		BOOL a_bConfirm) {
    168      1.1  christos 	return _getPasswd( a_pszPrompt, a_iLen, a_bConfirm, useUnicode);
    169      1.1  christos }
    170      1.1  christos #endif
    171      1.1  christos char *_getPasswd(const char *a_pszPrompt, int* a_iLen,
    172      1.1  christos 		BOOL a_bConfirm, BOOL a_bUseUnicode) {
    173      1.1  christos 
    174      1.1  christos 	char *pszPrompt = (char *)a_pszPrompt;
    175      1.1  christos 	char *pszPasswd = NULL;
    176      1.1  christos 	char *pszRetPasswd = NULL;
    177      1.1  christos 
    178      1.1  christos 	do {
    179      1.1  christos 		// Get password value from user - this is a static buffer
    180      1.1  christos 		// and should never be freed
    181      1.1  christos 		pszPasswd = getpass( pszPrompt );
    182      1.1  christos 		if (!pszPasswd && pszRetPasswd) {
    183      1.1  christos 			shredPasswd( pszRetPasswd );
    184      1.1  christos 			return NULL;
    185      1.1  christos 		}
    186      1.1  christos 
    187      1.1  christos 		// If this is confirmation pass check for match
    188      1.1  christos 		if ( pszRetPasswd ) {
    189      1.1  christos 			// Matched work complete
    190      1.1  christos 			if ( strcmp( pszPasswd, pszRetPasswd ) == 0)
    191      1.1  christos 				goto out;
    192      1.1  christos 
    193      1.1  christos 			// No match clean-up
    194      1.1  christos 			logMsg( _("Passwords didn't match\n") );
    195      1.1  christos 
    196      1.1  christos 			// pszPasswd will be cleaned up at out label
    197      1.1  christos 			shredPasswd( pszRetPasswd );
    198      1.1  christos 			pszRetPasswd = NULL;
    199      1.1  christos 			goto out;
    200      1.1  christos 		}
    201      1.1  christos 
    202      1.1  christos 		// Save this passwd for next pass and/or return val
    203      1.1  christos 		pszRetPasswd = strdup( pszPasswd );
    204      1.1  christos 		if ( !pszRetPasswd )
    205      1.1  christos 			goto out;
    206      1.1  christos 
    207      1.1  christos 		pszPrompt = _("Confirm password: ");
    208      1.1  christos 	} while (a_bConfirm);
    209      1.1  christos 
    210      1.1  christos out:
    211      1.1  christos 	if (pszRetPasswd) {
    212      1.1  christos 		*a_iLen = strlen(pszRetPasswd);
    213      1.1  christos 
    214      1.1  christos 		if (a_bUseUnicode) {
    215      1.1  christos 			shredPasswd(pszRetPasswd);
    216      1.1  christos 			pszRetPasswd = (char *)Trspi_Native_To_UNICODE((BYTE *)pszPasswd, (unsigned int *)a_iLen);
    217      1.1  christos 		}
    218      1.1  christos 	}
    219      1.1  christos 
    220      1.1  christos 	// pszPasswd is a static buffer, just clear it
    221      1.1  christos 	if ( pszPasswd )
    222  1.1.1.2  christos 		__memset( pszPasswd, 0, strlen( pszPasswd ) );
    223      1.1  christos 
    224      1.1  christos 	return pszRetPasswd;
    225      1.1  christos }
    226      1.1  christos 
    227      1.1  christos /*
    228      1.1  christos  * You must free the memory passed back to you when you are finished.
    229      1.1  christos  */
    230      1.1  christos char *getReply( const char *a_pszPrompt, int a_iMaxLen ) {
    231      1.1  christos 
    232      1.1  christos 	char *pszReply  = NULL;
    233      1.1  christos 	int   iReplyLen = a_iMaxLen + 2; // Room for newline and trailing zero
    234      1.1  christos 
    235      1.1  christos 	if ( iReplyLen <= 0 )
    236      1.1  christos 		goto out;
    237      1.1  christos 
    238      1.1  christos 	pszReply = (char *)calloc( iReplyLen, 1 );
    239      1.1  christos 	if ( !pszReply )
    240      1.1  christos 		goto out;
    241      1.1  christos 
    242      1.1  christos 	logMsg( "%s", a_pszPrompt );
    243      1.1  christos 	pszReply = fgets( pszReply, iReplyLen, stdin );
    244      1.1  christos 	if ( !pszReply )
    245      1.1  christos 		goto out;
    246      1.1  christos 
    247      1.1  christos 	// Be certain that a complete line was read
    248      1.1  christos 	if ( ( pszReply[ a_iMaxLen ] != '\n' ) && ( pszReply[ a_iMaxLen ] != '\0' ) ) {
    249      1.1  christos 		free( pszReply );
    250      1.1  christos 		pszReply = NULL;
    251      1.1  christos 		goto out;
    252      1.1  christos 	}
    253      1.1  christos 
    254      1.1  christos 	for ( iReplyLen -= 1; iReplyLen >= 0; iReplyLen-- ) {
    255      1.1  christos 		if ( pszReply[ iReplyLen ] == '\0' )
    256      1.1  christos 			continue;
    257      1.1  christos 
    258      1.1  christos 		if ( pszReply[ iReplyLen ] == '\n' )
    259      1.1  christos 			pszReply[ iReplyLen ] = '\0';
    260      1.1  christos 		break;
    261      1.1  christos 	}
    262      1.1  christos 
    263      1.1  christos out:
    264      1.1  christos 	return pszReply;
    265      1.1  christos }
    266