/* Copyright (C) 1993, 1994, 1998 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: iutil2.c,v 1.2.6.2.2.1 2003/01/17 00:49:04 giles Exp $ */ /* Level 2 utilities for Ghostscript interpreter */ #include "memory_.h" #include "string_.h" #include "ghost.h" #include "errors.h" #include "opcheck.h" #include "gsparam.h" #include "gsutil.h" /* bytes_compare prototype */ #include "idict.h" #include "imemory.h" /* for iutil.h */ #include "iutil.h" #include "iutil2.h" /* ------ Password utilities ------ */ /* Read a password from a parameter list. */ /* Return 0 if present, 1 if absent, or an error code. */ int param_read_password(gs_param_list * plist, const char *kstr, password * ppass) { gs_param_string ps; long ipass; int code; ps.data = (const byte *)ppass->data, ps.size = ppass->size, ps.persistent = false; code = param_read_string(plist, kstr, &ps); switch (code) { case 0: /* OK */ if (ps.size > MAX_PASSWORD) return_error(e_limitcheck); /* Copy the data back. */ memcpy(ppass->data, ps.data, ps.size); ppass->size = ps.size; return 0; case 1: /* key is missing */ return 1; } /* We might have gotten a typecheck because */ /* the supplied password was an integer. */ if (code != e_typecheck) return code; code = param_read_long(plist, kstr, &ipass); if (code != 0) /* error or missing */ return code; sprintf((char *)ppass->data, "%ld", ipass); ppass->size = strlen((char *)ppass->data); return 0; } /* Write a password to a parameter list. */ int param_write_password(gs_param_list * plist, const char *kstr, const password * ppass) { gs_param_string ps; ps.data = (const byte *)ppass->data, ps.size = ppass->size, ps.persistent = false; if (ps.size > MAX_PASSWORD) return_error(e_limitcheck); return param_write_string(plist, kstr, &ps); } /* Check a password from a parameter list. */ /* Return 0 if OK, 1 if not OK, or an error code. */ int param_check_password(gs_param_list * plist, const password * ppass) { if (ppass->size != 0) { password pass; int code = param_read_password(plist, "Password", &pass); if (code) return code; if (pass.size != ppass->size || bytes_compare(&pass.data[0], pass.size, &ppass->data[0], ppass->size) != 0 ) return 1; } return 0; } /* Read a password from, or write a password into, a dictionary */ /* (presumably systemdict). */ private int dict_find_password(ref ** ppvalue, const ref * pdref, const char *kstr) { ref *pvalue; if (dict_find_string(pdref, kstr, &pvalue) <= 0) return_error(e_undefined); if (!r_has_type(pvalue, t_string) || r_has_attrs(pvalue, a_read) || pvalue->value.const_bytes[0] >= r_size(pvalue) ) return_error(e_rangecheck); *ppvalue = pvalue; return 0; } int dict_read_password(password * ppass, const ref * pdref, const char *pkey) { ref *pvalue; int code = dict_find_password(&pvalue, pdref, pkey); if (code < 0) return code; if (pvalue->value.const_bytes[0] > MAX_PASSWORD) return_error(e_rangecheck); /* limitcheck? */ memcpy(ppass->data, pvalue->value.const_bytes + 1, (ppass->size = pvalue->value.const_bytes[0])); return 0; } int dict_write_password(const password * ppass, ref * pdref, const char *pkey, bool change_allowed) { ref *pvalue; int code = dict_find_password(&pvalue, pdref, pkey); if (code < 0) return code; if (ppass->size >= r_size(pvalue)) return_error(e_rangecheck); if (!change_allowed && bytes_compare(pvalue->value.bytes + 1, pvalue->value.bytes[0], ppass->data, ppass->size) != 0) return_error(e_invalidaccess); memcpy(pvalue->value.bytes + 1, ppass->data, (pvalue->value.bytes[0] = ppass->size)); return 0; }