1 | /* poppler-form-field.cc: glib interface to poppler |
2 | * |
3 | * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org> |
4 | * Copyright (C) 2006 Julien Rebetez |
5 | * Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de> |
6 | * Copyright (C) 2021 André Guerreiro <aguerreiro1985@gmail.com> |
7 | * Copyright (C) 2021, 2023 Marek Kasik <mkasik@redhat.com> |
8 | * Copyright (C) 2023, 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2, or (at your option) |
13 | * any later version. |
14 | * |
15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
23 | */ |
24 | |
25 | #include <memory> |
26 | |
27 | #include "poppler.h" |
28 | #include "poppler-private.h" |
29 | |
30 | #include <CertificateInfo.h> |
31 | #ifdef ENABLE_NSS3 |
32 | # include <NSSCryptoSignBackend.h> |
33 | #endif |
34 | #include <CryptoSignBackend.h> |
35 | |
36 | /** |
37 | * SECTION:poppler-form-field |
38 | * @short_description: Form Field |
39 | * @title: PopplerFormField |
40 | */ |
41 | |
42 | typedef struct _PopplerFormFieldClass PopplerFormFieldClass; |
43 | struct _PopplerFormFieldClass |
44 | { |
45 | GObjectClass parent_class; |
46 | }; |
47 | |
48 | G_DEFINE_TYPE(PopplerFormField, poppler_form_field, G_TYPE_OBJECT) |
49 | |
50 | static void poppler_form_field_finalize(GObject *object) |
51 | { |
52 | PopplerFormField *field = POPPLER_FORM_FIELD(object); |
53 | |
54 | if (field->document) { |
55 | g_object_unref(object: field->document); |
56 | field->document = nullptr; |
57 | } |
58 | if (field->action) { |
59 | poppler_action_free(action: field->action); |
60 | field->action = nullptr; |
61 | } |
62 | field->widget = nullptr; |
63 | |
64 | G_OBJECT_CLASS(poppler_form_field_parent_class)->finalize(object); |
65 | } |
66 | |
67 | static void poppler_form_field_init(PopplerFormField *field) { } |
68 | |
69 | static void poppler_form_field_class_init(PopplerFormFieldClass *klass) |
70 | { |
71 | GObjectClass *gobject_class = G_OBJECT_CLASS(klass); |
72 | |
73 | gobject_class->finalize = poppler_form_field_finalize; |
74 | } |
75 | |
76 | PopplerFormField *_poppler_form_field_new(PopplerDocument *document, FormWidget *field) |
77 | { |
78 | PopplerFormField *poppler_field; |
79 | |
80 | g_return_val_if_fail(POPPLER_IS_DOCUMENT(document), NULL); |
81 | g_return_val_if_fail(field != nullptr, NULL); |
82 | |
83 | poppler_field = POPPLER_FORM_FIELD(g_object_new(POPPLER_TYPE_FORM_FIELD, nullptr)); |
84 | |
85 | poppler_field->document = (PopplerDocument *)g_object_ref(document); |
86 | poppler_field->widget = field; |
87 | |
88 | return poppler_field; |
89 | } |
90 | |
91 | /* Public methods */ |
92 | /** |
93 | * poppler_form_field_get_field_type: |
94 | * @field: a #PopplerFormField |
95 | * |
96 | * Gets the type of @field |
97 | * |
98 | * Return value: #PopplerFormFieldType of @field |
99 | **/ |
100 | PopplerFormFieldType poppler_form_field_get_field_type(PopplerFormField *field) |
101 | { |
102 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), POPPLER_FORM_FIELD_UNKNOWN); |
103 | |
104 | switch (field->widget->getType()) { |
105 | case formButton: |
106 | return POPPLER_FORM_FIELD_BUTTON; |
107 | case formText: |
108 | return POPPLER_FORM_FIELD_TEXT; |
109 | case formChoice: |
110 | return POPPLER_FORM_FIELD_CHOICE; |
111 | case formSignature: |
112 | return POPPLER_FORM_FIELD_SIGNATURE; |
113 | default: |
114 | g_warning("Unsupported Form Field Type" ); |
115 | } |
116 | |
117 | return POPPLER_FORM_FIELD_UNKNOWN; |
118 | } |
119 | |
120 | /** |
121 | * poppler_form_field_get_id: |
122 | * @field: a #PopplerFormField |
123 | * |
124 | * Gets the id of @field |
125 | * |
126 | * Return value: the id of @field |
127 | **/ |
128 | gint poppler_form_field_get_id(PopplerFormField *field) |
129 | { |
130 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), -1); |
131 | |
132 | return field->widget->getID(); |
133 | } |
134 | |
135 | /** |
136 | * poppler_form_field_get_font_size: |
137 | * @field: a #PopplerFormField |
138 | * |
139 | * Gets the font size of @field |
140 | * |
141 | * WARNING: This function always returns 0. Contact the poppler |
142 | * mailing list if you're interested in implementing it properly |
143 | * |
144 | * Return value: the font size of @field |
145 | **/ |
146 | gdouble poppler_form_field_get_font_size(PopplerFormField *field) |
147 | { |
148 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), 0); |
149 | |
150 | return 0; |
151 | } |
152 | |
153 | /** |
154 | * poppler_form_field_is_read_only: |
155 | * @field: a #PopplerFormField |
156 | * |
157 | * Checks whether @field is read only |
158 | * |
159 | * Return value: %TRUE if @field is read only |
160 | **/ |
161 | gboolean poppler_form_field_is_read_only(PopplerFormField *field) |
162 | { |
163 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), FALSE); |
164 | |
165 | return field->widget->isReadOnly(); |
166 | } |
167 | |
168 | /** |
169 | * poppler_form_field_get_action: |
170 | * @field: a #PopplerFormField |
171 | * |
172 | * Retrieves the action (#PopplerAction) that shall be |
173 | * performed when @field is activated, or %NULL |
174 | * |
175 | * Return value: (transfer none): the action to perform. The returned |
176 | * object is owned by @field and should not be freed |
177 | * |
178 | * Since: 0.18 |
179 | */ |
180 | PopplerAction *poppler_form_field_get_action(PopplerFormField *field) |
181 | { |
182 | LinkAction *action; |
183 | |
184 | if (field->action) { |
185 | return field->action; |
186 | } |
187 | |
188 | action = field->widget->getActivationAction(); |
189 | if (!action) { |
190 | return nullptr; |
191 | } |
192 | |
193 | field->action = _poppler_action_new(document: field->document, link: action, title: nullptr); |
194 | |
195 | return field->action; |
196 | } |
197 | |
198 | /** |
199 | * poppler_form_field_get_additional_action: |
200 | * @field: a #PopplerFormField |
201 | * @type: the type of additional action |
202 | * |
203 | * Retrieves the action (#PopplerAction) that shall be performed when |
204 | * an additional action is triggered on @field, or %NULL. |
205 | * |
206 | * Return value: (transfer none): the action to perform. The returned |
207 | * object is owned by @field and should not be freed. |
208 | * |
209 | * |
210 | * Since: 0.72 |
211 | */ |
212 | PopplerAction *poppler_form_field_get_additional_action(PopplerFormField *field, PopplerAdditionalActionType type) |
213 | { |
214 | Annot::FormAdditionalActionsType form_action; |
215 | PopplerAction **action; |
216 | |
217 | switch (type) { |
218 | case POPPLER_ADDITIONAL_ACTION_FIELD_MODIFIED: |
219 | form_action = Annot::actionFieldModified; |
220 | action = &field->field_modified_action; |
221 | break; |
222 | case POPPLER_ADDITIONAL_ACTION_FORMAT_FIELD: |
223 | form_action = Annot::actionFormatField; |
224 | action = &field->format_field_action; |
225 | break; |
226 | case POPPLER_ADDITIONAL_ACTION_VALIDATE_FIELD: |
227 | form_action = Annot::actionValidateField; |
228 | action = &field->validate_field_action; |
229 | break; |
230 | case POPPLER_ADDITIONAL_ACTION_CALCULATE_FIELD: |
231 | form_action = Annot::actionCalculateField; |
232 | action = &field->calculate_field_action; |
233 | break; |
234 | default: |
235 | g_return_val_if_reached(nullptr); |
236 | return nullptr; |
237 | } |
238 | |
239 | if (*action) { |
240 | return *action; |
241 | } |
242 | |
243 | std::unique_ptr<LinkAction> link_action = field->widget->getAdditionalAction(type: form_action); |
244 | if (!link_action) { |
245 | return nullptr; |
246 | } |
247 | |
248 | *action = _poppler_action_new(document: nullptr, link: link_action.get(), title: nullptr); |
249 | |
250 | return *action; |
251 | } |
252 | |
253 | /* Button Field */ |
254 | /** |
255 | * poppler_form_field_button_get_button_type: |
256 | * @field: a #PopplerFormField |
257 | * |
258 | * Gets the button type of @field |
259 | * |
260 | * Return value: #PopplerFormButtonType of @field |
261 | **/ |
262 | PopplerFormButtonType poppler_form_field_button_get_button_type(PopplerFormField *field) |
263 | { |
264 | g_return_val_if_fail(field->widget->getType() == formButton, POPPLER_FORM_BUTTON_PUSH); |
265 | |
266 | switch (static_cast<FormWidgetButton *>(field->widget)->getButtonType()) { |
267 | case formButtonPush: |
268 | return POPPLER_FORM_BUTTON_PUSH; |
269 | case formButtonCheck: |
270 | return POPPLER_FORM_BUTTON_CHECK; |
271 | case formButtonRadio: |
272 | return POPPLER_FORM_BUTTON_RADIO; |
273 | default: |
274 | g_assert_not_reached(); |
275 | } |
276 | } |
277 | |
278 | /** |
279 | * poppler_form_field_button_get_state: |
280 | * @field: a #PopplerFormField |
281 | * |
282 | * Queries a #PopplerFormField and returns its current state. Returns %TRUE if |
283 | * @field is pressed in and %FALSE if it is raised. |
284 | * |
285 | * Return value: current state of @field |
286 | **/ |
287 | gboolean poppler_form_field_button_get_state(PopplerFormField *field) |
288 | { |
289 | g_return_val_if_fail(field->widget->getType() == formButton, FALSE); |
290 | |
291 | return static_cast<FormWidgetButton *>(field->widget)->getState(); |
292 | } |
293 | |
294 | /** |
295 | * poppler_form_field_button_set_state: |
296 | * @field: a #PopplerFormField |
297 | * @state: %TRUE or %FALSE |
298 | * |
299 | * Sets the status of @field. Set to %TRUE if you want the #PopplerFormField |
300 | * to be 'pressed in', and %FALSE to raise it. |
301 | **/ |
302 | void poppler_form_field_button_set_state(PopplerFormField *field, gboolean state) |
303 | { |
304 | g_return_if_fail(field->widget->getType() == formButton); |
305 | |
306 | static_cast<FormWidgetButton *>(field->widget)->setState((bool)state); |
307 | } |
308 | |
309 | /** |
310 | * poppler_form_field_get_partial_name: |
311 | * @field: a #PopplerFormField |
312 | * |
313 | * Gets the partial name of @field. |
314 | * |
315 | * Return value: a new allocated string. It must be freed with g_free() when done. |
316 | * |
317 | * Since: 0.16 |
318 | **/ |
319 | gchar *poppler_form_field_get_partial_name(PopplerFormField *field) |
320 | { |
321 | const GooString *tmp; |
322 | |
323 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL); |
324 | |
325 | tmp = field->widget->getPartialName(); |
326 | |
327 | return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr; |
328 | } |
329 | |
330 | /** |
331 | * poppler_form_field_get_mapping_name: |
332 | * @field: a #PopplerFormField |
333 | * |
334 | * Gets the mapping name of @field that is used when |
335 | * exporting interactive form field data from the document |
336 | * |
337 | * Return value: a new allocated string. It must be freed with g_free() when done. |
338 | * |
339 | * Since: 0.16 |
340 | **/ |
341 | gchar *poppler_form_field_get_mapping_name(PopplerFormField *field) |
342 | { |
343 | const GooString *tmp; |
344 | |
345 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL); |
346 | |
347 | tmp = field->widget->getMappingName(); |
348 | |
349 | return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr; |
350 | } |
351 | |
352 | /** |
353 | * poppler_form_field_get_name: |
354 | * @field: a #PopplerFormField |
355 | * |
356 | * Gets the fully qualified name of @field. It's constructed by concatenating |
357 | * the partial field names of the field and all of its ancestors. |
358 | * |
359 | * Return value: a new allocated string. It must be freed with g_free() when done. |
360 | * |
361 | * Since: 0.16 |
362 | **/ |
363 | gchar *poppler_form_field_get_name(PopplerFormField *field) |
364 | { |
365 | GooString *tmp; |
366 | |
367 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL); |
368 | |
369 | tmp = field->widget->getFullyQualifiedName(); |
370 | |
371 | return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr; |
372 | } |
373 | |
374 | /** |
375 | * poppler_form_field_get_alternate_ui_name: |
376 | * @field: a #PopplerFormField |
377 | * |
378 | * Gets the alternate ui name of @field. This name is also commonly |
379 | * used by pdf producers/readers to show it as a tooltip when @field area |
380 | * is hovered by a pointing device (eg. mouse). |
381 | * |
382 | * Return value: a new allocated string. It must be freed with g_free() when done. |
383 | * |
384 | * Since: 0.88 |
385 | **/ |
386 | gchar *poppler_form_field_get_alternate_ui_name(PopplerFormField *field) |
387 | { |
388 | const GooString *tmp; |
389 | |
390 | g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL); |
391 | |
392 | tmp = field->widget->getAlternateUiName(); |
393 | |
394 | return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr; |
395 | } |
396 | |
397 | /** |
398 | * PopplerCertificateInfo: |
399 | * |
400 | * PopplerCertificateInfo contains detailed info about a signing certificate. |
401 | * |
402 | * Since: 23.07.0 |
403 | */ |
404 | struct _PopplerCertificateInfo |
405 | { |
406 | char *id; |
407 | char *subject_common_name; |
408 | char *subject_organization; |
409 | char *subject_email; |
410 | char *issuer_common_name; |
411 | char *issuer_organization; |
412 | char *issuer_email; |
413 | GDateTime *issued; |
414 | GDateTime *expires; |
415 | }; |
416 | |
417 | typedef struct _PopplerCertificateInfo PopplerCertificateInfo; |
418 | |
419 | G_DEFINE_BOXED_TYPE(PopplerCertificateInfo, poppler_certificate_info, poppler_certificate_info_copy, poppler_certificate_info_free) |
420 | |
421 | /** |
422 | * PopplerSignatureInfo: |
423 | * |
424 | * PopplerSignatureInfo contains detailed info about a signature |
425 | * contained in a form field. |
426 | * |
427 | * Since: 21.12.0 |
428 | **/ |
429 | struct _PopplerSignatureInfo |
430 | { |
431 | PopplerSignatureStatus sig_status; |
432 | PopplerCertificateStatus cert_status; |
433 | char *signer_name; |
434 | GDateTime *local_signing_time; |
435 | PopplerCertificateInfo *certificate_info; |
436 | }; |
437 | |
438 | static PopplerSignatureInfo *_poppler_form_field_signature_validate(PopplerFormField *field, PopplerSignatureValidationFlags flags, gboolean force_revalidation, GError **error) |
439 | { |
440 | FormFieldSignature *sig_field; |
441 | SignatureInfo *sig_info; |
442 | PopplerSignatureInfo *poppler_sig_info; |
443 | const X509CertificateInfo *certificate_info; |
444 | |
445 | if (poppler_form_field_get_field_type(field) != POPPLER_FORM_FIELD_SIGNATURE) { |
446 | g_set_error(err: error, POPPLER_ERROR, code: POPPLER_ERROR_INVALID, format: "Wrong FormField type" ); |
447 | return nullptr; |
448 | } |
449 | |
450 | sig_field = static_cast<FormFieldSignature *>(field->widget->getField()); |
451 | |
452 | sig_info = sig_field->validateSignatureAsync(doVerifyCert: flags & POPPLER_SIGNATURE_VALIDATION_FLAG_VALIDATE_CERTIFICATE, forceRevalidation: force_revalidation, validationTime: -1, ocspRevocationCheck: flags & POPPLER_SIGNATURE_VALIDATION_FLAG_WITHOUT_OCSP_REVOCATION_CHECK, |
453 | enableAIA: flags & POPPLER_SIGNATURE_VALIDATION_FLAG_USE_AIA_CERTIFICATE_FETCH, doneCallback: {}); |
454 | CertificateValidationStatus certificateStatus = sig_field->validateSignatureResult(); |
455 | |
456 | poppler_sig_info = g_new0(PopplerSignatureInfo, 1); |
457 | switch (sig_info->getSignatureValStatus()) { |
458 | case SIGNATURE_VALID: |
459 | poppler_sig_info->sig_status = POPPLER_SIGNATURE_VALID; |
460 | break; |
461 | case SIGNATURE_INVALID: |
462 | poppler_sig_info->sig_status = POPPLER_SIGNATURE_INVALID; |
463 | break; |
464 | case SIGNATURE_DIGEST_MISMATCH: |
465 | poppler_sig_info->sig_status = POPPLER_SIGNATURE_DIGEST_MISMATCH; |
466 | break; |
467 | case SIGNATURE_DECODING_ERROR: |
468 | poppler_sig_info->sig_status = POPPLER_SIGNATURE_DECODING_ERROR; |
469 | break; |
470 | case SIGNATURE_GENERIC_ERROR: |
471 | poppler_sig_info->sig_status = POPPLER_SIGNATURE_GENERIC_ERROR; |
472 | break; |
473 | case SIGNATURE_NOT_FOUND: |
474 | poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_FOUND; |
475 | break; |
476 | case SIGNATURE_NOT_VERIFIED: |
477 | poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_VERIFIED; |
478 | break; |
479 | } |
480 | |
481 | switch (certificateStatus) { |
482 | case CERTIFICATE_TRUSTED: |
483 | poppler_sig_info->cert_status = POPPLER_CERTIFICATE_TRUSTED; |
484 | break; |
485 | case CERTIFICATE_UNTRUSTED_ISSUER: |
486 | poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNTRUSTED_ISSUER; |
487 | break; |
488 | case CERTIFICATE_UNKNOWN_ISSUER: |
489 | poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNKNOWN_ISSUER; |
490 | break; |
491 | case CERTIFICATE_REVOKED: |
492 | poppler_sig_info->cert_status = POPPLER_CERTIFICATE_REVOKED; |
493 | break; |
494 | case CERTIFICATE_EXPIRED: |
495 | poppler_sig_info->cert_status = POPPLER_CERTIFICATE_EXPIRED; |
496 | break; |
497 | case CERTIFICATE_GENERIC_ERROR: |
498 | poppler_sig_info->cert_status = POPPLER_CERTIFICATE_GENERIC_ERROR; |
499 | break; |
500 | case CERTIFICATE_NOT_VERIFIED: |
501 | poppler_sig_info->cert_status = POPPLER_CERTIFICATE_NOT_VERIFIED; |
502 | break; |
503 | } |
504 | |
505 | std::string signerName = sig_info->getSignerName(); |
506 | poppler_sig_info->signer_name = g_strdup(str: signerName.c_str()); |
507 | poppler_sig_info->local_signing_time = g_date_time_new_from_unix_local(t: sig_info->getSigningTime()); |
508 | |
509 | certificate_info = sig_info->getCertificateInfo(); |
510 | if (certificate_info != nullptr) { |
511 | const X509CertificateInfo::EntityInfo &subject_info = certificate_info->getSubjectInfo(); |
512 | const X509CertificateInfo::EntityInfo &issuer_info = certificate_info->getIssuerInfo(); |
513 | const X509CertificateInfo::Validity &validity = certificate_info->getValidity(); |
514 | |
515 | poppler_sig_info->certificate_info = poppler_certificate_info_new(); |
516 | poppler_sig_info->certificate_info->subject_common_name = g_strdup(str: subject_info.commonName.c_str()); |
517 | poppler_sig_info->certificate_info->subject_organization = g_strdup(str: subject_info.organization.c_str()); |
518 | poppler_sig_info->certificate_info->subject_email = g_strdup(str: subject_info.email.c_str()); |
519 | poppler_sig_info->certificate_info->issuer_common_name = g_strdup(str: issuer_info.commonName.c_str()); |
520 | poppler_sig_info->certificate_info->issuer_email = g_strdup(str: issuer_info.email.c_str()); |
521 | poppler_sig_info->certificate_info->issuer_organization = g_strdup(str: issuer_info.organization.c_str()); |
522 | poppler_sig_info->certificate_info->issued = g_date_time_new_from_unix_utc(t: validity.notBefore); |
523 | poppler_sig_info->certificate_info->expires = g_date_time_new_from_unix_utc(t: validity.notAfter); |
524 | } |
525 | |
526 | return poppler_sig_info; |
527 | } |
528 | |
529 | static void signature_validate_thread(GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) |
530 | { |
531 | PopplerSignatureValidationFlags flags = (PopplerSignatureValidationFlags)GPOINTER_TO_INT(task_data); |
532 | PopplerSignatureInfo *signature_info; |
533 | PopplerFormField *field = (PopplerFormField *)source_object; |
534 | GError *error = nullptr; |
535 | |
536 | signature_info = _poppler_form_field_signature_validate(field, flags, FALSE, error: &error); |
537 | if (signature_info == nullptr && error != nullptr) { |
538 | g_task_return_error(task, error); |
539 | return; |
540 | } |
541 | |
542 | if (g_task_set_return_on_cancel(task, FALSE)) { |
543 | g_task_return_pointer(task, result: signature_info, result_destroy: (GDestroyNotify)poppler_signature_info_free); |
544 | } |
545 | } |
546 | |
547 | /** |
548 | * poppler_form_field_signature_validate_sync: |
549 | * @field: a #PopplerFormField that represents a signature annotation |
550 | * @flags: #PopplerSignatureValidationFlags flags influencing process of validation of the field signature |
551 | * @cancellable: (nullable): optional #GCancellable object |
552 | * @error: a #GError |
553 | * |
554 | * Synchronously validates the cryptographic signature contained in @signature_field. |
555 | * |
556 | * Return value: (transfer full): a #PopplerSignatureInfo structure containing signature metadata and validation status |
557 | * Free the returned structure with poppler_signature_info_free(). |
558 | * |
559 | * Since: 21.12.0 |
560 | **/ |
561 | PopplerSignatureInfo *poppler_form_field_signature_validate_sync(PopplerFormField *field, PopplerSignatureValidationFlags flags, GCancellable *cancellable, GError **error) |
562 | { |
563 | PopplerSignatureInfo *signature_info; |
564 | GTask *task; |
565 | |
566 | g_return_val_if_fail(error == NULL || *error == NULL, NULL); |
567 | |
568 | task = g_task_new(source_object: field, cancellable, callback: nullptr, callback_data: nullptr); |
569 | g_task_set_task_data(task, GINT_TO_POINTER(flags), task_data_destroy: nullptr); |
570 | g_task_set_return_on_cancel(task, TRUE); |
571 | |
572 | g_task_run_in_thread_sync(task, task_func: signature_validate_thread); |
573 | |
574 | signature_info = (PopplerSignatureInfo *)g_task_propagate_pointer(task, error); |
575 | g_object_unref(object: task); |
576 | |
577 | return signature_info; |
578 | } |
579 | |
580 | /** |
581 | * poppler_form_field_signature_validate_async: |
582 | * @field: a #PopplerFormField that represents a signature annotation |
583 | * @flags: #PopplerSignatureValidationFlags flags influencing process of validation of the field signature |
584 | * @cancellable: (nullable): optional #GCancellable object |
585 | * @callback: (scope async): a #GAsyncReadyCallback to call when the signature is validated |
586 | * @user_data: (closure): the data to pass to callback function |
587 | * |
588 | * Asynchronously validates the cryptographic signature contained in @signature_field. |
589 | * |
590 | * Since: 21.12.0 |
591 | **/ |
592 | void poppler_form_field_signature_validate_async(PopplerFormField *field, PopplerSignatureValidationFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) |
593 | { |
594 | GTask *task; |
595 | |
596 | task = g_task_new(source_object: field, cancellable, callback, callback_data: user_data); |
597 | g_task_set_task_data(task, GINT_TO_POINTER(flags), task_data_destroy: nullptr); |
598 | g_task_set_return_on_cancel(task, TRUE); |
599 | |
600 | g_task_run_in_thread(task, task_func: signature_validate_thread); |
601 | |
602 | g_object_unref(object: task); |
603 | } |
604 | |
605 | /** |
606 | * poppler_form_field_signature_validate_finish: |
607 | * @field: a #PopplerFormField that represents a signature annotation |
608 | * @result: a #GAsyncResult |
609 | * @error: a #GError |
610 | * |
611 | * Finishes validation of the cryptographic signature contained in @signature_field. |
612 | * See poppler_form_field_signature_validate_async(). |
613 | * |
614 | * Return value: (transfer full): a #PopplerSignatureInfo structure containing signature metadata and validation status |
615 | * Free the returned structure with poppler_signature_info_free(). |
616 | * |
617 | * Since: 21.12.0 |
618 | **/ |
619 | PopplerSignatureInfo *poppler_form_field_signature_validate_finish(PopplerFormField *field, GAsyncResult *result, GError **error) |
620 | { |
621 | g_return_val_if_fail(g_task_is_valid(result, field), NULL); |
622 | |
623 | return (PopplerSignatureInfo *)g_task_propagate_pointer(G_TASK(result), error); |
624 | } |
625 | |
626 | G_DEFINE_BOXED_TYPE(PopplerSignatureInfo, poppler_signature_info, poppler_signature_info_copy, poppler_signature_info_free) |
627 | |
628 | /** |
629 | * poppler_signature_info_copy: |
630 | * @siginfo: a #PopplerSignatureInfo structure containing signature metadata and validation status |
631 | * |
632 | * Copies @siginfo, creating an identical #PopplerSignatureInfo. |
633 | * |
634 | * Return value: (transfer full): a new #PopplerSignatureInfo structure identical to @siginfo |
635 | * |
636 | * Since: 21.12.0 |
637 | **/ |
638 | PopplerSignatureInfo *poppler_signature_info_copy(const PopplerSignatureInfo *siginfo) |
639 | { |
640 | PopplerSignatureInfo *new_info; |
641 | |
642 | g_return_val_if_fail(siginfo != NULL, NULL); |
643 | |
644 | new_info = g_new(PopplerSignatureInfo, 1); |
645 | new_info->sig_status = siginfo->sig_status; |
646 | new_info->cert_status = siginfo->cert_status; |
647 | new_info->signer_name = g_strdup(str: siginfo->signer_name); |
648 | new_info->local_signing_time = g_date_time_ref(datetime: siginfo->local_signing_time); |
649 | new_info->certificate_info = poppler_certificate_info_copy(certificate_info: siginfo->certificate_info); |
650 | |
651 | return new_info; |
652 | } |
653 | |
654 | /** |
655 | * poppler_signature_info_free: |
656 | * @siginfo: a #PopplerSignatureInfo structure containing signature metadata and validation status |
657 | * |
658 | * Frees @siginfo |
659 | * |
660 | * Since: 21.12.0 |
661 | **/ |
662 | void poppler_signature_info_free(PopplerSignatureInfo *siginfo) |
663 | { |
664 | if (siginfo == nullptr) { |
665 | return; |
666 | } |
667 | |
668 | g_date_time_unref(datetime: siginfo->local_signing_time); |
669 | g_free(mem: siginfo->signer_name); |
670 | poppler_certificate_info_free(certificate_info: siginfo->certificate_info); |
671 | g_free(mem: siginfo); |
672 | } |
673 | |
674 | /** |
675 | * poppler_signature_info_get_signature_status: |
676 | * @siginfo: a #PopplerSignatureInfo |
677 | * |
678 | * Returns status of the signature for given PopplerSignatureInfo. |
679 | * |
680 | * Return value: signature status of the signature |
681 | * |
682 | * Since: 21.12.0 |
683 | **/ |
684 | PopplerSignatureStatus poppler_signature_info_get_signature_status(const PopplerSignatureInfo *siginfo) |
685 | { |
686 | g_return_val_if_fail(siginfo != NULL, POPPLER_SIGNATURE_GENERIC_ERROR); |
687 | |
688 | return siginfo->sig_status; |
689 | } |
690 | |
691 | /** |
692 | * poppler_signature_info_get_certificate_info: |
693 | * @siginfo: a #PopplerSignatureInfo |
694 | * |
695 | * Returns PopplerCertificateInfo for given PopplerSignatureInfo. |
696 | * |
697 | * Return value: (transfer none): certificate info of the signature |
698 | * |
699 | * Since: 23.08.0 |
700 | **/ |
701 | PopplerCertificateInfo *poppler_signature_info_get_certificate_info(const PopplerSignatureInfo *siginfo) |
702 | { |
703 | g_return_val_if_fail(siginfo != NULL, NULL); |
704 | |
705 | return siginfo->certificate_info; |
706 | } |
707 | |
708 | /** |
709 | * poppler_signature_info_get_certificate_status: |
710 | * @siginfo: a #PopplerSignatureInfo |
711 | * |
712 | * Returns status of the certificate for given PopplerSignatureInfo. |
713 | * |
714 | * Return value: certificate status of the signature |
715 | * |
716 | * Since: 21.12.0 |
717 | **/ |
718 | PopplerCertificateStatus poppler_signature_info_get_certificate_status(const PopplerSignatureInfo *siginfo) |
719 | { |
720 | g_return_val_if_fail(siginfo != NULL, POPPLER_CERTIFICATE_GENERIC_ERROR); |
721 | |
722 | return siginfo->cert_status; |
723 | } |
724 | |
725 | /** |
726 | * poppler_signature_info_get_signer_name: |
727 | * @siginfo: a #PopplerSignatureInfo |
728 | * |
729 | * Returns name of signer for given PopplerSignatureInfo. |
730 | * |
731 | * Return value: (transfer none): A string. |
732 | * |
733 | * Since: 21.12.0 |
734 | **/ |
735 | const gchar *poppler_signature_info_get_signer_name(const PopplerSignatureInfo *siginfo) |
736 | { |
737 | g_return_val_if_fail(siginfo != NULL, NULL); |
738 | |
739 | return siginfo->signer_name; |
740 | } |
741 | |
742 | /** |
743 | * poppler_signature_info_get_local_signing_time: |
744 | * @siginfo: a #PopplerSignatureInfo |
745 | * |
746 | * Returns local time of signing as GDateTime. This does not |
747 | * contain information about time zone since it has not been |
748 | * preserved during conversion. |
749 | * Do not modify returned value since it is internal to |
750 | * PopplerSignatureInfo. |
751 | * |
752 | * Return value: (transfer none): GDateTime |
753 | * |
754 | * Since: 21.12.0 |
755 | **/ |
756 | GDateTime *poppler_signature_info_get_local_signing_time(const PopplerSignatureInfo *siginfo) |
757 | { |
758 | g_return_val_if_fail(siginfo != NULL, NULL); |
759 | |
760 | return siginfo->local_signing_time; |
761 | } |
762 | |
763 | /* Text Field */ |
764 | /** |
765 | * poppler_form_field_text_get_text_type: |
766 | * @field: a #PopplerFormField |
767 | * |
768 | * Gets the text type of @field. |
769 | * |
770 | * Return value: #PopplerFormTextType of @field |
771 | **/ |
772 | PopplerFormTextType poppler_form_field_text_get_text_type(PopplerFormField *field) |
773 | { |
774 | FormWidgetText *text_field; |
775 | |
776 | g_return_val_if_fail(field->widget->getType() == formText, POPPLER_FORM_TEXT_NORMAL); |
777 | |
778 | text_field = static_cast<FormWidgetText *>(field->widget); |
779 | |
780 | if (text_field->isMultiline()) { |
781 | return POPPLER_FORM_TEXT_MULTILINE; |
782 | } else if (text_field->isFileSelect()) { |
783 | return POPPLER_FORM_TEXT_FILE_SELECT; |
784 | } |
785 | |
786 | return POPPLER_FORM_TEXT_NORMAL; |
787 | } |
788 | |
789 | /** |
790 | * poppler_form_field_text_get_text: |
791 | * @field: a #PopplerFormField |
792 | * |
793 | * Retrieves the contents of @field. |
794 | * |
795 | * Return value: a new allocated string. It must be freed with g_free() when done. |
796 | **/ |
797 | gchar *poppler_form_field_text_get_text(PopplerFormField *field) |
798 | { |
799 | FormWidgetText *text_field; |
800 | const GooString *tmp; |
801 | |
802 | g_return_val_if_fail(field->widget->getType() == formText, NULL); |
803 | |
804 | text_field = static_cast<FormWidgetText *>(field->widget); |
805 | tmp = text_field->getContent(); |
806 | |
807 | return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr; |
808 | } |
809 | |
810 | /** |
811 | * poppler_form_field_text_set_text: |
812 | * @field: a #PopplerFormField |
813 | * @text: the new text |
814 | * |
815 | * Sets the text in @field to the given value, replacing the current contents. |
816 | **/ |
817 | void poppler_form_field_text_set_text(PopplerFormField *field, const gchar *text) |
818 | { |
819 | GooString *goo_tmp; |
820 | gchar *tmp; |
821 | gsize length = 0; |
822 | |
823 | g_return_if_fail(field->widget->getType() == formText); |
824 | |
825 | tmp = text ? g_convert(str: text, len: -1, to_codeset: "UTF-16BE" , from_codeset: "UTF-8" , bytes_read: nullptr, bytes_written: &length, error: nullptr) : nullptr; |
826 | goo_tmp = new GooString(tmp, length); |
827 | g_free(mem: tmp); |
828 | static_cast<FormWidgetText *>(field->widget)->setContent(goo_tmp); |
829 | delete goo_tmp; |
830 | } |
831 | |
832 | /** |
833 | * poppler_form_field_text_get_max_len: |
834 | * @field: a #PopplerFormField |
835 | * |
836 | * Retrieves the maximum allowed length of the text in @field |
837 | * |
838 | * Return value: the maximum allowed number of characters in @field, or -1 if there is no maximum. |
839 | **/ |
840 | gint poppler_form_field_text_get_max_len(PopplerFormField *field) |
841 | { |
842 | g_return_val_if_fail(field->widget->getType() == formText, 0); |
843 | |
844 | return static_cast<FormWidgetText *>(field->widget)->getMaxLen(); |
845 | } |
846 | |
847 | /** |
848 | * poppler_form_field_text_do_spell_check: |
849 | * @field: a #PopplerFormField |
850 | * |
851 | * Checks whether spell checking should be done for the contents of @field |
852 | * |
853 | * Return value: %TRUE if spell checking should be done for @field |
854 | **/ |
855 | gboolean poppler_form_field_text_do_spell_check(PopplerFormField *field) |
856 | { |
857 | g_return_val_if_fail(field->widget->getType() == formText, FALSE); |
858 | |
859 | return !static_cast<FormWidgetText *>(field->widget)->noSpellCheck(); |
860 | } |
861 | |
862 | gboolean poppler_form_field_text_do_scroll(PopplerFormField *field) |
863 | { |
864 | g_return_val_if_fail(field->widget->getType() == formText, FALSE); |
865 | |
866 | return !static_cast<FormWidgetText *>(field->widget)->noScroll(); |
867 | } |
868 | |
869 | /** |
870 | * poppler_form_field_text_is_rich_text: |
871 | * @field: a #PopplerFormField |
872 | * |
873 | * Checks whether the contents of @field are rich text |
874 | * |
875 | * Return value: %TRUE if the contents of @field are rich text |
876 | **/ |
877 | gboolean poppler_form_field_text_is_rich_text(PopplerFormField *field) |
878 | { |
879 | g_return_val_if_fail(field->widget->getType() == formText, FALSE); |
880 | |
881 | return static_cast<FormWidgetText *>(field->widget)->isRichText(); |
882 | } |
883 | |
884 | /** |
885 | * poppler_form_field_text_is_password: |
886 | * @field: a #PopplerFormField |
887 | * |
888 | * Checks whether content of @field is a password and it must be hidden |
889 | * |
890 | * Return value: %TRUE if the content of @field is a password |
891 | **/ |
892 | gboolean poppler_form_field_text_is_password(PopplerFormField *field) |
893 | { |
894 | g_return_val_if_fail(field->widget->getType() == formText, FALSE); |
895 | |
896 | return static_cast<FormWidgetText *>(field->widget)->isPassword(); |
897 | } |
898 | |
899 | /* Choice Field */ |
900 | /** |
901 | * poppler_form_field_choice_get_choice_type: |
902 | * @field: a #PopplerFormField |
903 | * |
904 | * Gets the choice type of @field |
905 | * |
906 | * Return value: #PopplerFormChoiceType of @field |
907 | **/ |
908 | PopplerFormChoiceType poppler_form_field_choice_get_choice_type(PopplerFormField *field) |
909 | { |
910 | g_return_val_if_fail(field->widget->getType() == formChoice, POPPLER_FORM_CHOICE_COMBO); |
911 | |
912 | if (static_cast<FormWidgetChoice *>(field->widget)->isCombo()) { |
913 | return POPPLER_FORM_CHOICE_COMBO; |
914 | } else { |
915 | return POPPLER_FORM_CHOICE_LIST; |
916 | } |
917 | } |
918 | |
919 | /** |
920 | * poppler_form_field_choice_is_editable: |
921 | * @field: a #PopplerFormField |
922 | * |
923 | * Checks whether @field is editable |
924 | * |
925 | * Return value: %TRUE if @field is editable |
926 | **/ |
927 | gboolean poppler_form_field_choice_is_editable(PopplerFormField *field) |
928 | { |
929 | g_return_val_if_fail(field->widget->getType() == formChoice, FALSE); |
930 | |
931 | return static_cast<FormWidgetChoice *>(field->widget)->hasEdit(); |
932 | } |
933 | |
934 | /** |
935 | * poppler_form_field_choice_can_select_multiple: |
936 | * @field: a #PopplerFormField |
937 | * |
938 | * Checks whether @field allows multiple choices to be selected |
939 | * |
940 | * Return value: %TRUE if @field allows multiple choices to be selected |
941 | **/ |
942 | gboolean poppler_form_field_choice_can_select_multiple(PopplerFormField *field) |
943 | { |
944 | g_return_val_if_fail(field->widget->getType() == formChoice, FALSE); |
945 | |
946 | return static_cast<FormWidgetChoice *>(field->widget)->isMultiSelect(); |
947 | } |
948 | |
949 | /** |
950 | * poppler_form_field_choice_do_spell_check: |
951 | * @field: a #PopplerFormField |
952 | * |
953 | * Checks whether spell checking should be done for the contents of @field |
954 | * |
955 | * Return value: %TRUE if spell checking should be done for @field |
956 | **/ |
957 | gboolean poppler_form_field_choice_do_spell_check(PopplerFormField *field) |
958 | { |
959 | g_return_val_if_fail(field->widget->getType() == formChoice, FALSE); |
960 | |
961 | return !static_cast<FormWidgetChoice *>(field->widget)->noSpellCheck(); |
962 | } |
963 | |
964 | gboolean poppler_form_field_choice_commit_on_change(PopplerFormField *field) |
965 | { |
966 | g_return_val_if_fail(field->widget->getType() == formChoice, FALSE); |
967 | |
968 | return static_cast<FormWidgetChoice *>(field->widget)->commitOnSelChange(); |
969 | } |
970 | |
971 | /** |
972 | * poppler_form_field_choice_get_n_items: |
973 | * @field: a #PopplerFormField |
974 | * |
975 | * Returns the number of items on @field |
976 | * |
977 | * Return value: the number of items on @field |
978 | **/ |
979 | gint poppler_form_field_choice_get_n_items(PopplerFormField *field) |
980 | { |
981 | g_return_val_if_fail(field->widget->getType() == formChoice, -1); |
982 | |
983 | return static_cast<FormWidgetChoice *>(field->widget)->getNumChoices(); |
984 | } |
985 | |
986 | /** |
987 | * poppler_form_field_choice_get_item: |
988 | * @field: a #PopplerFormField |
989 | * @index: the index of the item |
990 | * |
991 | * Returns the contents of the item on @field at the given index |
992 | * |
993 | * Return value: a new allocated string. It must be freed with g_free() when done. |
994 | **/ |
995 | gchar *poppler_form_field_choice_get_item(PopplerFormField *field, gint index) |
996 | { |
997 | const GooString *tmp; |
998 | |
999 | g_return_val_if_fail(field->widget->getType() == formChoice, NULL); |
1000 | g_return_val_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field), NULL); |
1001 | |
1002 | tmp = static_cast<FormWidgetChoice *>(field->widget)->getChoice(i: index); |
1003 | return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr; |
1004 | } |
1005 | |
1006 | /** |
1007 | * poppler_form_field_choice_is_item_selected: |
1008 | * @field: a #PopplerFormField |
1009 | * @index: the index of the item |
1010 | * |
1011 | * Checks whether the item at the given index on @field is currently selected |
1012 | * |
1013 | * Return value: %TRUE if item at @index is currently selected |
1014 | **/ |
1015 | gboolean poppler_form_field_choice_is_item_selected(PopplerFormField *field, gint index) |
1016 | { |
1017 | g_return_val_if_fail(field->widget->getType() == formChoice, FALSE); |
1018 | g_return_val_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field), FALSE); |
1019 | |
1020 | return static_cast<FormWidgetChoice *>(field->widget)->isSelected(i: index); |
1021 | } |
1022 | |
1023 | /** |
1024 | * poppler_form_field_choice_select_item: |
1025 | * @field: a #PopplerFormField |
1026 | * @index: the index of the item |
1027 | * |
1028 | * Selects the item at the given index on @field |
1029 | **/ |
1030 | void poppler_form_field_choice_select_item(PopplerFormField *field, gint index) |
1031 | { |
1032 | g_return_if_fail(field->widget->getType() == formChoice); |
1033 | g_return_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field)); |
1034 | |
1035 | static_cast<FormWidgetChoice *>(field->widget)->select(i: index); |
1036 | } |
1037 | |
1038 | /** |
1039 | * poppler_form_field_choice_unselect_all: |
1040 | * @field: a #PopplerFormField |
1041 | * |
1042 | * Unselects all the items on @field |
1043 | **/ |
1044 | void poppler_form_field_choice_unselect_all(PopplerFormField *field) |
1045 | { |
1046 | g_return_if_fail(field->widget->getType() == formChoice); |
1047 | |
1048 | static_cast<FormWidgetChoice *>(field->widget)->deselectAll(); |
1049 | } |
1050 | |
1051 | /** |
1052 | * poppler_form_field_choice_toggle_item: |
1053 | * @field: a #PopplerFormField |
1054 | * @index: the index of the item |
1055 | * |
1056 | * Changes the state of the item at the given index |
1057 | **/ |
1058 | void poppler_form_field_choice_toggle_item(PopplerFormField *field, gint index) |
1059 | { |
1060 | g_return_if_fail(field->widget->getType() == formChoice); |
1061 | g_return_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field)); |
1062 | |
1063 | static_cast<FormWidgetChoice *>(field->widget)->toggle(i: index); |
1064 | } |
1065 | |
1066 | /** |
1067 | * poppler_form_field_choice_set_text: |
1068 | * @field: a #PopplerFormField |
1069 | * @text: the new text |
1070 | * |
1071 | * Sets the text in @field to the given value, replacing the current contents |
1072 | **/ |
1073 | void poppler_form_field_choice_set_text(PopplerFormField *field, const gchar *text) |
1074 | { |
1075 | GooString *goo_tmp; |
1076 | gchar *tmp; |
1077 | gsize length = 0; |
1078 | |
1079 | g_return_if_fail(field->widget->getType() == formChoice); |
1080 | |
1081 | tmp = text ? g_convert(str: text, len: -1, to_codeset: "UTF-16BE" , from_codeset: "UTF-8" , bytes_read: nullptr, bytes_written: &length, error: nullptr) : nullptr; |
1082 | goo_tmp = new GooString(tmp, length); |
1083 | g_free(mem: tmp); |
1084 | static_cast<FormWidgetChoice *>(field->widget)->setEditChoice(goo_tmp); |
1085 | delete goo_tmp; |
1086 | } |
1087 | |
1088 | /** |
1089 | * poppler_form_field_choice_get_text: |
1090 | * @field: a #PopplerFormField |
1091 | * |
1092 | * Retrieves the contents of @field. |
1093 | * |
1094 | * Return value: a new allocated string. It must be freed with g_free() when done. |
1095 | **/ |
1096 | gchar *poppler_form_field_choice_get_text(PopplerFormField *field) |
1097 | { |
1098 | const GooString *tmp; |
1099 | |
1100 | g_return_val_if_fail(field->widget->getType() == formChoice, NULL); |
1101 | |
1102 | tmp = static_cast<FormWidgetChoice *>(field->widget)->getEditChoice(); |
1103 | return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr; |
1104 | } |
1105 | |
1106 | /* Signing Data */ |
1107 | |
1108 | struct _PopplerSigningData |
1109 | { |
1110 | char *destination_filename; |
1111 | PopplerCertificateInfo *certificate_info; |
1112 | int page; |
1113 | |
1114 | char *signature_text; |
1115 | char *signature_text_left; |
1116 | PopplerRectangle signature_rect; |
1117 | |
1118 | PopplerColor font_color; |
1119 | gdouble font_size; |
1120 | gdouble left_font_size; |
1121 | |
1122 | PopplerColor border_color; |
1123 | gdouble border_width; |
1124 | |
1125 | PopplerColor background_color; |
1126 | |
1127 | char *field_partial_name; |
1128 | char *reason; |
1129 | char *location; |
1130 | char *image_path; |
1131 | char *password; |
1132 | char *document_owner_password; |
1133 | char *document_user_password; |
1134 | }; |
1135 | |
1136 | typedef struct _PopplerSigningData PopplerSigningData; |
1137 | |
1138 | G_DEFINE_BOXED_TYPE(PopplerSigningData, poppler_signing_data, poppler_signing_data_copy, poppler_signing_data_free) |
1139 | |
1140 | /** |
1141 | * poppler_signing_data_new: |
1142 | * |
1143 | * Creates a new #PopplerSigningData with default content. |
1144 | * |
1145 | * Return value: a new #PopplerSigningData. It must be freed with poppler_signing_data_free() when done. |
1146 | * |
1147 | * Since: 23.07.0 |
1148 | **/ |
1149 | PopplerSigningData *poppler_signing_data_new(void) |
1150 | { |
1151 | PopplerSigningData *data = (PopplerSigningData *)g_malloc0(n_bytes: sizeof(PopplerSigningData)); |
1152 | |
1153 | data->password = g_strdup(str: "" ); |
1154 | data->page = 0; |
1155 | |
1156 | data->font_size = 10.0; |
1157 | data->left_font_size = 20.0; |
1158 | data->border_width = 1.5; |
1159 | |
1160 | /* Grey background */ |
1161 | auto background_color = PopplerColor(); |
1162 | background_color.red = 0xEF; |
1163 | background_color.green = 0xEF; |
1164 | background_color.blue = 0xEF; |
1165 | poppler_signing_data_set_background_color(signing_data: data, background_color: &background_color); |
1166 | |
1167 | /* Red border color */ |
1168 | auto border_color = PopplerColor(); |
1169 | border_color.red = 0xFF; |
1170 | border_color.green = 0x00; |
1171 | border_color.blue = 0x00; |
1172 | poppler_signing_data_set_border_color(signing_data: data, border_color: &border_color); |
1173 | |
1174 | /* Red font color */ |
1175 | auto font_color = PopplerColor(); |
1176 | font_color.red = 0xFF; |
1177 | font_color.green = 0x00; |
1178 | border_color.blue = 0x00; |
1179 | poppler_signing_data_set_font_color(signing_data: data, font_color: &font_color); |
1180 | |
1181 | return data; |
1182 | } |
1183 | |
1184 | /** |
1185 | * poppler_signing_data_copy: |
1186 | * @signing_data: a #PopplerSigningData structure containing signing data |
1187 | * |
1188 | * Copies @signing_data, creating an identical #PopplerSigningData. |
1189 | * |
1190 | * Return value: (transfer full): a new #PopplerSigningData structure identical to @signing_data |
1191 | * |
1192 | * Since: 23.07.0 |
1193 | **/ |
1194 | PopplerSigningData *poppler_signing_data_copy(const PopplerSigningData *signing_data) |
1195 | { |
1196 | PopplerSigningData *data; |
1197 | |
1198 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1199 | |
1200 | data = (PopplerSigningData *)g_malloc0(n_bytes: sizeof(PopplerSigningData)); |
1201 | data->destination_filename = g_strdup(str: signing_data->destination_filename); |
1202 | data->certificate_info = poppler_certificate_info_copy(certificate_info: signing_data->certificate_info); |
1203 | data->page = signing_data->page; |
1204 | |
1205 | data->signature_text = g_strdup(str: signing_data->signature_text); |
1206 | data->signature_text_left = g_strdup(str: signing_data->signature_text_left); |
1207 | memcpy(dest: &data->signature_rect, src: &signing_data->signature_rect, n: sizeof(PopplerRectangle)); |
1208 | |
1209 | memcpy(dest: &data->font_color, src: &signing_data->font_color, n: sizeof(PopplerColor)); |
1210 | data->font_size = signing_data->font_size; |
1211 | data->left_font_size = signing_data->left_font_size; |
1212 | |
1213 | memcpy(dest: &data->border_color, src: &signing_data->border_color, n: sizeof(PopplerColor)); |
1214 | data->border_width = signing_data->border_width; |
1215 | |
1216 | memcpy(dest: &data->background_color, src: &signing_data->background_color, n: sizeof(PopplerColor)); |
1217 | |
1218 | data->field_partial_name = g_strdup(str: signing_data->field_partial_name); |
1219 | data->reason = g_strdup(str: signing_data->reason); |
1220 | data->location = g_strdup(str: signing_data->location); |
1221 | data->image_path = g_strdup(str: signing_data->image_path); |
1222 | data->password = g_strdup(str: signing_data->password); |
1223 | data->document_owner_password = g_strdup(str: signing_data->document_owner_password); |
1224 | data->document_user_password = g_strdup(str: signing_data->document_user_password); |
1225 | |
1226 | return data; |
1227 | } |
1228 | |
1229 | /** |
1230 | * poppler_signing_data_free: |
1231 | * @signing_data: (nullable): a #PopplerSigningData structure containing signing data |
1232 | * |
1233 | * Frees @signing_data |
1234 | * |
1235 | * Since: 23.07.0 |
1236 | **/ |
1237 | void poppler_signing_data_free(PopplerSigningData *signing_data) |
1238 | { |
1239 | if (!signing_data) { |
1240 | return; |
1241 | } |
1242 | |
1243 | g_clear_pointer(&signing_data->destination_filename, g_free); |
1244 | g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free); |
1245 | g_clear_pointer(&signing_data->signature_text, g_free); |
1246 | g_clear_pointer(&signing_data->signature_text_left, g_free); |
1247 | g_clear_pointer(&signing_data->field_partial_name, g_free); |
1248 | g_clear_pointer(&signing_data->reason, g_free); |
1249 | g_clear_pointer(&signing_data->location, g_free); |
1250 | g_clear_pointer(&signing_data->image_path, g_free); |
1251 | |
1252 | if (signing_data->password) { |
1253 | #ifdef HAVE_EXPLICIT_BZERO |
1254 | explicit_bzero(signing_data->password, strlen(signing_data->password)); |
1255 | #else |
1256 | memset(s: signing_data->password, c: 0, n: strlen(s: signing_data->password)); |
1257 | #endif |
1258 | g_clear_pointer(&signing_data->password, g_free); |
1259 | } |
1260 | |
1261 | if (signing_data->document_owner_password) { |
1262 | #ifdef HAVE_EXPLICIT_BZERO |
1263 | explicit_bzero(signing_data->document_owner_password, strlen(signing_data->document_owner_password)); |
1264 | #else |
1265 | memset(s: signing_data->document_owner_password, c: 0, n: strlen(s: signing_data->document_owner_password)); |
1266 | #endif |
1267 | g_clear_pointer(&signing_data->document_owner_password, g_free); |
1268 | } |
1269 | |
1270 | if (signing_data->document_user_password) { |
1271 | #ifdef HAVE_EXPLICIT_BZERO |
1272 | explicit_bzero(signing_data->document_user_password, strlen(signing_data->document_user_password)); |
1273 | #else |
1274 | memset(s: signing_data->document_user_password, c: 0, n: strlen(s: signing_data->document_user_password)); |
1275 | #endif |
1276 | g_clear_pointer(&signing_data->document_user_password, g_free); |
1277 | } |
1278 | |
1279 | g_free(mem: signing_data); |
1280 | } |
1281 | |
1282 | /** |
1283 | * poppler_signing_data_set_destination_filename: |
1284 | * @signing_data: a #PopplerSigningData structure containing signing data |
1285 | * @filename: destination filename |
1286 | * |
1287 | * Set destination file name. |
1288 | * |
1289 | * Since: 23.07.0 |
1290 | **/ |
1291 | void poppler_signing_data_set_destination_filename(PopplerSigningData *signing_data, const gchar *filename) |
1292 | { |
1293 | g_return_if_fail(signing_data != nullptr); |
1294 | g_return_if_fail(filename != nullptr); |
1295 | |
1296 | if (signing_data->destination_filename == filename) { |
1297 | return; |
1298 | } |
1299 | |
1300 | g_clear_pointer(&signing_data->destination_filename, g_free); |
1301 | signing_data->destination_filename = g_strdup(str: filename); |
1302 | } |
1303 | |
1304 | /** |
1305 | * poppler_signing_data_get_destination_filename: |
1306 | * @signing_data: a #PopplerSigningData structure containing signing data |
1307 | * |
1308 | * Get destination file name. |
1309 | * |
1310 | * Return value: destination filename |
1311 | * |
1312 | * Since: 23.07.0 |
1313 | **/ |
1314 | const gchar *poppler_signing_data_get_destination_filename(const PopplerSigningData *signing_data) |
1315 | { |
1316 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1317 | |
1318 | return signing_data->destination_filename; |
1319 | } |
1320 | |
1321 | /** |
1322 | * poppler_signing_data_set_certificate_info: |
1323 | * @signing_data: a #PopplerSigningData structure containing signing data |
1324 | * @certificate_info: a #PopplerCertificateInfo |
1325 | * |
1326 | * Set certification information. |
1327 | * |
1328 | * Since: 23.07.0 |
1329 | **/ |
1330 | void poppler_signing_data_set_certificate_info(PopplerSigningData *signing_data, const PopplerCertificateInfo *certificate_info) |
1331 | { |
1332 | g_return_if_fail(signing_data != nullptr); |
1333 | g_return_if_fail(certificate_info != nullptr); |
1334 | |
1335 | if (signing_data->certificate_info == certificate_info) { |
1336 | return; |
1337 | } |
1338 | |
1339 | g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free); |
1340 | signing_data->certificate_info = poppler_certificate_info_copy(certificate_info); |
1341 | } |
1342 | |
1343 | /** |
1344 | * poppler_signing_data_get_certificate_info: |
1345 | * @signing_data: a #PopplerSigningData structure containing signing data |
1346 | * |
1347 | * Get certification information. |
1348 | * |
1349 | * Return value: a #PopplerCertificateInfo |
1350 | * |
1351 | * Since: 23.07.0 |
1352 | **/ |
1353 | const PopplerCertificateInfo *poppler_signing_data_get_certificate_info(const PopplerSigningData *signing_data) |
1354 | { |
1355 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1356 | return signing_data->certificate_info; |
1357 | } |
1358 | |
1359 | /** |
1360 | * poppler_signing_data_set_page: |
1361 | * @signing_data: a #PopplerSigningData structure containing signing data |
1362 | * @page: a page number |
1363 | * |
1364 | * Set page (>=0). |
1365 | * |
1366 | * Since: 23.07.0 |
1367 | **/ |
1368 | void poppler_signing_data_set_page(PopplerSigningData *signing_data, int page) |
1369 | { |
1370 | g_return_if_fail(signing_data != nullptr); |
1371 | |
1372 | if (page < 0) { |
1373 | return; |
1374 | } |
1375 | |
1376 | signing_data->page = page; |
1377 | } |
1378 | |
1379 | /** |
1380 | * poppler_signing_data_get_page: |
1381 | * @signing_data: a #PopplerSigningData structure containing signing data |
1382 | * |
1383 | * Get page. |
1384 | * |
1385 | * Return value: page number |
1386 | * |
1387 | * Since: 23.07.0 |
1388 | **/ |
1389 | int poppler_signing_data_get_page(const PopplerSigningData *signing_data) |
1390 | { |
1391 | g_return_val_if_fail(signing_data != nullptr, 0); |
1392 | return signing_data->page; |
1393 | } |
1394 | |
1395 | /** |
1396 | * poppler_signing_data_set_signature_text: |
1397 | * @signing_data: a #PopplerSigningData structure containing signing data |
1398 | * @signature_text: text to show as main signature |
1399 | * |
1400 | * Set signature text. |
1401 | * |
1402 | * Since: 23.07.0 |
1403 | **/ |
1404 | void poppler_signing_data_set_signature_text(PopplerSigningData *signing_data, const gchar *signature_text) |
1405 | { |
1406 | g_return_if_fail(signing_data != nullptr); |
1407 | g_return_if_fail(signature_text != nullptr); |
1408 | |
1409 | if (signing_data->signature_text == signature_text) { |
1410 | return; |
1411 | } |
1412 | |
1413 | g_clear_pointer(&signing_data->signature_text, g_free); |
1414 | signing_data->signature_text = g_strdup(str: signature_text); |
1415 | } |
1416 | |
1417 | /** |
1418 | * poppler_signing_data_get_signature_text: |
1419 | * @signing_data: a #PopplerSigningData structure containing signing data |
1420 | * |
1421 | * Get signature text. |
1422 | * |
1423 | * Return value: signature text |
1424 | * |
1425 | * Since: 23.07.0 |
1426 | **/ |
1427 | const gchar *poppler_signing_data_get_signature_text(const PopplerSigningData *signing_data) |
1428 | { |
1429 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1430 | return signing_data->signature_text; |
1431 | } |
1432 | |
1433 | /** |
1434 | * poppler_signing_data_set_signature_text_left: |
1435 | * @signing_data: a #PopplerSigningData structure containing signing data |
1436 | * @signature_text_left: text to show as small left signature |
1437 | * |
1438 | * Set small signature text on the left hand. |
1439 | * |
1440 | * Since: 23.07.0 |
1441 | **/ |
1442 | void poppler_signing_data_set_signature_text_left(PopplerSigningData *signing_data, const gchar *signature_text_left) |
1443 | { |
1444 | g_return_if_fail(signing_data != nullptr); |
1445 | g_return_if_fail(signature_text_left != nullptr); |
1446 | |
1447 | if (signing_data->signature_text_left == signature_text_left) { |
1448 | return; |
1449 | } |
1450 | |
1451 | g_clear_pointer(&signing_data->signature_text_left, g_free); |
1452 | signing_data->signature_text_left = g_strdup(str: signature_text_left); |
1453 | } |
1454 | |
1455 | /** |
1456 | * poppler_signing_data_get_signature_text_left: |
1457 | * @signing_data: a #PopplerSigningData structure containing signing data |
1458 | * |
1459 | * Get signature text left. |
1460 | * |
1461 | * Return value: signature text left |
1462 | * |
1463 | * Since: 23.07.0 |
1464 | **/ |
1465 | const gchar *poppler_signing_data_get_signature_text_left(const PopplerSigningData *signing_data) |
1466 | { |
1467 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1468 | return signing_data->signature_text_left; |
1469 | } |
1470 | |
1471 | /** |
1472 | * poppler_signing_data_set_signature_rectangle: |
1473 | * @signing_data: a #PopplerSigningData structure containing signing data |
1474 | * @signature_rect: a #PopplerRectangle where signature should be shown |
1475 | * |
1476 | * Set signature rectangle. |
1477 | * |
1478 | * Since: 23.07.0 |
1479 | **/ |
1480 | void poppler_signing_data_set_signature_rectangle(PopplerSigningData *signing_data, const PopplerRectangle *signature_rect) |
1481 | { |
1482 | g_return_if_fail(signing_data != nullptr); |
1483 | g_return_if_fail(signature_rect != nullptr); |
1484 | |
1485 | memcpy(dest: &signing_data->signature_rect, src: signature_rect, n: sizeof(PopplerRectangle)); |
1486 | } |
1487 | |
1488 | /** |
1489 | * poppler_signing_data_get_signature_rectangle: |
1490 | * @signing_data: a #PopplerSigningData structure containing signing data |
1491 | * |
1492 | * Get signature rectangle. |
1493 | * |
1494 | * Return value: a #PopplerRectangle |
1495 | * |
1496 | * Since: 23.07.0 |
1497 | **/ |
1498 | const PopplerRectangle *poppler_signing_data_get_signature_rectangle(const PopplerSigningData *signing_data) |
1499 | { |
1500 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1501 | return &signing_data->signature_rect; |
1502 | } |
1503 | |
1504 | /** |
1505 | * poppler_signing_data_set_font_color: |
1506 | * @signing_data: a #PopplerSigningData structure containing signing data |
1507 | * @font_color: a #PopplerColor to be used as signature font color |
1508 | * |
1509 | * Set signature font color. |
1510 | * |
1511 | * Since: 23.07.0 |
1512 | **/ |
1513 | void poppler_signing_data_set_font_color(PopplerSigningData *signing_data, const PopplerColor *font_color) |
1514 | { |
1515 | g_return_if_fail(signing_data != nullptr); |
1516 | g_return_if_fail(font_color != nullptr); |
1517 | |
1518 | memcpy(dest: &signing_data->font_color, src: font_color, n: sizeof(PopplerColor)); |
1519 | } |
1520 | |
1521 | /** |
1522 | * poppler_signing_data_get_font_color: |
1523 | * @signing_data: a #PopplerSigningData structure containing signing data |
1524 | * |
1525 | * Get signature font color. |
1526 | * |
1527 | * Return value: a #PopplerColor |
1528 | * |
1529 | * Since: 23.07.0 |
1530 | **/ |
1531 | const PopplerColor *poppler_signing_data_get_font_color(const PopplerSigningData *signing_data) |
1532 | { |
1533 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1534 | return &signing_data->font_color; |
1535 | } |
1536 | |
1537 | /** |
1538 | * poppler_signing_data_set_font_size: |
1539 | * @signing_data: a #PopplerSigningData structure containing signing data |
1540 | * @font_size: signature font size |
1541 | * |
1542 | * Set signature font size (>0). |
1543 | * |
1544 | * Since: 23.07.0 |
1545 | **/ |
1546 | void poppler_signing_data_set_font_size(PopplerSigningData *signing_data, gdouble font_size) |
1547 | { |
1548 | g_return_if_fail(signing_data != nullptr); |
1549 | |
1550 | if (font_size <= 0) { |
1551 | return; |
1552 | } |
1553 | |
1554 | signing_data->font_size = font_size; |
1555 | } |
1556 | |
1557 | /** |
1558 | * poppler_signing_data_get_font_size: |
1559 | * @signing_data: a #PopplerSigningData structure containing signing data |
1560 | * |
1561 | * Get signature font size. |
1562 | * |
1563 | * Return value: font size |
1564 | * |
1565 | * Since: 23.07.0 |
1566 | **/ |
1567 | gdouble poppler_signing_data_get_font_size(const PopplerSigningData *signing_data) |
1568 | { |
1569 | g_return_val_if_fail(signing_data != nullptr, 20.0f); |
1570 | return signing_data->font_size; |
1571 | } |
1572 | |
1573 | /** |
1574 | * poppler_signing_data_set_left_font_size: |
1575 | * @signing_data: a #PopplerSigningData structure containing signing data |
1576 | * @font_size: signature font size |
1577 | * |
1578 | * Set signature left font size (> 0). |
1579 | * |
1580 | * Since: 23.07.0 |
1581 | **/ |
1582 | void poppler_signing_data_set_left_font_size(PopplerSigningData *signing_data, gdouble left_font_size) |
1583 | { |
1584 | g_return_if_fail(signing_data != nullptr); |
1585 | |
1586 | if (left_font_size <= 0) { |
1587 | return; |
1588 | } |
1589 | |
1590 | signing_data->left_font_size = left_font_size; |
1591 | } |
1592 | |
1593 | /** |
1594 | * poppler_signing_data_get_left_font_size: |
1595 | * @signing_data: a #PopplerSigningData structure containing signing data |
1596 | * |
1597 | * Get signature left font size. |
1598 | * |
1599 | * Return value: left font size |
1600 | * |
1601 | * Since: 23.07.0 |
1602 | **/ |
1603 | gdouble poppler_signing_data_get_left_font_size(const PopplerSigningData *signing_data) |
1604 | { |
1605 | g_return_val_if_fail(signing_data != nullptr, 12.0); |
1606 | return signing_data->left_font_size; |
1607 | } |
1608 | |
1609 | /** |
1610 | * poppler_signing_data_set_border_color: |
1611 | * @signing_data: a #PopplerSigningData structure containing signing data |
1612 | * @border_color: a #PopplerColor to be used for signature border |
1613 | * |
1614 | * Set signature border color. |
1615 | * |
1616 | * Since: 23.07.0 |
1617 | **/ |
1618 | void poppler_signing_data_set_border_color(PopplerSigningData *signing_data, const PopplerColor *border_color) |
1619 | { |
1620 | g_return_if_fail(signing_data != nullptr); |
1621 | g_return_if_fail(border_color != nullptr); |
1622 | |
1623 | memcpy(dest: &signing_data->border_color, src: border_color, n: sizeof(PopplerColor)); |
1624 | } |
1625 | |
1626 | /** |
1627 | * poppler_signing_data_get_border_color: |
1628 | * @signing_data: a #PopplerSigningData structure containing signing data |
1629 | * |
1630 | * Get signature border color. |
1631 | * |
1632 | * Return value: a #PopplerColor |
1633 | * |
1634 | * Since: 23.07.0 |
1635 | **/ |
1636 | const PopplerColor *poppler_signing_data_get_border_color(const PopplerSigningData *signing_data) |
1637 | { |
1638 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1639 | return &signing_data->border_color; |
1640 | } |
1641 | |
1642 | /** |
1643 | * poppler_signing_data_set_border_width: |
1644 | * @signing_data: a #PopplerSigningData structure containing signing data |
1645 | * @border_width: border width |
1646 | * |
1647 | * Set signature border width. |
1648 | * |
1649 | * Since: 23.07.0 |
1650 | **/ |
1651 | void poppler_signing_data_set_border_width(PopplerSigningData *signing_data, gdouble border_width) |
1652 | { |
1653 | g_return_if_fail(signing_data != nullptr); |
1654 | |
1655 | if (border_width < 0) { |
1656 | return; |
1657 | } |
1658 | |
1659 | signing_data->border_width = border_width; |
1660 | } |
1661 | |
1662 | /** |
1663 | * poppler_signing_data_get_border_width: |
1664 | * @signing_data: a #PopplerSigningData structure containing signing data |
1665 | * |
1666 | * Get signature border width. |
1667 | * |
1668 | * Return value: border width |
1669 | * |
1670 | * Since: 23.07.0 |
1671 | **/ |
1672 | gdouble poppler_signing_data_get_border_width(const PopplerSigningData *signing_data) |
1673 | { |
1674 | g_return_val_if_fail(signing_data != nullptr, 12); |
1675 | return signing_data->border_width; |
1676 | } |
1677 | |
1678 | /** |
1679 | * poppler_signing_data_set_background_color: |
1680 | * @signing_data: a #PopplerSigningData structure containing signing data |
1681 | * @background_color: a #PopplerColor to be used for signature background |
1682 | * |
1683 | * Set signature background color. |
1684 | * |
1685 | * Since: 23.07.0 |
1686 | **/ |
1687 | void poppler_signing_data_set_background_color(PopplerSigningData *signing_data, const PopplerColor *background_color) |
1688 | { |
1689 | g_return_if_fail(signing_data != nullptr); |
1690 | g_return_if_fail(background_color != nullptr); |
1691 | |
1692 | memcpy(dest: &signing_data->background_color, src: background_color, n: sizeof(PopplerColor)); |
1693 | } |
1694 | |
1695 | /** |
1696 | * poppler_signing_data_get_background_color: |
1697 | * @signing_data: a #PopplerSigningData structure containing signing data |
1698 | * |
1699 | * Get signature background color. |
1700 | * |
1701 | * Return value: a #PopplerColor |
1702 | * |
1703 | * Since: 23.07.0 |
1704 | **/ |
1705 | const PopplerColor *poppler_signing_data_get_background_color(const PopplerSigningData *signing_data) |
1706 | { |
1707 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1708 | return &signing_data->background_color; |
1709 | } |
1710 | |
1711 | /** |
1712 | * poppler_signing_data_set_field_partial_name: |
1713 | * @signing_data: a #PopplerSigningData structure containing signing data |
1714 | * @field_partial_name: a field partial name |
1715 | * |
1716 | * Set field partial name (existing field id or a new one) where signature is placed. |
1717 | * |
1718 | * Since: 23.07.0 |
1719 | **/ |
1720 | void poppler_signing_data_set_field_partial_name(PopplerSigningData *signing_data, const gchar *field_partial_name) |
1721 | { |
1722 | g_return_if_fail(signing_data != nullptr); |
1723 | g_return_if_fail(field_partial_name != nullptr); |
1724 | |
1725 | g_clear_pointer(&signing_data->field_partial_name, g_free); |
1726 | signing_data->field_partial_name = g_strdup(str: field_partial_name); |
1727 | } |
1728 | |
1729 | /** |
1730 | * poppler_signing_data_get_field_partial_name: |
1731 | * @signing_data: a #PopplerSigningData structure containing signing data |
1732 | * |
1733 | * Get field partial name. |
1734 | * |
1735 | * Return value: field partial name |
1736 | * |
1737 | * Since: 23.07.0 |
1738 | **/ |
1739 | const gchar *poppler_signing_data_get_field_partial_name(const PopplerSigningData *signing_data) |
1740 | { |
1741 | g_return_val_if_fail(signing_data != nullptr, "" ); |
1742 | return signing_data->field_partial_name; |
1743 | } |
1744 | |
1745 | /** |
1746 | * poppler_signing_data_set_reason: |
1747 | * @signing_data: a #PopplerSigningData structure containing signing data |
1748 | * @reason: a reason |
1749 | * |
1750 | * Set reason for signature (e.g. I'm approver). |
1751 | * |
1752 | * Since: 23.07.0 |
1753 | **/ |
1754 | void poppler_signing_data_set_reason(PopplerSigningData *signing_data, const gchar *reason) |
1755 | { |
1756 | g_return_if_fail(signing_data != nullptr); |
1757 | g_return_if_fail(reason != nullptr); |
1758 | |
1759 | if (signing_data->reason == reason) { |
1760 | return; |
1761 | } |
1762 | |
1763 | g_clear_pointer(&signing_data->reason, g_free); |
1764 | signing_data->reason = g_strdup(str: reason); |
1765 | } |
1766 | |
1767 | /** |
1768 | * poppler_signing_data_get_reason: |
1769 | * @signing_data: a #PopplerSigningData structure containing signing data |
1770 | * |
1771 | * Get reason. |
1772 | * |
1773 | * Return value: reason |
1774 | * |
1775 | * Since: 23.07.0 |
1776 | **/ |
1777 | const gchar *poppler_signing_data_get_reason(const PopplerSigningData *signing_data) |
1778 | { |
1779 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1780 | return signing_data->reason; |
1781 | } |
1782 | |
1783 | /** |
1784 | * poppler_signing_data_set_location: |
1785 | * @signing_data: a #PopplerSigningData structure containing signing data |
1786 | * @location: a location |
1787 | * |
1788 | * Set signature location (e.g. "At my desk"). |
1789 | * |
1790 | * Since: 23.07.0 |
1791 | **/ |
1792 | void poppler_signing_data_set_location(PopplerSigningData *signing_data, const gchar *location) |
1793 | { |
1794 | g_return_if_fail(signing_data != nullptr); |
1795 | g_return_if_fail(location != nullptr); |
1796 | |
1797 | if (signing_data->location == location) { |
1798 | return; |
1799 | } |
1800 | |
1801 | g_clear_pointer(&signing_data->location, g_free); |
1802 | signing_data->location = g_strdup(str: location); |
1803 | } |
1804 | |
1805 | /** |
1806 | * poppler_signing_data_get_location: |
1807 | * @signing_data: a #PopplerSigningData structure containing signing data |
1808 | * |
1809 | * Get location. |
1810 | * |
1811 | * Return value: location |
1812 | * |
1813 | * Since: 23.07.0 |
1814 | **/ |
1815 | const gchar *poppler_signing_data_get_location(const PopplerSigningData *signing_data) |
1816 | { |
1817 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1818 | return signing_data->location; |
1819 | } |
1820 | |
1821 | /** |
1822 | * poppler_signing_data_set_image_path: |
1823 | * @signing_data: a #PopplerSigningData structure containing signing data |
1824 | * @image_path: signature image path |
1825 | * |
1826 | * Set signature background (watermark) image path. |
1827 | * |
1828 | * Since: 23.07.0 |
1829 | **/ |
1830 | void poppler_signing_data_set_image_path(PopplerSigningData *signing_data, const gchar *image_path) |
1831 | { |
1832 | g_return_if_fail(signing_data != nullptr); |
1833 | g_return_if_fail(image_path != nullptr); |
1834 | |
1835 | if (signing_data->image_path == image_path) { |
1836 | return; |
1837 | } |
1838 | |
1839 | g_clear_pointer(&signing_data->image_path, g_free); |
1840 | signing_data->image_path = g_strdup(str: image_path); |
1841 | } |
1842 | |
1843 | /** |
1844 | * poppler_signing_data_get_image_path: |
1845 | * @signing_data: a #PopplerSigningData structure containing signing data |
1846 | * |
1847 | * Get image path. |
1848 | * |
1849 | * Return value: image path |
1850 | * |
1851 | * Since: 23.07.0 |
1852 | **/ |
1853 | const gchar *poppler_signing_data_get_image_path(const PopplerSigningData *signing_data) |
1854 | { |
1855 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1856 | return signing_data->image_path; |
1857 | } |
1858 | |
1859 | /** |
1860 | * poppler_signing_data_set_password: |
1861 | * @signing_data: a #PopplerSigningData structure containing signing data |
1862 | * @password: a password |
1863 | * |
1864 | * Set password for the signing key. |
1865 | * |
1866 | * Since: 23.07.0 |
1867 | **/ |
1868 | void poppler_signing_data_set_password(PopplerSigningData *signing_data, const gchar *password) |
1869 | { |
1870 | g_return_if_fail(signing_data != nullptr); |
1871 | g_return_if_fail(password != nullptr); |
1872 | |
1873 | if (signing_data->password == password) { |
1874 | return; |
1875 | } |
1876 | |
1877 | g_clear_pointer(&signing_data->password, g_free); |
1878 | signing_data->password = g_strdup(str: password); |
1879 | } |
1880 | |
1881 | /** |
1882 | * poppler_signing_data_get_password: |
1883 | * @signing_data: a #PopplerSigningData structure containing signing data |
1884 | * |
1885 | * Get signing key password. |
1886 | * |
1887 | * Return value: password |
1888 | * |
1889 | * Since: 23.07.0 |
1890 | **/ |
1891 | const gchar *poppler_signing_data_get_password(const PopplerSigningData *signing_data) |
1892 | { |
1893 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1894 | return signing_data->password; |
1895 | } |
1896 | |
1897 | /** |
1898 | * poppler_signing_data_set_document_owner_password: |
1899 | * @signing_data: a #PopplerSigningData structure containing signing data |
1900 | * @document_owner_password: document owner password |
1901 | * |
1902 | * Set document owner password (for encrypted files). |
1903 | * |
1904 | * Since: 23.07.0 |
1905 | **/ |
1906 | void poppler_signing_data_set_document_owner_password(PopplerSigningData *signing_data, const gchar *document_owner_password) |
1907 | { |
1908 | g_return_if_fail(signing_data != nullptr); |
1909 | g_return_if_fail(document_owner_password != nullptr); |
1910 | |
1911 | if (signing_data->document_owner_password == document_owner_password) { |
1912 | return; |
1913 | } |
1914 | |
1915 | g_clear_pointer(&signing_data->document_owner_password, g_free); |
1916 | signing_data->document_owner_password = g_strdup(str: document_owner_password); |
1917 | } |
1918 | |
1919 | /** |
1920 | * poppler_signing_data_get_document_owner_password: |
1921 | * @signing_data: a #PopplerSigningData structure containing signing data |
1922 | * |
1923 | * Get document owner password. |
1924 | * |
1925 | * Return value: document owner password (for encrypted files) |
1926 | * |
1927 | * Since: 23.07.0 |
1928 | **/ |
1929 | const gchar *poppler_signing_data_get_document_owner_password(const PopplerSigningData *signing_data) |
1930 | { |
1931 | g_return_val_if_fail(signing_data != nullptr, nullptr); |
1932 | return signing_data->document_owner_password; |
1933 | } |
1934 | |
1935 | /** |
1936 | * poppler_signing_data_set_document_user_password: |
1937 | * @signing_data: a #PopplerSigningData structure containing signing data |
1938 | * @document_user_password: document user password |
1939 | * |
1940 | * Set document user password (for encrypted files). |
1941 | * |
1942 | * Since: 23.07.0 |
1943 | **/ |
1944 | void poppler_signing_data_set_document_user_password(PopplerSigningData *signing_data, const gchar *document_user_password) |
1945 | { |
1946 | g_return_if_fail(signing_data != nullptr); |
1947 | g_return_if_fail(document_user_password != nullptr); |
1948 | |
1949 | if (signing_data->document_user_password == document_user_password) { |
1950 | return; |
1951 | } |
1952 | |
1953 | g_clear_pointer(&signing_data->document_user_password, g_free); |
1954 | signing_data->document_user_password = g_strdup(str: document_user_password); |
1955 | } |
1956 | |
1957 | /** |
1958 | * poppler_signing_data_get_document_user_password: |
1959 | * @signing_data: a #PopplerSigningData structure containing signing data |
1960 | * |
1961 | * Get document user password. |
1962 | * |
1963 | * Return value: document user password (for encrypted files) |
1964 | * |
1965 | * Since: 23.07.0 |
1966 | **/ |
1967 | const gchar *poppler_signing_data_get_document_user_password(const PopplerSigningData *signing_data) |
1968 | { |
1969 | g_return_val_if_fail(signing_data != nullptr, "" ); |
1970 | return signing_data->document_user_password; |
1971 | } |
1972 | |
1973 | /* Certificate Information */ |
1974 | |
1975 | /** |
1976 | * poppler_certificate_info_new: |
1977 | * |
1978 | * Creates a new #PopplerCertificateInfo |
1979 | * |
1980 | * Return value: a new #PopplerCertificateInfo. It must be freed with poppler_certificate_info_free() when done. |
1981 | * |
1982 | * Since: 23.07.0 |
1983 | **/ |
1984 | PopplerCertificateInfo *poppler_certificate_info_new(void) |
1985 | { |
1986 | return (PopplerCertificateInfo *)g_malloc0(n_bytes: sizeof(PopplerCertificateInfo)); |
1987 | } |
1988 | |
1989 | /** |
1990 | * poppler_certificate_info_get_id: |
1991 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
1992 | * |
1993 | * Get certificate nick name |
1994 | * |
1995 | * Return value: certificate nick name |
1996 | * |
1997 | * Since: 23.07.0 |
1998 | **/ |
1999 | const char *poppler_certificate_info_get_id(const PopplerCertificateInfo *certificate_info) |
2000 | { |
2001 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2002 | return certificate_info->id; |
2003 | } |
2004 | |
2005 | /** |
2006 | * poppler_certificate_info_get_subject_common_name: |
2007 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2008 | * |
2009 | * Get certificate subject common name |
2010 | * |
2011 | * Return value: certificate subject common name |
2012 | * |
2013 | * Since: 23.07.0 |
2014 | **/ |
2015 | const char *poppler_certificate_info_get_subject_common_name(const PopplerCertificateInfo *certificate_info) |
2016 | { |
2017 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2018 | return certificate_info->subject_common_name; |
2019 | } |
2020 | |
2021 | /** |
2022 | * poppler_certificate_info_get_subject_organization: |
2023 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2024 | * |
2025 | * Get certificate subject organization |
2026 | * |
2027 | * Return value: certificate subject organization |
2028 | * |
2029 | * Since: 23.08.0 |
2030 | **/ |
2031 | const char *poppler_certificate_info_get_subject_organization(const PopplerCertificateInfo *certificate_info) |
2032 | { |
2033 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2034 | return certificate_info->subject_organization; |
2035 | } |
2036 | |
2037 | /** |
2038 | * poppler_certificate_info_get_subject_email: |
2039 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2040 | * |
2041 | * Get certificate subject email |
2042 | * |
2043 | * Return value: certificate subject email |
2044 | * |
2045 | * Since: 23.08.0 |
2046 | **/ |
2047 | const char *poppler_certificate_info_get_subject_email(const PopplerCertificateInfo *certificate_info) |
2048 | { |
2049 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2050 | return certificate_info->subject_email; |
2051 | } |
2052 | |
2053 | /** |
2054 | * poppler_certificate_info_get_issuer_common_name: |
2055 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2056 | * |
2057 | * Get certificate issuer common name |
2058 | * |
2059 | * Return value: certificate issuer common name |
2060 | * |
2061 | * Since: 23.08.0 |
2062 | **/ |
2063 | const char *poppler_certificate_info_get_issuer_common_name(const PopplerCertificateInfo *certificate_info) |
2064 | { |
2065 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2066 | return certificate_info->issuer_common_name; |
2067 | } |
2068 | |
2069 | /** |
2070 | * poppler_certificate_info_get_issuer_organization: |
2071 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2072 | * |
2073 | * Get certificate issuer organization |
2074 | * |
2075 | * Return value: certificate issuer organization |
2076 | * |
2077 | * Since: 23.08.0 |
2078 | **/ |
2079 | const char *poppler_certificate_info_get_issuer_organization(const PopplerCertificateInfo *certificate_info) |
2080 | { |
2081 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2082 | return certificate_info->issuer_organization; |
2083 | } |
2084 | |
2085 | /** |
2086 | * poppler_certificate_info_get_issuer_email: |
2087 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2088 | * |
2089 | * Get certificate issuer email |
2090 | * |
2091 | * Return value: certificate issuer email |
2092 | * |
2093 | * Since: 23.08.0 |
2094 | **/ |
2095 | const char *poppler_certificate_info_get_issuer_email(const PopplerCertificateInfo *certificate_info) |
2096 | { |
2097 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2098 | return certificate_info->issuer_email; |
2099 | } |
2100 | |
2101 | /** |
2102 | * poppler_certificate_info_get_issuance_time: |
2103 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2104 | * |
2105 | * Get certificate issuance time |
2106 | * |
2107 | * Return value: (transfer none): certificate issuance time |
2108 | * |
2109 | * Since: 23.08.0 |
2110 | **/ |
2111 | GDateTime *poppler_certificate_info_get_issuance_time(const PopplerCertificateInfo *certificate_info) |
2112 | { |
2113 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2114 | return certificate_info->issued; |
2115 | } |
2116 | |
2117 | /** |
2118 | * poppler_certificate_info_get_expiration_time: |
2119 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2120 | * |
2121 | * Get certificate expiration time |
2122 | * |
2123 | * Return value: (transfer none): certificate expiration time |
2124 | * |
2125 | * Since: 23.08.0 |
2126 | **/ |
2127 | GDateTime *poppler_certificate_info_get_expiration_time(const PopplerCertificateInfo *certificate_info) |
2128 | { |
2129 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2130 | return certificate_info->expires; |
2131 | } |
2132 | |
2133 | static PopplerCertificateInfo *create_certificate_info(const X509CertificateInfo *ci) |
2134 | { |
2135 | PopplerCertificateInfo *certificate_info; |
2136 | |
2137 | g_return_val_if_fail(ci != nullptr, nullptr); |
2138 | |
2139 | const X509CertificateInfo::EntityInfo &subject_info = ci->getSubjectInfo(); |
2140 | const X509CertificateInfo::EntityInfo &issuer_info = ci->getIssuerInfo(); |
2141 | const X509CertificateInfo::Validity &validity = ci->getValidity(); |
2142 | |
2143 | certificate_info = poppler_certificate_info_new(); |
2144 | certificate_info->id = g_strdup(str: ci->getNickName().c_str()); |
2145 | certificate_info->subject_common_name = g_strdup(str: subject_info.commonName.c_str()); |
2146 | certificate_info->subject_organization = g_strdup(str: subject_info.organization.c_str()); |
2147 | certificate_info->subject_email = g_strdup(str: subject_info.email.c_str()); |
2148 | certificate_info->issuer_common_name = g_strdup(str: issuer_info.commonName.c_str()); |
2149 | certificate_info->issuer_organization = g_strdup(str: issuer_info.organization.c_str()); |
2150 | certificate_info->issuer_email = g_strdup(str: issuer_info.email.c_str()); |
2151 | certificate_info->issued = g_date_time_new_from_unix_utc(t: validity.notBefore); |
2152 | certificate_info->expires = g_date_time_new_from_unix_utc(t: validity.notAfter); |
2153 | |
2154 | return certificate_info; |
2155 | } |
2156 | |
2157 | /** |
2158 | * poppler_certificate_info_copy: |
2159 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2160 | * |
2161 | * Copies @certificate_info, creating an identical #PopplerCertificateInfo. |
2162 | * |
2163 | * Return value: (transfer full): a new #PopplerCertificateInfo structure identical to @certificate_info |
2164 | * |
2165 | * Since: 23.07.0 |
2166 | **/ |
2167 | PopplerCertificateInfo *poppler_certificate_info_copy(const PopplerCertificateInfo *certificate_info) |
2168 | { |
2169 | PopplerCertificateInfo *dup; |
2170 | |
2171 | g_return_val_if_fail(certificate_info != nullptr, nullptr); |
2172 | |
2173 | dup = (PopplerCertificateInfo *)g_malloc0(n_bytes: sizeof(PopplerCertificateInfo)); |
2174 | dup->id = g_strdup(str: certificate_info->id); |
2175 | dup->subject_common_name = g_strdup(str: certificate_info->subject_common_name); |
2176 | dup->subject_organization = g_strdup(str: certificate_info->subject_organization); |
2177 | dup->subject_email = g_strdup(str: certificate_info->subject_email); |
2178 | dup->issuer_common_name = g_strdup(str: certificate_info->issuer_common_name); |
2179 | dup->issuer_organization = g_strdup(str: certificate_info->issuer_organization); |
2180 | dup->issuer_email = g_strdup(str: certificate_info->issuer_email); |
2181 | dup->issued = g_date_time_ref(datetime: certificate_info->issued); |
2182 | dup->expires = g_date_time_ref(datetime: certificate_info->expires); |
2183 | |
2184 | return dup; |
2185 | } |
2186 | |
2187 | /** |
2188 | * poppler_certificate_info_free: |
2189 | * @certificate_info: a #PopplerCertificateInfo structure containing certificate information |
2190 | * |
2191 | * Frees @certificate_info |
2192 | * |
2193 | * Since: 23.07.0 |
2194 | **/ |
2195 | void poppler_certificate_info_free(PopplerCertificateInfo *certificate_info) |
2196 | { |
2197 | if (certificate_info == nullptr) { |
2198 | return; |
2199 | } |
2200 | |
2201 | g_clear_pointer(&certificate_info->id, g_free); |
2202 | g_clear_pointer(&certificate_info->subject_common_name, g_free); |
2203 | g_clear_pointer(&certificate_info->subject_organization, g_free); |
2204 | g_clear_pointer(&certificate_info->subject_email, g_free); |
2205 | g_clear_pointer(&certificate_info->issuer_common_name, g_free); |
2206 | g_clear_pointer(&certificate_info->issuer_organization, g_free); |
2207 | g_clear_pointer(&certificate_info->issuer_email, g_free); |
2208 | g_clear_pointer(&certificate_info->issued, g_date_time_unref); |
2209 | g_clear_pointer(&certificate_info->expires, g_date_time_unref); |
2210 | |
2211 | g_free(mem: certificate_info); |
2212 | } |
2213 | |
2214 | /** |
2215 | * poppler_get_available_signing_certificates: |
2216 | * |
2217 | * Get all available signing certificate information |
2218 | * |
2219 | * Returns: (transfer full) (element-type PopplerCertificateInfo): all available signing certificate information |
2220 | **/ |
2221 | GList *poppler_get_available_signing_certificates(void) |
2222 | { |
2223 | GList *list = nullptr; |
2224 | auto backend = CryptoSign::Factory::createActive(); |
2225 | |
2226 | if (!backend) { |
2227 | return nullptr; |
2228 | } |
2229 | |
2230 | std::vector<std::unique_ptr<X509CertificateInfo>> vCerts = backend->getAvailableSigningCertificates(); |
2231 | for (auto &cert : vCerts) { |
2232 | PopplerCertificateInfo *certificate_info = create_certificate_info(ci: cert.get()); |
2233 | list = g_list_append(list, data: certificate_info); |
2234 | } |
2235 | return list; |
2236 | } |
2237 | |
2238 | /** |
2239 | * poppler_get_certificate_info_by_id: |
2240 | * |
2241 | * Get certificate by nick name |
2242 | * |
2243 | * Returns: (transfer full): a #PopplerCertificateInfo or %NULL if not found |
2244 | **/ |
2245 | PopplerCertificateInfo *poppler_get_certificate_info_by_id(const char *id) |
2246 | { |
2247 | PopplerCertificateInfo *ret = nullptr; |
2248 | GList *certificate_info = poppler_get_available_signing_certificates(); |
2249 | GList *list; |
2250 | |
2251 | for (list = certificate_info; list != nullptr; list = list->next) { |
2252 | PopplerCertificateInfo *info = (PopplerCertificateInfo *)list->data; |
2253 | |
2254 | if (g_strcmp0(str1: info->id, str2: id) == 0) { |
2255 | ret = poppler_certificate_info_copy(certificate_info: info); |
2256 | break; |
2257 | } |
2258 | } |
2259 | |
2260 | g_list_free_full(list: certificate_info, free_func: (GDestroyNotify)poppler_certificate_info_free); |
2261 | |
2262 | return ret; |
2263 | } |
2264 | |
2265 | /* NSS functions */ |
2266 | |
2267 | /** |
2268 | * poppler_set_nss_dir: |
2269 | * |
2270 | * Set NSS directory |
2271 | * |
2272 | * Since: 23.07.0 |
2273 | **/ |
2274 | void poppler_set_nss_dir(const char *path) |
2275 | { |
2276 | #ifdef ENABLE_NSS3 |
2277 | NSSSignatureConfiguration::setNSSDir(GooString(path)); |
2278 | #else |
2279 | (void)path; |
2280 | #endif |
2281 | } |
2282 | |
2283 | /** |
2284 | * poppler_get_nss_dir: |
2285 | * |
2286 | * Get NSS directory |
2287 | * |
2288 | * Return value: (transfer full): nss directroy. |
2289 | * |
2290 | * Since: 23.07.0 |
2291 | **/ |
2292 | char *poppler_get_nss_dir(void) |
2293 | { |
2294 | #ifdef ENABLE_NSS3 |
2295 | return g_strdup(str: NSSSignatureConfiguration::getNSSDir().c_str()); |
2296 | #else |
2297 | return nullptr; |
2298 | #endif |
2299 | } |
2300 | |
2301 | /** |
2302 | * poppler_set_nss_password_callback: |
2303 | * @func: (scope call): a #PopplerNssPasswordFunc that represents a signature annotation |
2304 | * |
2305 | * A callback which asks for certificate password |
2306 | * |
2307 | * Since: 23.07.0 |
2308 | **/ |
2309 | void poppler_set_nss_password_callback(PopplerNssPasswordFunc func) |
2310 | { |
2311 | #ifdef ENABLE_NSS3 |
2312 | NSSSignatureConfiguration::setNSSPasswordCallback(func); |
2313 | #else |
2314 | g_warning("poppler_set_nss_password_callback called but this poppler is built without NSS support" ); |
2315 | (void)func; |
2316 | #endif |
2317 | } |
2318 | |