1/* misc.c 2 * Copyright (C) 1999, 2001, 2002, 2003, 2007, 3 * 2008 Free Software Foundation, Inc. 4 * 5 * This file is part of Libgcrypt. 6 * 7 * Libgcrypt is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public License as 9 * published by the Free Software Foundation; either version 2.1 of 10 * the License, or (at your option) any later version. 11 * 12 * Libgcrypt is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this program; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include <config.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25#include <stdarg.h> 26#include <unistd.h> 27 28#include "g10lib.h" 29#include "secmem.h" 30 31static int verbosity_level = 0; 32 33static void (*fatal_error_handler)(void*,int, const char*) = NULL; 34static void *fatal_error_handler_value = 0; 35static void (*log_handler)(void*,int, const char*, va_list) = NULL; 36static void *log_handler_value = 0; 37 38static const char *(*user_gettext_handler)( const char * ) = NULL; 39 40void 41gcry_set_gettext_handler( const char *(*f)(const char*) ) 42{ 43 user_gettext_handler = f; 44} 45 46 47const char * 48_gcry_gettext( const char *key ) 49{ 50 if( user_gettext_handler ) 51 return user_gettext_handler( key ); 52 /* FIXME: switch the domain to gnupg and restore later */ 53 return key; 54} 55 56void 57gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value) 58{ 59 fatal_error_handler_value = value; 60 fatal_error_handler = fnc; 61} 62 63static void 64write2stderr( const char *s ) 65{ 66 /* Dummy variable to silence gcc warning. */ 67 int res = write( 2, s, strlen(s) ); 68 (void) res; 69} 70 71/* 72 * This function is called for fatal errors. A caller might want to 73 * set his own handler because this function simply calls abort(). 74 */ 75void 76_gcry_fatal_error (int rc, const char *text) 77{ 78 if ( !text ) /* get a default text */ 79 text = gpg_strerror (rc); 80 81 if (fatal_error_handler && !fips_mode () ) 82 fatal_error_handler (fatal_error_handler_value, rc, text); 83 84 fips_signal_fatal_error (text); 85 write2stderr("\nFatal error: "); 86 write2stderr(text); 87 write2stderr("\n"); 88 _gcry_secmem_term (); 89 abort (); 90} 91 92void 93gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ), 94 void *opaque ) 95{ 96 log_handler = f; 97 log_handler_value = opaque; 98} 99 100void 101_gcry_set_log_verbosity( int level ) 102{ 103 verbosity_level = level; 104} 105 106int 107_gcry_log_verbosity( int level ) 108{ 109 return verbosity_level >= level; 110} 111 112/**************** 113 * This is our log function which prints all log messages to stderr or 114 * using the function defined with gcry_set_log_handler(). 115 */ 116static void 117_gcry_logv( int level, const char *fmt, va_list arg_ptr ) 118{ 119 if (log_handler) 120 log_handler (log_handler_value, level, fmt, arg_ptr); 121 else 122 { 123 switch (level) 124 { 125 case GCRY_LOG_CONT: break; 126 case GCRY_LOG_INFO: break; 127 case GCRY_LOG_WARN: break; 128 case GCRY_LOG_ERROR: break; 129 case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break; 130 case GCRY_LOG_BUG: fputs("Ohhhh jeeee: ", stderr); break; 131 case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break; 132 default: fprintf(stderr,"[Unknown log level %d]: ", level ); break; 133 } 134 vfprintf(stderr,fmt,arg_ptr) ; 135 } 136 137 if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG ) 138 { 139 fips_signal_fatal_error ("internal error (fatal or bug)"); 140 _gcry_secmem_term (); 141 abort (); 142 } 143} 144 145 146void 147_gcry_log( int level, const char *fmt, ... ) 148{ 149 va_list arg_ptr ; 150 151 va_start( arg_ptr, fmt ) ; 152 _gcry_logv( level, fmt, arg_ptr ); 153 va_end(arg_ptr); 154} 155 156 157#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L 158void 159_gcry_bug( const char *file, int line, const char *func ) 160{ 161 _gcry_log( GCRY_LOG_BUG, 162 ("... this is a bug (%s:%d:%s)\n"), file, line, func ); 163 abort(); /* never called, but it makes the compiler happy */ 164} 165void 166_gcry_assert_failed (const char *expr, const char *file, int line, 167 const char *func) 168{ 169 _gcry_log (GCRY_LOG_BUG, 170 ("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func ); 171 abort(); /* Never called, but it makes the compiler happy. */ 172} 173#else 174void 175_gcry_bug( const char *file, int line ) 176{ 177 _gcry_log( GCRY_LOG_BUG, 178 _("you found a bug ... (%s:%d)\n"), file, line); 179 abort(); /* never called, but it makes the compiler happy */ 180} 181void 182_gcry_assert_failed (const char *expr, const char *file, int line) 183{ 184 _gcry_log (GCRY_LOG_BUG, 185 ("Assertion `%s' failed (%s:%d)\n"), expr, file, line); 186 abort(); /* Never called, but it makes the compiler happy. */ 187} 188#endif 189 190void 191_gcry_log_info( const char *fmt, ... ) 192{ 193 va_list arg_ptr ; 194 195 va_start( arg_ptr, fmt ) ; 196 _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr ); 197 va_end(arg_ptr); 198} 199 200int 201_gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... ) 202{ 203 va_list arg_ptr; 204 205 (void)fp; 206 va_start( arg_ptr, fmt ) ; 207 _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr ); 208 va_end(arg_ptr); 209 return 0; 210} 211 212void 213_gcry_log_error( const char *fmt, ... ) 214{ 215 va_list arg_ptr ; 216 217 va_start( arg_ptr, fmt ) ; 218 _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr ); 219 va_end(arg_ptr); 220} 221 222 223void 224_gcry_log_fatal( const char *fmt, ... ) 225{ 226 va_list arg_ptr ; 227 228 va_start( arg_ptr, fmt ) ; 229 _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr ); 230 va_end(arg_ptr); 231 abort(); /* never called, but it makes the compiler happy */ 232} 233 234void 235_gcry_log_bug( const char *fmt, ... ) 236{ 237 va_list arg_ptr ; 238 239 va_start( arg_ptr, fmt ) ; 240 _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr ); 241 va_end(arg_ptr); 242 abort(); /* never called, but it makes the compiler happy */ 243} 244 245void 246_gcry_log_debug( const char *fmt, ... ) 247{ 248 va_list arg_ptr ; 249 250 va_start( arg_ptr, fmt ) ; 251 _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr ); 252 va_end(arg_ptr); 253} 254 255 256void 257_gcry_log_printf (const char *fmt, ...) 258{ 259 va_list arg_ptr; 260 261 if (fmt) 262 { 263 va_start( arg_ptr, fmt ) ; 264 _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr); 265 va_end(arg_ptr); 266 } 267} 268 269/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw 270 dump, with TEXT an empty string, print a trailing linefeed, 271 otherwise print an entire debug line. */ 272void 273_gcry_log_printhex (const char *text, const void *buffer, size_t length) 274{ 275 if (text && *text) 276 log_debug ("%s ", text); 277 if (length) 278 { 279 const unsigned char *p = buffer; 280 log_printf ("%02X", *p); 281 for (length--, p++; length--; p++) 282 log_printf (" %02X", *p); 283 } 284 if (text) 285 log_printf ("\n"); 286} 287 288 289void 290_gcry_burn_stack (int bytes) 291{ 292 char buf[64]; 293 294 wipememory (buf, sizeof buf); 295 bytes -= sizeof buf; 296 if (bytes > 0) 297 _gcry_burn_stack (bytes); 298} 299