/src/ghostpdl/psi/iutil2.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* Level 2 utilities for Ghostscript interpreter */ |
18 | | #include "memory_.h" |
19 | | #include "string_.h" |
20 | | #include "ghost.h" |
21 | | #include "ierrors.h" |
22 | | #include "opcheck.h" |
23 | | #include "gsparam.h" |
24 | | #include "gsutil.h" /* bytes_compare prototype */ |
25 | | #include "idict.h" |
26 | | #include "imemory.h" /* for iutil.h */ |
27 | | #include "iutil.h" |
28 | | #include "iutil2.h" |
29 | | |
30 | | /* ------ Password utilities ------ */ |
31 | | |
32 | | /* Read a password from a parameter list. */ |
33 | | /* Return 0 if present, 1 if absent, or an error code. */ |
34 | | int |
35 | | param_read_password(gs_param_list * plist, const char *kstr, password * ppass) |
36 | 0 | { |
37 | 0 | gs_param_string ps; |
38 | 0 | long ipass; |
39 | 0 | int code = param_read_string(plist, kstr, &ps); |
40 | |
|
41 | 0 | switch (code) { |
42 | 0 | case 0: /* OK */ |
43 | 0 | if (ps.size > MAX_PASSWORD) |
44 | 0 | return_error(gs_error_limitcheck); |
45 | | /* Copy the data back. */ |
46 | 0 | memcpy(ppass->data, ps.data, ps.size); |
47 | 0 | ppass->size = ps.size; |
48 | 0 | return 0; |
49 | 0 | case 1: /* key is missing */ |
50 | 0 | return 1; |
51 | 0 | } |
52 | | /* We might have gotten a typecheck because */ |
53 | | /* the supplied password was an integer. */ |
54 | 0 | if (code != gs_error_typecheck) |
55 | 0 | return code; |
56 | 0 | code = param_read_long(plist, kstr, &ipass); |
57 | 0 | if (code != 0) /* error or missing */ |
58 | 0 | return code; |
59 | 0 | gs_snprintf((char *)ppass->data, MAX_PASSWORD, "%ld", ipass); |
60 | 0 | ppass->size = strlen((char *)ppass->data); |
61 | 0 | return 0; |
62 | 0 | } |
63 | | /* Write a password to a parameter list. */ |
64 | | int |
65 | | param_write_password(gs_param_list * plist, const char *kstr, |
66 | | const password * ppass) |
67 | 0 | { |
68 | 0 | gs_param_string ps; |
69 | |
|
70 | 0 | ps.data = (const byte *)ppass->data, ps.size = ppass->size, |
71 | 0 | ps.persistent = false; |
72 | 0 | if (ps.size > MAX_PASSWORD) |
73 | 0 | return_error(gs_error_limitcheck); |
74 | 0 | return param_write_string(plist, kstr, &ps); |
75 | 0 | } |
76 | | |
77 | | /* Check a password from a parameter list. */ |
78 | | /* Return 0 if OK, 1 if not OK, or an error code. */ |
79 | | int |
80 | | param_check_password(gs_param_list * plist, const password * ppass) |
81 | 0 | { |
82 | 0 | if (ppass->size != 0) { |
83 | 0 | password pass; |
84 | 0 | int code = param_read_password(plist, "Password", &pass); |
85 | |
|
86 | 0 | if (code) |
87 | 0 | return code; |
88 | 0 | if (pass.size != ppass->size || |
89 | 0 | bytes_compare(&pass.data[0], pass.size, |
90 | 0 | &ppass->data[0], |
91 | 0 | ppass->size) != 0 |
92 | 0 | ) |
93 | 0 | return 1; |
94 | 0 | } |
95 | 0 | return 0; |
96 | 0 | } |
97 | | |
98 | | /* Read a password from, or write a password into, a dictionary */ |
99 | | /* (presumably systemdict). */ |
100 | | static int |
101 | | dict_find_password(ref ** ppvalue, const ref * pdref, const char *kstr) |
102 | 0 | { |
103 | 0 | ref *pvalue; |
104 | |
|
105 | 0 | if (dict_find_string(pdref, kstr, &pvalue) <= 0) |
106 | 0 | return_error(gs_error_undefined); |
107 | 0 | if (!r_has_type(pvalue, t_string) || |
108 | 0 | r_has_attrs(pvalue, a_read) || |
109 | 0 | pvalue->value.const_bytes[0] >= r_size(pvalue) |
110 | 0 | ) |
111 | 0 | return_error(gs_error_rangecheck); |
112 | 0 | *ppvalue = pvalue; |
113 | 0 | return 0; |
114 | 0 | } |
115 | | int |
116 | | dict_read_password(password * ppass, const ref * pdref, const char *pkey) |
117 | 0 | { |
118 | 0 | ref *pvalue; |
119 | 0 | int code = dict_find_password(&pvalue, pdref, pkey); |
120 | |
|
121 | 0 | if (code < 0) |
122 | 0 | return code; |
123 | 0 | if (pvalue->value.const_bytes[0] > MAX_PASSWORD) |
124 | 0 | return_error(gs_error_rangecheck); /* limitcheck? */ |
125 | 0 | memcpy(ppass->data, pvalue->value.const_bytes + 1, |
126 | 0 | (ppass->size = pvalue->value.const_bytes[0])); |
127 | 0 | return 0; |
128 | 0 | } |
129 | | int |
130 | | dict_write_password(const password * ppass, ref * pdref, const char *pkey, |
131 | | bool change_allowed) |
132 | 0 | { |
133 | 0 | ref *pvalue; |
134 | 0 | int code = dict_find_password(&pvalue, pdref, pkey); |
135 | |
|
136 | 0 | if (code < 0) |
137 | 0 | return code; |
138 | 0 | if (ppass->size >= r_size(pvalue)) |
139 | 0 | return_error(gs_error_rangecheck); |
140 | 0 | if (!change_allowed && |
141 | 0 | bytes_compare(pvalue->value.bytes + 1, pvalue->value.bytes[0], |
142 | 0 | ppass->data, ppass->size) != 0) |
143 | 0 | return_error(gs_error_invalidaccess); |
144 | 0 | memcpy(pvalue->value.bytes + 1, ppass->data, |
145 | 0 | (pvalue->value.bytes[0] = ppass->size)); |
146 | 0 | return 0; |
147 | 0 | } |