xref: /plan9/sys/src/cmd/gs/src/iutil2.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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