1 /*
2 * strings.c: Implementation of default UI strings
3 *
4 * Copyright (C) 2017 Frank Morgner <frankmorgner@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "libopensc/internal.h"
22 #include "ui/strings.h"
23 #include <locale.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 enum ui_langs {
28 EN,
29 DE,
30 };
31
get_inserted_text(struct sc_pkcs15_card * p15card,struct sc_atr * atr)32 static const char *get_inserted_text(struct sc_pkcs15_card *p15card, struct sc_atr *atr)
33 {
34 static char text[3*SC_MAX_ATR_SIZE] = {0};
35 const char prefix[] = "ATR: ";
36
37 if (p15card && p15card->card
38 && p15card->card->name) {
39 return p15card->card->name;
40 } else if (p15card && p15card->card
41 && p15card->card->reader && p15card->card->reader->name) {
42 return p15card->card->reader->name;
43 }
44
45 if (!atr)
46 return NULL;
47
48 strcpy(text, prefix);
49 sc_bin_to_hex(atr->value, atr->len, text + (sizeof prefix) - 1,
50 sizeof(text) - (sizeof prefix) - 1, ':');
51
52 return text;
53 }
54
get_removed_text(struct sc_pkcs15_card * p15card)55 static const char *get_removed_text(struct sc_pkcs15_card *p15card)
56 {
57 if (p15card && p15card->card && p15card->card->reader
58 && p15card->card->reader->name) {
59 return p15card->card->reader->name;
60 }
61
62 return NULL;
63 }
64
ui_get_config_str(struct sc_context * ctx,struct sc_atr * atr,const char * flag_name,const char * ret_default)65 static const char *ui_get_config_str(struct sc_context *ctx,
66 struct sc_atr *atr, const char *flag_name, const char *ret_default)
67 {
68 const char *ret = ret_default;
69
70 scconf_block *atrblock = _sc_match_atr_block(ctx, NULL, atr);
71
72 if (atrblock)
73 ret = scconf_get_str(atrblock, flag_name, ret_default);
74
75 return ret;
76 }
77
find_lang_str(const char * str,enum ui_langs * lang)78 static int find_lang_str(const char *str, enum ui_langs *lang)
79 {
80 if (str) {
81 if (0 == strncmp(str, "de", 2)) {
82 if (lang) {
83 *lang = DE;
84 }
85 return 1;
86 } else if (0 == strncmp(str, "en", 2)) {
87 if (lang) {
88 *lang = EN;
89 }
90 return 1;
91 }
92 }
93
94 return 0;
95 }
96
ui_get_str(struct sc_context * ctx,struct sc_atr * atr,struct sc_pkcs15_card * p15card,enum ui_str id)97 const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr,
98 struct sc_pkcs15_card *p15card, enum ui_str id)
99 {
100 enum ui_langs lang = EN;
101 const char *str, *option;
102
103 /* load option strings */
104 switch (id) {
105 case MD_PINPAD_DLG_TITLE:
106 option = "md_pinpad_dlg_title";
107 break;
108 case MD_PINPAD_DLG_MAIN:
109 option = "md_pinpad_dlg_main";
110 break;
111 case MD_PINPAD_DLG_CONTENT_USER:
112 option = "md_pinpad_dlg_content_user";
113 break;
114 case MD_PINPAD_DLG_CONTENT_USER_SIGN:
115 option = "md_pinpad_dlg_content_user_sign";
116 break;
117 case MD_PINPAD_DLG_CONTENT_ADMIN:
118 option = "md_pinpad_dlg_content_admin";
119 break;
120 case MD_PINPAD_DLG_EXPANDED:
121 option = "md_pinpad_dlg_expanded";
122 break;
123 case MD_PINPAD_DLG_ICON:
124 option = "md_pinpad_dlg_icon";
125 break;
126 case NOTIFY_CARD_INSERTED:
127 option = "notify_card_inserted";
128 break;
129 case NOTIFY_CARD_INSERTED_TEXT:
130 option = "notify_card_inserted_text";
131 break;
132 case NOTIFY_CARD_REMOVED:
133 option = "notify_card_removed";
134 break;
135 case NOTIFY_CARD_REMOVED_TEXT:
136 option = "notify_card_removed_text";
137 break;
138 case NOTIFY_PIN_GOOD:
139 option = "notify_pin_good";
140 break;
141 case NOTIFY_PIN_GOOD_TEXT:
142 option = "notify_pin_good_text";
143 break;
144 case NOTIFY_PIN_BAD:
145 option = "notify_pin_bad";
146 break;
147 case NOTIFY_PIN_BAD_TEXT:
148 option = "notify_pin_bad_text";
149 break;
150 case MD_PINPAD_DLG_VERIFICATION:
151 option = "md_pinpad_dlg_verification";
152 break;
153 default:
154 option = NULL;
155 break;
156 }
157
158 /* load language */
159 /* card's language supersedes system's language */
160 if (!p15card || !p15card->tokeninfo
161 || !find_lang_str(p15card->tokeninfo->preferred_language, &lang)) {
162 #ifdef _WIN32
163 LANGID langid = GetUserDefaultUILanguage();
164 if ((langid & LANG_GERMAN) == LANG_GERMAN) {
165 lang = DE;
166 }
167 #else
168 /* LANGUAGE supersedes locale */
169 if (!find_lang_str(getenv("LANGUAGE"), &lang)) {
170 /* XXX Should we use LC_MESSAGES instead? */
171 find_lang_str(setlocale(LC_ALL, ""), &lang);
172 }
173 #endif
174 }
175
176 /* load default strings */
177 switch (lang) {
178 case DE:
179 switch (id) {
180 case MD_PINPAD_DLG_TITLE:
181 str = "Windows-Sicherheit";
182 break;
183 case MD_PINPAD_DLG_MAIN:
184 str = "OpenSC Smartcard-Anbieter";
185 break;
186 case MD_PINPAD_DLG_CONTENT_USER:
187 str = "Bitte geben Sie Ihre PIN auf dem PIN-Pad ein.";
188 break;
189 case MD_PINPAD_DLG_CONTENT_USER_SIGN:
190 str = "Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PIN-Pad ein.";
191 break;
192 case MD_PINPAD_DLG_CONTENT_ADMIN:
193 str = "Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PIN-Pad ein.";
194 break;
195 case MD_PINPAD_DLG_EXPANDED:
196 str = "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PIN-Pad eingegeben wurde (Timeout typischerweise nach 30 Sekunden).";
197 break;
198 case NOTIFY_CARD_INSERTED:
199 if (p15card && p15card->card && p15card->card->name) {
200 str = "Smartcard kann jetzt verwendet werden";
201 } else {
202 str = "Smartcard erkannt";
203 }
204 break;
205 case NOTIFY_CARD_INSERTED_TEXT:
206 str = get_inserted_text(p15card, atr);
207 break;
208 case NOTIFY_CARD_REMOVED:
209 str = "Smartcard entfernt";
210 break;
211 case NOTIFY_CARD_REMOVED_TEXT:
212 str = get_removed_text(p15card);
213 break;
214 case NOTIFY_PIN_GOOD:
215 str = "PIN verifiziert";
216 break;
217 case NOTIFY_PIN_GOOD_TEXT:
218 str = "Smartcard ist entsperrt";
219 break;
220 case NOTIFY_PIN_BAD:
221 str = "PIN nicht verifiziert";
222 break;
223 case NOTIFY_PIN_BAD_TEXT:
224 str = "Smartcard ist gesperrt";
225 break;
226 case MD_PINPAD_DLG_VERIFICATION:
227 str = "Sofort PIN am PIN-Pad abfragen";
228 break;
229
230 case MD_PINPAD_DLG_CONTROL_COLLAPSED:
231 case MD_PINPAD_DLG_CONTROL_EXPANDED:
232 str = "Weitere Informationen";
233 break;
234 case MD_PINPAD_DLG_CANCEL:
235 str = "Abbrechen";
236 break;
237 case NOTIFY_EXIT:
238 str = "Beenden";
239 break;
240 default:
241 str = NULL;
242 break;
243 }
244 break;
245 case EN:
246 default:
247 switch (id) {
248 case MD_PINPAD_DLG_TITLE:
249 str = "Windows Security";
250 break;
251 case MD_PINPAD_DLG_MAIN:
252 str = "OpenSC Smart Card Provider";
253 break;
254 case MD_PINPAD_DLG_CONTENT_USER:
255 str = "Please enter your PIN on the PIN pad.";
256 break;
257 case MD_PINPAD_DLG_CONTENT_USER_SIGN:
258 str = "Please enter your digital signature PIN on the PIN pad.";
259 break;
260 case MD_PINPAD_DLG_CONTENT_ADMIN:
261 str = "Please enter your PIN to unblock the user PIN on the PIN pad.";
262 break;
263 case MD_PINPAD_DLG_EXPANDED:
264 str = "This window will be closed automatically after the PIN has been submitted on the PIN pad (timeout typically after 30 seconds).";
265 break;
266 case NOTIFY_CARD_INSERTED:
267 if (p15card && p15card->card && p15card->card->name) {
268 str = "Smart card is ready to use";
269 } else {
270 str = "Smart card detected";
271 }
272 break;
273 case NOTIFY_CARD_INSERTED_TEXT:
274 str = get_inserted_text(p15card, atr);
275 break;
276 case NOTIFY_CARD_REMOVED:
277 str = "Smart card removed";
278 break;
279 case NOTIFY_CARD_REMOVED_TEXT:
280 str = get_removed_text(p15card);
281 break;
282 case NOTIFY_PIN_GOOD:
283 str = "PIN verified";
284 break;
285 case NOTIFY_PIN_GOOD_TEXT:
286 str = "Smart card is unlocked";
287 break;
288 case NOTIFY_PIN_BAD:
289 str = "PIN not verified";
290 break;
291 case NOTIFY_PIN_BAD_TEXT:
292 str = "Smart card is locked";
293 break;
294 case MD_PINPAD_DLG_VERIFICATION:
295 str = "Immediately request PIN on PIN-Pad";
296 break;
297
298 case MD_PINPAD_DLG_CONTROL_COLLAPSED:
299 case MD_PINPAD_DLG_CONTROL_EXPANDED:
300 str = "Click here for more information";
301 break;
302 case MD_PINPAD_DLG_CANCEL:
303 str = "Cancel";
304 break;
305 case NOTIFY_EXIT:
306 str = "Exit";
307 break;
308 default:
309 str = NULL;
310 break;
311 }
312 break;
313 }
314
315 /* user's strings supersede default strings */
316 if (option != NULL) {
317 /* overwrite str with the user's choice */
318 str = ui_get_config_str(ctx, atr, option, str);
319 }
320
321 return str;
322 }
323