00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00017 #include "config.h"
00018 #ifdef HAVE_SYSLOG_H
00019 #include <syslog.h>
00020 #endif
00021 #include <unistd.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <stdarg.h>
00026 #include <assert.h>
00027 #include <sys/types.h>
00028
00029 #include "pcsclite.h"
00030 #include "misc.h"
00031 #include "debuglog.h"
00032 #include "sys_generic.h"
00033 #include "strlcpycat.h"
00034
00039 #define DEBUG_BUF_SIZE 2048
00040
00041 static char LogSuppress = DEBUGLOG_LOG_ENTRIES;
00042 static char LogMsgType = DEBUGLOG_NO_DEBUG;
00043 static char LogCategory = DEBUG_CATEGORY_NOTHING;
00044
00045
00046 static char LogLevel = PCSC_LOG_INFO;
00047
00048 static signed char LogDoColor = 0;
00049
00050 void log_msg(const int priority, const char *fmt, ...)
00051 {
00052 char DebugBuffer[DEBUG_BUF_SIZE];
00053 va_list argptr;
00054
00055 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00056 || (priority < LogLevel)
00057 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00058 return;
00059
00060 va_start(argptr, fmt);
00061 #ifndef WIN32
00062 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00063 #else
00064 #if HAVE_VSNPRINTF
00065 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00066 #else
00067 vsprintf(DebugBuffer, fmt, argptr);
00068 #endif
00069 #endif
00070 va_end(argptr);
00071
00072 #ifndef WIN32
00073 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00074 syslog(LOG_INFO, "%s", DebugBuffer);
00075 else
00076 {
00077 if (LogDoColor)
00078 {
00079 const char *color_pfx = "", *color_sfx = "\33[0m";
00080
00081 switch (priority)
00082 {
00083 case PCSC_LOG_CRITICAL:
00084 color_pfx = "\33[01;31m";
00085 break;
00086
00087 case PCSC_LOG_ERROR:
00088 color_pfx = "\33[35m";
00089 break;
00090
00091 case PCSC_LOG_INFO:
00092 color_pfx = "\33[34m";
00093 break;
00094
00095 case PCSC_LOG_DEBUG:
00096 color_pfx = "";
00097 color_sfx = "";
00098 break;
00099 }
00100 fprintf(stderr, "%s%s%s\n", color_pfx, DebugBuffer, color_sfx);
00101 }
00102 else
00103 fprintf(stderr, "%s\n", DebugBuffer);
00104 }
00105 #else
00106 fprintf(stderr, "%s\n", DebugBuffer);
00107 #endif
00108 }
00109
00110 void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
00111 const int len)
00112 {
00113 char DebugBuffer[DEBUG_BUF_SIZE];
00114 int i;
00115 char *c;
00116 char *debug_buf_end;
00117
00118 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00119 || (priority < LogLevel)
00120 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00121 return;
00122
00123 debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5;
00124
00125 strlcpy(DebugBuffer, msg, sizeof(DebugBuffer));
00126 c = DebugBuffer + strlen(DebugBuffer);
00127
00128 for (i = 0; (i < len) && (c < debug_buf_end); ++i)
00129 {
00130 sprintf(c, "%02X ", buffer[i]);
00131 c += strlen(c);
00132 }
00133
00134 #ifndef WIN32
00135 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00136 syslog(LOG_INFO, "%s", DebugBuffer);
00137 else
00138 #endif
00139 fprintf(stderr, "%s\n", DebugBuffer);
00140 }
00141
00142 #ifdef PCSCD
00143 void DebugLogSuppress(const int lSType)
00144 {
00145 LogSuppress = lSType;
00146 }
00147 #endif
00148
00149 void DebugLogSetLogType(const int dbgtype)
00150 {
00151 switch (dbgtype)
00152 {
00153 case DEBUGLOG_NO_DEBUG:
00154 case DEBUGLOG_SYSLOG_DEBUG:
00155 case DEBUGLOG_STDERR_DEBUG:
00156 LogMsgType = dbgtype;
00157 break;
00158 default:
00159 Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
00160 dbgtype);
00161 LogMsgType = DEBUGLOG_STDERR_DEBUG;
00162 }
00163
00164
00165 #ifndef WIN32
00166
00167 if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
00168 {
00169 const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
00170 char *term;
00171
00172 term = getenv("TERM");
00173 if (term)
00174 {
00175 int i;
00176
00177
00178 for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
00179 {
00180
00181 if (0 == strcmp(terms[i], term))
00182 {
00183 LogDoColor = 1;
00184 break;
00185 }
00186 }
00187 }
00188 }
00189 #endif
00190 }
00191
00192 void DebugLogSetLevel(const int level)
00193 {
00194 LogLevel = level;
00195 switch (level)
00196 {
00197 case PCSC_LOG_CRITICAL:
00198 case PCSC_LOG_ERROR:
00199
00200 break;
00201
00202 case PCSC_LOG_INFO:
00203 Log1(PCSC_LOG_INFO, "debug level=notice");
00204 break;
00205
00206 case PCSC_LOG_DEBUG:
00207 Log1(PCSC_LOG_DEBUG, "debug level=debug");
00208 break;
00209
00210 default:
00211 LogLevel = PCSC_LOG_INFO;
00212 Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
00213 level);
00214 }
00215 }
00216
00217 INTERNAL int DebugLogSetCategory(const int dbginfo)
00218 {
00219 #define DEBUG_INFO_LENGTH 80
00220 char text[DEBUG_INFO_LENGTH];
00221
00222
00223
00224
00225 if (dbginfo < 0)
00226 LogCategory &= dbginfo;
00227 else
00228 LogCategory |= dbginfo;
00229
00230
00231 text[0] = '\0';
00232
00233 if (LogCategory & DEBUG_CATEGORY_APDU)
00234 strlcat(text, " APDU", sizeof(text));
00235
00236 Log2(PCSC_LOG_INFO, "Debug options:%s", text);
00237
00238 return LogCategory;
00239 }
00240
00241 INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
00242 const int len)
00243 {
00244 if ((category & DEBUG_CATEGORY_APDU)
00245 && (LogCategory & DEBUG_CATEGORY_APDU))
00246 log_xxd(PCSC_LOG_INFO, "APDU: ", (const unsigned char *)buffer, len);
00247
00248 if ((category & DEBUG_CATEGORY_SW)
00249 && (LogCategory & DEBUG_CATEGORY_APDU))
00250 log_xxd(PCSC_LOG_INFO, "SW: ", (const unsigned char *)buffer, len);
00251 }
00252
00270 char* pcsc_stringify_error(long pcscError)
00271 {
00272 static char strError[75];
00273
00274 switch (pcscError)
00275 {
00276 case SCARD_S_SUCCESS:
00277 strlcpy(strError, "Command successful.", sizeof(strError));
00278 break;
00279 case SCARD_E_CANCELLED:
00280 strlcpy(strError, "Command cancelled.", sizeof(strError));
00281 break;
00282 case SCARD_E_CANT_DISPOSE:
00283 strlcpy(strError, "Cannot dispose handle.", sizeof(strError));
00284 break;
00285 case SCARD_E_INSUFFICIENT_BUFFER:
00286 strlcpy(strError, "Insufficient buffer.", sizeof(strError));
00287 break;
00288 case SCARD_E_INVALID_ATR:
00289 strlcpy(strError, "Invalid ATR.", sizeof(strError));
00290 break;
00291 case SCARD_E_INVALID_HANDLE:
00292 strlcpy(strError, "Invalid handle.", sizeof(strError));
00293 break;
00294 case SCARD_E_INVALID_PARAMETER:
00295 strlcpy(strError, "Invalid parameter given.", sizeof(strError));
00296 break;
00297 case SCARD_E_INVALID_TARGET:
00298 strlcpy(strError, "Invalid target given.", sizeof(strError));
00299 break;
00300 case SCARD_E_INVALID_VALUE:
00301 strlcpy(strError, "Invalid value given.", sizeof(strError));
00302 break;
00303 case SCARD_E_NO_MEMORY:
00304 strlcpy(strError, "Not enough memory.", sizeof(strError));
00305 break;
00306 case SCARD_F_COMM_ERROR:
00307 strlcpy(strError, "RPC transport error.", sizeof(strError));
00308 break;
00309 case SCARD_F_INTERNAL_ERROR:
00310 strlcpy(strError, "Internal error.", sizeof(strError));
00311 break;
00312 case SCARD_F_UNKNOWN_ERROR:
00313 strlcpy(strError, "Unknown error.", sizeof(strError));
00314 break;
00315 case SCARD_F_WAITED_TOO_LONG:
00316 strlcpy(strError, "Waited too long.", sizeof(strError));
00317 break;
00318 case SCARD_E_UNKNOWN_READER:
00319 strlcpy(strError, "Unknown reader specified.", sizeof(strError));
00320 break;
00321 case SCARD_E_TIMEOUT:
00322 strlcpy(strError, "Command timeout.", sizeof(strError));
00323 break;
00324 case SCARD_E_SHARING_VIOLATION:
00325 strlcpy(strError, "Sharing violation.", sizeof(strError));
00326 break;
00327 case SCARD_E_NO_SMARTCARD:
00328 strlcpy(strError, "No smart card inserted.", sizeof(strError));
00329 break;
00330 case SCARD_E_UNKNOWN_CARD:
00331 strlcpy(strError, "Unknown card.", sizeof(strError));
00332 break;
00333 case SCARD_E_PROTO_MISMATCH:
00334 strlcpy(strError, "Card protocol mismatch.", sizeof(strError));
00335 break;
00336 case SCARD_E_NOT_READY:
00337 strlcpy(strError, "Subsystem not ready.", sizeof(strError));
00338 break;
00339 case SCARD_E_SYSTEM_CANCELLED:
00340 strlcpy(strError, "System cancelled.", sizeof(strError));
00341 break;
00342 case SCARD_E_NOT_TRANSACTED:
00343 strlcpy(strError, "Transaction failed.", sizeof(strError));
00344 break;
00345 case SCARD_E_READER_UNAVAILABLE:
00346 strlcpy(strError, "Reader is unavailable.", sizeof(strError));
00347 break;
00348 case SCARD_W_UNSUPPORTED_CARD:
00349 strlcpy(strError, "Card is not supported.", sizeof(strError));
00350 break;
00351 case SCARD_W_UNRESPONSIVE_CARD:
00352 strlcpy(strError, "Card is unresponsive.", sizeof(strError));
00353 break;
00354 case SCARD_W_UNPOWERED_CARD:
00355 strlcpy(strError, "Card is unpowered.", sizeof(strError));
00356 break;
00357 case SCARD_W_RESET_CARD:
00358 strlcpy(strError, "Card was reset.", sizeof(strError));
00359 break;
00360 case SCARD_W_REMOVED_CARD:
00361 strlcpy(strError, "Card was removed.", sizeof(strError));
00362 break;
00363 case SCARD_W_INSERTED_CARD:
00364 strlcpy(strError, "Card was inserted.", sizeof(strError));
00365 break;
00366 case SCARD_E_UNSUPPORTED_FEATURE:
00367 strlcpy(strError, "Feature not supported.", sizeof(strError));
00368 break;
00369 case SCARD_E_PCI_TOO_SMALL:
00370 strlcpy(strError, "PCI struct too small.", sizeof(strError));
00371 break;
00372 case SCARD_E_READER_UNSUPPORTED:
00373 strlcpy(strError, "Reader is unsupported.", sizeof(strError));
00374 break;
00375 case SCARD_E_DUPLICATE_READER:
00376 strlcpy(strError, "Reader already exists.", sizeof(strError));
00377 break;
00378 case SCARD_E_CARD_UNSUPPORTED:
00379 strlcpy(strError, "Card is unsupported.", sizeof(strError));
00380 break;
00381 case SCARD_E_NO_SERVICE:
00382 strlcpy(strError, "Service not available.", sizeof(strError));
00383 break;
00384 case SCARD_E_SERVICE_STOPPED:
00385 strlcpy(strError, "Service was stopped.", sizeof(strError));
00386 break;
00387 default:
00388 snprintf(strError, sizeof(strError)-1, "Unkown error: 0x%08lX",
00389 pcscError);
00390 };
00391
00392
00393 strError[sizeof(strError)] = '\0';
00394
00395 return strError;
00396 }
00397
00398
00399
00400
00401
00402 #ifdef PCSCD
00403 void debug_msg(const char *fmt, ...)
00404 {
00405 char DebugBuffer[DEBUG_BUF_SIZE];
00406 va_list argptr;
00407
00408 if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
00409 || (DEBUGLOG_NO_DEBUG == LogMsgType))
00410 return;
00411
00412 va_start(argptr, fmt);
00413 #ifndef WIN32
00414 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00415 #else
00416 #if HAVE_VSNPRINTF
00417 vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
00418 #else
00419 vsprintf(DebugBuffer, fmt, argptr);
00420 #endif
00421 #endif
00422 va_end(argptr);
00423
00424 #ifndef WIN32
00425 if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
00426 syslog(LOG_INFO, "%s", DebugBuffer);
00427 else
00428 #endif
00429 fprintf(stderr, "%s\n", DebugBuffer);
00430 }
00431
00432 void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
00433 {
00434 log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
00435 }
00436 #endif
00437