diff --git a/common/Makefile.am b/common/Makefile.am index 3a5f73dbd..b389d5a3f 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -44,6 +44,7 @@ libp11_test_la_SOURCES = \ $(NULL) libp11_tool_la_SOURCES = \ + common/print.c common/print.h \ common/tool.c common/tool.h \ $(NULL) diff --git a/common/meson.build b/common/meson.build index 5510a1ade..65ad0d866 100644 --- a/common/meson.build +++ b/common/meson.build @@ -49,6 +49,7 @@ if get_option('test') endif libp11_tool_sources = [ + 'print.c', 'tool.c' ] diff --git a/common/print.c b/common/print.c new file mode 100644 index 000000000..d1dee8048 --- /dev/null +++ b/common/print.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Zoltan Fridrich + */ + +#include "config.h" + +#include "print.h" + +#include +#include + +static const char * +color_to_sgr (p11_color color) +{ + switch (color) { + case P11_COLOR_BLACK: return "30"; + case P11_COLOR_RED: return "31"; + case P11_COLOR_GREEN: return "32"; + case P11_COLOR_YELLOW: return "33"; + case P11_COLOR_BLUE: return "34"; + case P11_COLOR_MAGENTA: return "35"; + case P11_COLOR_CYAN: return "36"; + case P11_COLOR_WHITE: return "37"; + default: return "0"; + } +} + +void +p11_highlight_word (FILE *fp, + const char *string) +{ + if (isatty (fileno (fp))) + fprintf (fp, "\e]8;;%s\e\\\033[36m%s\033[0m\e]8;;\e\\\n", string, string); + else + fprintf (fp, "%s\n", string); +} + +void +p11_print_word (FILE *fp, + const char *string, + p11_color color, + p11_font font) +{ + if (!isatty (fileno (fp))) { + fputs (string, fp); + return; + } + + fprintf (fp, "\033[%s", color_to_sgr (color)); + if (font & P11_FONT_BOLD) + fprintf (fp, ";1"); + if (font & P11_FONT_UNDERLINE) + fprintf (fp, ";4"); + fprintf (fp, "m%s\033[0m", string); +} + +void +p11_print_value (FILE *fp, + size_t indent, + const char *key, + p11_color color, + p11_font font, + const char *value_fmt, + ...) +{ + size_t i; + va_list args; + + for (i = 0; i < indent; ++i) + fputc (' ', fp); + + p11_print_word (fp, key, color, font); + p11_print_word (fp, ": ", color, font); + + va_start (args, value_fmt); + vfprintf (fp, value_fmt, args); + va_end (args); + fputc ('\n', fp); +} diff --git a/common/print.h b/common/print.h new file mode 100644 index 000000000..681c300ac --- /dev/null +++ b/common/print.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Zoltan Fridrich + */ + +#ifndef P11_PRINT_H_ +#define P11_PRINT_H_ + +#include + +#define P11_PRINT_VALUE_BOLD(INDENT, KEY, VALUE) \ + p11_print_value (stdout, INDENT, KEY, P11_COLOR_DEFAULT, P11_FONT_BOLD, VALUE) + +typedef enum { + P11_COLOR_DEFAULT, + P11_COLOR_BLACK, + P11_COLOR_RED, + P11_COLOR_GREEN, + P11_COLOR_YELLOW, + P11_COLOR_BLUE, + P11_COLOR_MAGENTA, + P11_COLOR_CYAN, + P11_COLOR_WHITE +} p11_color; + +typedef enum { + P11_FONT_DEFAULT = 0, + P11_FONT_BOLD = 1<<0, + P11_FONT_UNDERLINE = 1<<1 +} p11_font; + +void p11_highlight_word (FILE *fp, + const char *string); + +void p11_print_word (FILE *fp, + const char *string, + p11_color color, + p11_font font); + +void p11_print_value (FILE *fp, + size_t indent, + const char *key, + p11_color color, + p11_font font, + const char *value_fmt, + ...); + +#endif /* P11_PRINT_H_ */ diff --git a/p11-kit/lists.c b/p11-kit/lists.c index b0e38344f..d39e6ca68 100644 --- a/p11-kit/lists.c +++ b/p11-kit/lists.c @@ -48,6 +48,7 @@ #include "message.h" #include "p11-kit.h" +#include "print.h" #include "tool.h" #include "uri.h" @@ -119,35 +120,33 @@ print_token_info (CK_FUNCTION_LIST_PTR module, CK_SLOT_ID slot_id) } value = p11_kit_space_strdup (info.label, sizeof (info.label)); - printf (" token: %s\n", value); + p11_print_value (stdout, 4, "token", P11_COLOR_GREEN, P11_FONT_BOLD, value); free (value); value = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID)); - printf (" manufacturer: %s\n", value); + P11_PRINT_VALUE_BOLD (8, "manufacturer", value); free (value); value = p11_kit_space_strdup (info.model, sizeof (info.model)); - printf (" model: %s\n", value); + P11_PRINT_VALUE_BOLD (8, "model", value); free (value); if (is_ascii_string (info.serialNumber, sizeof (info.serialNumber))) value = p11_kit_space_strdup (info.serialNumber, sizeof (info.serialNumber)); else value = hex_encode (info.serialNumber, sizeof (info.serialNumber)); - printf (" serial-number: %s\n", value); + P11_PRINT_VALUE_BOLD (8, "serial-number", value); free (value); if (info.hardwareVersion.major || info.hardwareVersion.minor) - printf (" hardware-version: %d.%d\n", - info.hardwareVersion.major, - info.hardwareVersion.minor); + p11_print_value (stdout, 8, "hardware-version", P11_COLOR_DEFAULT, P11_FONT_BOLD, + "%d.%d", info.hardwareVersion.major, info.hardwareVersion.minor); if (info.firmwareVersion.major || info.firmwareVersion.minor) - printf (" firmware-version: %d.%d\n", - info.firmwareVersion.major, - info.firmwareVersion.minor); + p11_print_value (stdout, 8, "firmware-version", P11_COLOR_DEFAULT, P11_FONT_BOLD, + "%d.%d", info.firmwareVersion.major, info.firmwareVersion.minor); - printf (" flags:\n"); + p11_print_value (stdout, 8, "flags", P11_COLOR_DEFAULT, P11_FONT_BOLD, ""); #define X(x, y) if (info.flags & (x)) printf (" %s\n", (y)) X(CKF_RNG, "rng"); X(CKF_WRITE_PROTECTED, "write-protected"); @@ -185,19 +184,16 @@ print_module_info (CK_FUNCTION_LIST_PTR module) return; } - value = p11_kit_space_strdup (info.libraryDescription, - sizeof (info.libraryDescription)); - printf (" library-description: %s\n", value); + value = p11_kit_space_strdup (info.libraryDescription, sizeof (info.libraryDescription)); + P11_PRINT_VALUE_BOLD (4, "library-description", value); free (value); - value = p11_kit_space_strdup (info.manufacturerID, - sizeof (info.manufacturerID)); - printf (" library-manufacturer: %s\n", value); + value = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID)); + P11_PRINT_VALUE_BOLD (4, "library-manufacturer", value); free (value); - printf (" library-version: %d.%d\n", - info.libraryVersion.major, - info.libraryVersion.minor); + p11_print_value (stdout, 4, "library-version", P11_COLOR_DEFAULT, P11_FONT_BOLD, + "%d.%d", info.libraryVersion.major, info.libraryVersion.minor); count = sizeof (slot_list) / sizeof (slot_list[0]); rv = (module->C_GetSlotList) (CK_TRUE, slot_list, &count); @@ -226,9 +222,8 @@ print_modules (void) name = p11_kit_module_get_name (module_list[i]); path = p11_kit_config_option (module_list[i], "module"); - printf ("%s: %s\n", - name ? name : "(null)", - path ? path : "(null)"); + p11_print_value (stdout, 0, name ? name : "(null)", P11_COLOR_BLUE, + P11_FONT_BOLD, path ? path : "(null)"); print_module_info (module_list[i]); free (name); diff --git a/trust/check-format.c b/trust/check-format.c index bab2be6b9..049bfc241 100644 --- a/trust/check-format.c +++ b/trust/check-format.c @@ -40,6 +40,7 @@ #include "debug.h" #include "message.h" #include "persist.h" +#include "print.h" #include "tool.h" #include @@ -61,23 +62,21 @@ enum format_result { FORMAT_ERROR }; -static bool color_out; -static bool color_err; - static inline void print_result (enum format_result result, const char *filename) { - printf (color_out ? "\033[1m%s:\033[0m " : "%s: ", filename); + p11_print_word (stdout, filename, P11_COLOR_DEFAULT, P11_FONT_BOLD); + p11_print_word (stdout, ": ", P11_COLOR_DEFAULT, P11_FONT_BOLD); switch (result) { case FORMAT_OK: - printf (color_out ? "\033[1;32mOK\033[0m\n" : "OK\n"); + p11_print_word (stdout, "OK\n", P11_COLOR_GREEN, P11_FONT_BOLD); break; case FORMAT_FAIL: - printf (color_out ? "\033[1;31mFAIL\033[0m\n" : "FAIL\n"); + p11_print_word (stdout, "FAIL\n", P11_COLOR_RED, P11_FONT_BOLD); break; case FORMAT_ERROR: - printf (color_out ? "\033[1;31mERROR\033[0m\n" : "ERROR\n"); + p11_print_word (stdout, "ERROR\n", P11_COLOR_RED, P11_FONT_BOLD); break; default: assert_not_reached (); @@ -173,9 +172,6 @@ p11_trust_check_format (int argc, return 2; } - color_out = isatty (fileno (stdout)); - color_err = isatty (fileno (stderr)); - for (i = 0; i < argc; ++i) { result = check_format (argv[i]); print_result (result, argv[i]); diff --git a/trust/list.c b/trust/list.c index 0c2723cd5..a1c3ecbf2 100644 --- a/trust/list.c +++ b/trust/list.c @@ -43,6 +43,7 @@ #include "list.h" #include "message.h" #include "pkcs11x.h" +#include "print.h" #include "tool.h" #include "url.h" @@ -123,33 +124,33 @@ list_iterate (p11_enumerate *ex, continue; } - printf ("%s\n", string); + p11_highlight_word (stdout, string); free (string); if (p11_attrs_find_ulong (ex->attrs, CKA_CLASS, &klass)) { nick = p11_constant_nick (p11_constant_classes, klass); if (nick != NULL) - printf (" type: %s\n", nick); + P11_PRINT_VALUE_BOLD (4, "type", nick); } attr = p11_attrs_find_valid (ex->attrs, CKA_LABEL); if (attr && attr->pValue && attr->ulValueLen) { string = strndup (attr->pValue, attr->ulValueLen); - printf (" label: %s\n", string); + P11_PRINT_VALUE_BOLD (4, "label", string); free (string); } if (p11_attrs_find_bool (ex->attrs, CKA_X_DISTRUSTED, &val) && val) - printf (" trust: distrusted\n"); + P11_PRINT_VALUE_BOLD (4, "trust", "distrusted"); else if (p11_attrs_find_bool (ex->attrs, CKA_TRUSTED, &val) && val) - printf (" trust: anchor\n"); + P11_PRINT_VALUE_BOLD (4, "trust", "anchor"); else - printf (" trust: unspecified\n"); + P11_PRINT_VALUE_BOLD (4, "trust", "unspecified"); if (p11_attrs_find_ulong (ex->attrs, CKA_CERTIFICATE_CATEGORY, &category)) { nick = p11_constant_nick (p11_constant_categories, category); if (nick != NULL) - printf (" category: %s\n", nick); + P11_PRINT_VALUE_BOLD (4, "category", nick); } if (details) { @@ -158,7 +159,8 @@ list_iterate (p11_enumerate *ex, p11_buffer_init (&buf, 1024); bytes = attr->pValue; p11_url_encode (bytes, bytes + attr->ulValueLen, "", &buf); - printf (" public-key-info: %.*s\n", (int)buf.len, (char *)buf.data); + p11_print_value (stdout, 4, "public-key-info", P11_COLOR_DEFAULT, P11_FONT_BOLD, + "%.*s", (int)buf.len, (char *)buf.data); p11_buffer_uninit (&buf); } }