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