summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java')
-rw-r--r--pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java783
1 files changed, 783 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
new file mode 100644
index 000000000..20c124dbc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
@@ -0,0 +1,783 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// 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; version 2 of the License.
+//
+// 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.def;
+
+import java.io.*;
+import java.util.*;
+import java.security.cert.CertificateException;
+
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.property.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.pattern.*;
+import com.netscape.certsrv.apps.*;
+
+import com.netscape.cms.profile.common.EnrollProfile;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.extensions.*;
+
+
+/**
+ * This class implements an enrollment default policy.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class EnrollDefault implements IPolicyDefault, ICertInfoPolicyDefault {
+
+ public static final String PROP_NAME = "name";
+
+ public static final String GN_RFC822_NAME = "RFC822Name";
+ public static final String GN_DNS_NAME = "DNSName";
+ public static final String GN_URI_NAME = "URIName";
+ public static final String GN_IP_NAME = "IPAddressName";
+ public static final String GN_DIRECTORY_NAME = "DirectoryName";
+ public static final String GN_EDI_NAME = "EDIPartyName";
+ public static final String GN_ANY_NAME = "OtherName";
+ public static final String GN_OID_NAME = "OIDName";
+
+ protected IConfigStore mConfig = null;
+ protected Vector mConfigNames = new Vector();
+ protected Vector mValueNames = new Vector();
+
+ public EnrollDefault() {
+ }
+
+ public Enumeration getConfigNames() {
+ return mConfigNames.elements();
+ }
+
+ public IDescriptor getConfigDescriptor(Locale locale, String name) {
+ return null;
+ }
+
+ public void addConfigName(String name) {
+ mConfigNames.addElement(name);
+ }
+
+ public void setConfig(String name, String value)
+ throws EPropertyException {
+ if (mConfig.getSubStore("params") == null) {
+ //
+ } else {
+ mConfig.getSubStore("params").putString(name, value);
+ }
+ }
+
+ public String getConfig(String name) {
+ try {
+ if (mConfig == null)
+ return null;
+ if (mConfig.getSubStore("params") != null) {
+ return mConfig.getSubStore("params").getString(name);
+ }
+ } catch (EBaseException e) {
+ }
+ return "";
+ }
+
+ public void init(IProfile profile, IConfigStore config)
+ throws EProfileException {
+ mConfig = config;
+ }
+
+ /**
+ * Retrieves the localizable description of this policy.
+ *
+ * @param locale locale of the end user
+ * @return localized description of this default policy
+ */
+ public abstract String getText(Locale locale);
+
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public String getName(Locale locale) {
+ try {
+ return mConfig.getString(PROP_NAME);
+ } catch (EBaseException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Populates attributes into the certificate template.
+ *
+ * @param request enrollment request
+ * @param info certificate template
+ * @exception EProfileException failed to populate attributes
+ * into request
+ */
+ public abstract void populate(IRequest request, X509CertInfo info)
+ throws EProfileException;
+
+ /**
+ * Sets values from the approval page into certificate template.
+ *
+ * @param name name of the attribute
+ * @param locale user locale
+ * @param info certificate template
+ * @param value attribute value
+ * @exception EProfileException failed to set attributes
+ * into request
+ */
+ public abstract void setValue(String name, Locale locale,
+ X509CertInfo info, String value)
+ throws EPropertyException;
+
+ /**
+ * Retrieves certificate template values and returns them to
+ * the approval page.
+ *
+ * @param name name of the attribute
+ * @param locale user locale
+ * @param info certificate template
+ * @exception EProfileException failed to get attributes
+ * from request
+ */
+ public abstract String getValue(String name, Locale locale,
+ X509CertInfo info)
+ throws EPropertyException;
+
+ /**
+ * Populates the request with this policy default.
+ *
+ * The current implementation extracts enrollment specific attributes
+ * and calls the populate() method of the subclass.
+ *
+ * @param request request to be populated
+ * @exception EProfileException failed to populate
+ */
+ public void populate(IRequest request)
+ throws EProfileException {
+ String name = getClass().getName();
+
+ name = name.substring(name.lastIndexOf('.') + 1);
+ CMS.debug(name + ": populate start");
+ X509CertInfo info =
+ request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+
+ populate(request, info);
+
+ request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ CMS.debug(name + ": populate end");
+ }
+
+ public void addValueName(String name) {
+ mValueNames.addElement(name);
+ }
+
+ public Enumeration getValueNames() {
+ return mValueNames.elements();
+ }
+
+ public IDescriptor getValueDescriptor(String name) {
+ return null;
+ }
+
+ /**
+ * Sets the value of the given value property by name.
+ *
+ * The current implementation extracts enrollment specific attributes
+ * and calls the setValue() method of the subclass.
+ *
+ * @param name name of property
+ * @param locale locale of the end user
+ * @param request request
+ * @param value value to be set in the given request
+ * @exception EPropertyException failed to set property
+ */
+ public void setValue(String name, Locale locale, IRequest request,
+ String value)
+ throws EPropertyException {
+ X509CertInfo info =
+ request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+
+ setValue(name, locale, info, value);
+
+ request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ }
+
+ /**
+ * Retrieves the value of the given value
+ * property by name.
+ *
+ * The current implementation extracts enrollment specific attributes
+ * and calls the getValue() method of the subclass.
+ *
+ * @param name name of property
+ * @param locale locale of the end user
+ * @param request request
+ * @exception EPropertyException failed to get property
+ */
+ public String getValue(String name, Locale locale, IRequest request)
+ throws EPropertyException {
+ X509CertInfo info =
+ request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+
+ String value = getValue(name, locale, info);
+ request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info);
+ return value;
+ }
+
+ public String toHexString(byte data[]) {
+ IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
+ String s = pp.toHexString(data, 0, 16);
+ StringTokenizer st = new StringTokenizer(s, "\n");
+ StringBuffer buffer = new StringBuffer();
+
+ while (st.hasMoreTokens()) {
+ buffer.append(st.nextToken());
+ buffer.append("\\n");
+ }
+ return buffer.toString();
+ }
+
+ protected void refreshConfigAndValueNames() {
+ mConfigNames.removeAllElements();
+ mValueNames.removeAllElements();
+ }
+
+ protected void deleteExtension(String name, X509CertInfo info) {
+ CertificateExtensions exts = null;
+
+ try {
+ exts = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ if (exts == null)
+ return;
+ Enumeration e = exts.getNames();
+
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+ Extension ext = (Extension) exts.get(n);
+
+ if (ext.getExtensionId().toString().equals(name)) {
+ exts.delete(n);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug(e.toString());
+ }
+ }
+
+ protected Extension getExtension(String name, X509CertInfo info) {
+ CertificateExtensions exts = null;
+
+ try {
+ exts = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ } catch (Exception e) {
+ CMS.debug("EnrollDefault: getExtension " + e.toString());
+ }
+ if (exts == null)
+ return null;
+ return getExtension(name, exts);
+ }
+
+ protected Extension getExtension(String name, CertificateExtensions exts) {
+ if (exts == null)
+ return null;
+ Enumeration e = exts.getElements();
+
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+
+ if (ext.getExtensionId().toString().equals(name)) {
+ return ext;
+ }
+ }
+ return null;
+ }
+
+ protected void addExtension(String name, Extension ext, X509CertInfo info)
+ throws EProfileException {
+ if (ext == null) {
+ throw new EProfileException("extension not found");
+ }
+ CertificateExtensions exts = null;
+
+ Extension alreadyPresentExtension = getExtension(name,info);
+
+ if (alreadyPresentExtension != null) {
+ String eName = ext.toString();
+ CMS.debug("EnrollDefault.addExtension: duplicate extension attempted! Name: " + eName);
+ throw new EProfileException(CMS.getUserMessage("CMS_PROFILE_DUPLICATE_EXTENSION",eName));
+ }
+
+ try {
+ exts = (CertificateExtensions)
+ info.get(X509CertInfo.EXTENSIONS);
+ } catch (Exception e) {
+ CMS.debug("EnrollDefault: " + e.toString());
+ }
+ if (exts == null) {
+ throw new EProfileException("extensions not found");
+ }
+ try {
+ exts.set(name, ext);
+ } catch (IOException e) {
+ CMS.debug("EnrollDefault: " + e.toString());
+ }
+ }
+
+ protected void replaceExtension(String name, Extension ext, X509CertInfo info)
+ throws EProfileException {
+ deleteExtension(name, info);
+ addExtension(name, ext, info);
+ }
+
+ protected boolean isOptional(String value) {
+ return value.equals("");
+ }
+
+ protected boolean getBoolean(String value) {
+ return Boolean.valueOf(value).booleanValue();
+ }
+
+ protected int getInt(String value) {
+ return Integer.valueOf(value).intValue();
+ }
+
+ protected boolean getConfigBoolean(String value) {
+ return getBoolean(getConfig(value));
+ }
+
+ protected int getConfigInt(String value) {
+ return getInt(getConfig(value));
+ }
+
+ protected boolean isGeneralNameValid(String name)
+ {
+ if (name == null)
+ return false;
+ int pos = name.indexOf(':');
+ if (pos == -1)
+ return false;
+ String nameType = name.substring(0, pos).trim();
+ String nameValue = name.substring(pos + 1).trim();
+ if (nameValue.equals(""))
+ return false;
+ return true;
+ }
+
+ protected GeneralNameInterface parseGeneralName(String name)
+ throws IOException {
+ int pos = name.indexOf(':');
+ if (pos == -1)
+ return null;
+ String nameType = name.substring(0, pos).trim();
+ String nameValue = name.substring(pos + 1).trim();
+ return parseGeneralName(nameType, nameValue);
+ }
+
+ protected boolean isGeneralNameType(String nameType)
+ {
+ if (nameType.equalsIgnoreCase("RFC822Name")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("DNSName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("x400")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("DirectoryName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("EDIPartyName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("URIName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("IPAddress")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("OIDName")) {
+ return true;
+ }
+ if (nameType.equalsIgnoreCase("OtherName")) {
+ return true;
+ }
+ return false;
+ }
+
+ protected GeneralNameInterface parseGeneralName(String nameType, String nameValue)
+ throws IOException
+ {
+ if (nameType.equalsIgnoreCase("RFC822Name")) {
+ return new RFC822Name(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("DNSName")) {
+ return new DNSName(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("x400")) {
+ // XXX
+ }
+ if (nameType.equalsIgnoreCase("DirectoryName")) {
+ return new X500Name(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("EDIPartyName")) {
+ return new EDIPartyName(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("URIName")) {
+ return new URIName(nameValue);
+ }
+ if (nameType.equalsIgnoreCase("IPAddress")) {
+ CMS.debug("IP Value:" + nameValue);
+ if (nameValue.indexOf('/') != -1) {
+ // CIDR support for NameConstraintsExt
+ StringTokenizer st = new StringTokenizer(nameValue, "/");
+ String addr = st.nextToken();
+ String netmask = st.nextToken();
+ CMS.debug("addr:" + addr +" netmask: "+netmask);
+ return new IPAddressName(addr, netmask);
+ } else {
+ return new IPAddressName(nameValue);
+ }
+ }
+ if (nameType.equalsIgnoreCase("OIDName")) {
+ try {
+ // check if OID
+ ObjectIdentifier oid = new ObjectIdentifier(nameValue);
+ } catch (Exception e) {
+ return null;
+ }
+ return new OIDName(nameValue);
+ }
+ if (nameType.equals("OtherName")) {
+ if (nameValue == null || nameValue.length() == 0)
+ nameValue = " ";
+ if (nameValue.startsWith("(PrintableString)")) {
+ // format: OtherName: (PrintableString)oid,value
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_PrintableString, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(KerberosName)")) {
+ // Syntax: (KerberosName)Realm|NameType|NameString(s)
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf('|');
+ int pos2 = nameValue.lastIndexOf('|');
+ String realm = nameValue.substring(pos0 + 1, pos1).trim();
+ String name_type = nameValue.substring(pos1 + 1, pos2).trim();
+ String name_strings = nameValue.substring(pos2 + 1).trim();
+ Vector strings = new Vector();
+ StringTokenizer st = new StringTokenizer(name_strings, ",");
+ while (st.hasMoreTokens()) {
+ strings.addElement(st.nextToken());
+ }
+ KerberosName name = new KerberosName(realm,
+ Integer.parseInt(name_type), strings);
+ // krb5 OBJECT IDENTIFIER ::= { iso (1)
+ // org (3)
+ // dod (6)
+ // internet (1)
+ // security (5)
+ // kerberosv5 (2) }
+ // krb5PrincipalName OBJECT IDENTIFIER ::= { krb5 2 }
+ return new OtherName(KerberosName.KRB5_PRINCIPAL_NAME,
+ name.toByteArray());
+ } else if (nameValue.startsWith("(IA5String)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_IA5String, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(UTF8String)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_UTF8String, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(BMPString)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_BMPString, on_value);
+ } else {
+ return null;
+ }
+ } else if (nameValue.startsWith("(Any)")) {
+ int pos0 = nameValue.indexOf(')');
+ int pos1 = nameValue.indexOf(',');
+ if (pos1 == -1)
+ return null;
+ String on_oid = nameValue.substring(pos0 + 1, pos1).trim();
+ String on_value = nameValue.substring(pos1 + 1).trim();
+ if (isValidOID(on_oid)) {
+ CMS.debug("OID: " + on_oid + " Value:" + on_value);
+ return new OtherName(new ObjectIdentifier(on_oid), getBytes(on_value));
+ } else {
+ CMS.debug("Invalid OID " + on_oid);
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+
+/**
+ * Converts string containing pairs of characters in the range of '0'
+ * to '9', 'a' to 'f' to an array of bytes such that each pair of
+ * characters in the string represents an individual byte
+ */
+ public byte[] getBytes(String string) {
+ if (string == null)
+ return null;
+ int stringLength = string.length();
+ if ((stringLength == 0) || ((stringLength % 2) != 0))
+ return null;
+ byte[] bytes = new byte[ (stringLength / 2) ];
+ for (int i = 0, b = 0; i < stringLength; i += 2, ++b) {
+ String nextByte = string.substring(i, (i + 2));
+ bytes[b] = (byte)Integer.parseInt(nextByte, 0x10);
+ }
+ return bytes;
+ }
+
+ /**
+ * Check if a object identifier in string form is valid,
+ * that is a string in the form n.n.n.n and der encode and decode-able.
+ * @param oid object identifier string.
+ * @return true if the oid is valid
+ */
+ public boolean isValidOID(String oid)
+ {
+ ObjectIdentifier v = null;
+ try {
+ v = ObjectIdentifier.getObjectIdentifier(oid);
+ } catch (Exception e) {
+ return false;
+ }
+ if (v == null)
+ return false;
+
+ // if the OID isn't valid (ex. n.n) the error isn't caught til
+ // encoding time leaving a bad request in the request queue.
+ try {
+ DerOutputStream derOut = new DerOutputStream();
+
+ derOut.putOID(v);
+ new ObjectIdentifier(new DerInputStream(derOut.toByteArray()));
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ protected String buildRecords(Vector recs) throws EPropertyException {
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < recs.size(); i++) {
+ NameValuePairs pairs = (NameValuePairs) recs.elementAt(i);
+
+ sb.append("Record #");
+ sb.append(i);
+ sb.append("\r\n");
+ Enumeration e = pairs.getNames();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+ String val = pairs.getValue(key);
+
+ sb.append(key);
+ sb.append(":");
+ sb.append(val);
+ sb.append("\r\n");
+ }
+ sb.append("\r\n");
+
+ }
+ return sb.toString();
+ }
+
+ protected Vector parseRecords(String value) throws EPropertyException {
+ StringTokenizer st = new StringTokenizer(value, "\r\n");
+ int num = 0;
+ Vector v = new Vector();
+ NameValuePairs nvps = null;
+
+ while (st.hasMoreTokens()) {
+ String token = (String) st.nextToken();
+
+ if (token.equals("Record #" + num)) {
+ CMS.debug("parseRecords: Record" + num);
+ nvps = new NameValuePairs();
+ v.addElement(nvps);
+ try {
+ token = (String) st.nextToken();
+ } catch (NoSuchElementException e) {
+ v.removeElementAt(num);
+ CMS.debug(e.toString());
+ return v;
+ }
+ num++;
+ }
+
+ if (nvps == null)
+ throw new EPropertyException("Bad Input Format");
+
+ int pos = token.indexOf(":");
+
+ if (pos <= 0) {
+ CMS.debug("parseRecords: No colon found in the input line");
+ throw new EPropertyException("Bad Input Format");
+ } else {
+ if (pos == (token.length() - 1)) {
+ nvps.add(token.substring(0, pos), "");
+ } else {
+ nvps.add(token.substring(0, pos), token.substring(pos + 1));
+ }
+ }
+ }
+
+ return v;
+ }
+
+ protected String getGeneralNameType(GeneralName gn)
+ throws EPropertyException {
+ int type = gn.getType();
+
+ if (type == GeneralNameInterface.NAME_RFC822)
+ return "RFC822Name";
+ else if (type == GeneralNameInterface.NAME_DNS)
+ return "DNSName";
+ else if (type == GeneralNameInterface.NAME_URI)
+ return "URIName";
+ else if (type == GeneralNameInterface.NAME_IP)
+ return "IPAddress";
+ else if (type == GeneralNameInterface.NAME_DIRECTORY)
+ return "DirectoryName";
+ else if (type == GeneralNameInterface.NAME_EDI)
+ return "EDIPartyName";
+ else if (type == GeneralNameInterface.NAME_ANY)
+ return "OtherName";
+ else if (type == GeneralNameInterface.NAME_OID)
+ return "OIDName";
+
+ throw new EPropertyException("Unsupported type: " + type);
+ }
+
+ protected String getGeneralNameValue(GeneralName gn) throws EPropertyException {
+ String s = gn.toString();
+ int type = gn.getType();
+
+ if (type == GeneralNameInterface.NAME_DIRECTORY)
+ return s;
+ else {
+ int pos = s.indexOf(":");
+
+ if (pos <= 0)
+ throw new EPropertyException("Badly formatted general name: " + s);
+ else {
+ return s.substring(pos + 1).trim();
+ }
+ }
+ }
+
+ public Locale getLocale(IRequest request) {
+ Locale locale = null;
+
+ if (request == null)
+ return null;
+
+ String language = request.getExtDataInString(
+ EnrollProfile.REQUEST_LOCALE);
+ if (language != null) {
+ locale = new Locale(language);
+ }
+ return locale;
+ }
+
+ public String toGeneralNameString(GeneralName gn) {
+ int type = gn.getType();
+ // Sun's General Name is not consistent, so we need
+ // to do a special case for directory string
+ if (type == GeneralNameInterface.NAME_DIRECTORY) {
+ return "DirectoryName: " + gn.toString();
+ }
+ return gn.toString();
+ }
+
+ protected String mapPattern(IRequest request, String pattern)
+ throws IOException {
+ Pattern p = new Pattern(pattern);
+ IAttrSet attrSet = null;
+ if (request != null) {
+ attrSet = request.asIAttrSet();
+ }
+ return p.substitute2("request", attrSet);
+ }
+
+ protected StringBuffer escapeValueRfc1779(String v, boolean doubleEscape)
+ {
+ StringBuffer result = new StringBuffer();
+
+ // Do we need to escape any characters
+ for (int i = 0; i < v.length(); i++) {
+ int c = v.charAt(i);
+ if (c == ',' || c == '=' || c == '+' || c == '<' ||
+ c == '>' || c == '#' || c == ';' || c == '\r' ||
+ c == '\n' || c == '\\' || c == '"') {
+ result.append('\\');
+ if (doubleEscape) result.append('\\');
+ }
+ if (c == '\r') {
+ result.append("0D");
+ } else if (c == '\n') {
+ result.append("0A");
+ } else {
+ result.append((char)c);
+ }
+ }
+ return result;
+ }
+
+}